diff options
Diffstat (limited to 'usr.sbin/ppp/bundle.c')
| -rw-r--r-- | usr.sbin/ppp/bundle.c | 200 |
1 files changed, 102 insertions, 98 deletions
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c index 89388b951b6b0..569d893f72dd7 100644 --- a/usr.sbin/ppp/bundle.c +++ b/usr.sbin/ppp/bundle.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bundle.c,v 1.42 1998/12/14 19:24:28 brian Exp $ + * $Id: bundle.c,v 1.34 1998/08/26 17:39:36 brian Exp $ */ #include <sys/param.h> @@ -89,7 +89,6 @@ #include "cbcp.h" #include "datalink.h" #include "ip.h" -#include "iface.h" #define SCATTER_SEGMENTS 4 /* version, datalink, name, physical */ #define SOCKET_OVERHEAD 100 /* additional buffer space for large */ @@ -149,6 +148,49 @@ bundle_NewPhase(struct bundle *bundle, u_int new) } } +static int +bundle_CleanInterface(const struct bundle *bundle) +{ + int s; + struct ifreq ifrq; + struct ifaliasreq ifra; + + s = ID0socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) { + log_Printf(LogERROR, "bundle_CleanInterface: socket(): %s\n", + strerror(errno)); + return (-1); + } + strncpy(ifrq.ifr_name, bundle->ifp.Name, sizeof ifrq.ifr_name - 1); + ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0'; + while (ID0ioctl(s, SIOCGIFADDR, &ifrq) == 0) { + memset(&ifra.ifra_mask, '\0', sizeof ifra.ifra_mask); + strncpy(ifra.ifra_name, bundle->ifp.Name, sizeof ifra.ifra_name - 1); + ifra.ifra_name[sizeof ifra.ifra_name - 1] = '\0'; + ifra.ifra_addr = ifrq.ifr_addr; + if (ID0ioctl(s, SIOCGIFDSTADDR, &ifrq) < 0) { + if (ifra.ifra_addr.sa_family == AF_INET) + log_Printf(LogERROR, "Can't get dst for %s on %s !\n", + inet_ntoa(((struct sockaddr_in *)&ifra.ifra_addr)->sin_addr), + bundle->ifp.Name); + close(s); + return 0; + } + ifra.ifra_broadaddr = ifrq.ifr_dstaddr; + if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0) { + if (ifra.ifra_addr.sa_family == AF_INET) + log_Printf(LogERROR, "Can't delete %s address on %s !\n", + inet_ntoa(((struct sockaddr_in *)&ifra.ifra_addr)->sin_addr), + bundle->ifp.Name); + close(s); + return 0; + } + } + close(s); + + return 1; +} + static void bundle_LayerStart(void *v, struct fsm *fp) { @@ -345,14 +387,14 @@ bundle_LayerUp(void *v, struct fsm *fp) if (bundle->ncp.mp.active) { struct datalink *dl; - bundle->ifSpeed = 0; + bundle->ifp.Speed = 0; for (dl = bundle->links; dl; dl = dl->next) if (dl->state == DATALINK_OPEN) - bundle->ifSpeed += modem_Speed(dl->physical); + bundle->ifp.Speed += modem_Speed(dl->physical); tun_configure(bundle, bundle->ncp.mp.peer_mrru); bundle->autoload.running = 1; } else { - bundle->ifSpeed = modem_Speed(p); + bundle->ifp.Speed = modem_Speed(p); tun_configure(bundle, fsm2lcp(fp)->his_mru); } } else if (fp->proto == PROTO_IPCP) { @@ -382,15 +424,15 @@ bundle_LayerDown(void *v, struct fsm *fp) struct datalink *dl; struct datalink *lost; - bundle->ifSpeed = 0; + bundle->ifp.Speed = 0; lost = NULL; for (dl = bundle->links; dl; dl = dl->next) if (fp == &dl->physical->link.lcp.fsm) lost = dl; else if (dl->state == DATALINK_OPEN) - bundle->ifSpeed += modem_Speed(dl->physical); + bundle->ifp.Speed += modem_Speed(dl->physical); - if (bundle->ifSpeed) + if (bundle->ifp.Speed) /* Don't configure down to a speed of 0 */ tun_configure(bundle, bundle->ncp.mp.link.lcp.his_mru); @@ -625,6 +667,12 @@ bundle_DescriptorRead(struct descriptor *d, struct bundle *bundle, if (pri >= 0) { struct mbuf *bp; +#ifndef NOALIAS + if (bundle->AliasEnabled) { + PacketAliasIn(tun.data, sizeof tun.data); + n = ntohs(((struct ip *)tun.data)->ip_len); + } +#endif bp = mbuf_Alloc(n, MB_IPIN); memcpy(MBUF_CTOP(bp), tun.data, n); ip_Input(bundle, bp); @@ -721,11 +769,10 @@ struct bundle * bundle_Create(const char *prefix, int type, const char **argv) { int s, enoentcount, err; - const char *ifname; struct ifreq ifrq; static struct bundle bundle; /* there can be only one */ - if (bundle.iface != NULL) { /* Already allocated ! */ + if (bundle.ifp.Name != NULL) { /* Already allocated ! */ log_Printf(LogALERT, "bundle_Create: There's only one BUNDLE !\n"); return NULL; } @@ -756,8 +803,6 @@ bundle_Create(const char *prefix, int type, const char **argv) log_SetTun(bundle.unit); bundle.argv = argv; - bundle.argv0 = argv[0]; - bundle.argv1 = argv[1]; s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { @@ -766,32 +811,24 @@ bundle_Create(const char *prefix, int type, const char **argv) return NULL; } - ifname = strrchr(bundle.dev.Name, '/'); - if (ifname == NULL) - ifname = bundle.dev.Name; + bundle.ifp.Name = strrchr(bundle.dev.Name, '/'); + if (bundle.ifp.Name == NULL) + bundle.ifp.Name = bundle.dev.Name; else - ifname++; - - bundle.iface = iface_Create(ifname); - if (bundle.iface == NULL) { - close(s); - close(bundle.dev.fd); - return NULL; - } + bundle.ifp.Name++; /* * Now, bring up the interface. */ memset(&ifrq, '\0', sizeof ifrq); - strncpy(ifrq.ifr_name, ifname, sizeof ifrq.ifr_name - 1); + strncpy(ifrq.ifr_name, bundle.ifp.Name, sizeof ifrq.ifr_name - 1); ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0'; if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) { log_Printf(LogERROR, "bundle_Create: ioctl(SIOCGIFFLAGS): %s\n", strerror(errno)); close(s); - iface_Destroy(bundle.iface); - bundle.iface = NULL; close(bundle.dev.fd); + bundle.ifp.Name = NULL; return NULL; } ifrq.ifr_flags |= IFF_UP; @@ -799,17 +836,22 @@ bundle_Create(const char *prefix, int type, const char **argv) log_Printf(LogERROR, "bundle_Create: ioctl(SIOCSIFFLAGS): %s\n", strerror(errno)); close(s); - iface_Destroy(bundle.iface); - bundle.iface = NULL; close(bundle.dev.fd); + bundle.ifp.Name = NULL; return NULL; } close(s); - log_Printf(LogPHASE, "Using interface: %s\n", ifname); + if ((bundle.ifp.Index = GetIfIndex(bundle.ifp.Name)) < 0) { + log_Printf(LogERROR, "Can't find interface index.\n"); + close(bundle.dev.fd); + bundle.ifp.Name = NULL; + return NULL; + } + log_Printf(LogPHASE, "Using interface: %s\n", bundle.ifp.Name); - bundle.ifSpeed = 0; + bundle.ifp.Speed = 0; bundle.routing_seq = 0; bundle.phase = PHASE_DEAD; @@ -840,9 +882,8 @@ bundle_Create(const char *prefix, int type, const char **argv) bundle.links = datalink_Create("deflink", &bundle, type); if (bundle.links == NULL) { log_Printf(LogALERT, "Cannot create data link: %s\n", strerror(errno)); - iface_Destroy(bundle.iface); - bundle.iface = NULL; close(bundle.dev.fd); + bundle.ifp.Name = NULL; return NULL; } @@ -876,7 +917,7 @@ bundle_Create(const char *prefix, int type, const char **argv) memset(&bundle.choked.timer, '\0', sizeof bundle.choked.timer); /* Clean out any leftover crud */ - iface_Clear(bundle.iface, IFACE_CLEAR_ALL); + bundle_CleanInterface(&bundle); bundle_LockTun(&bundle); @@ -898,7 +939,7 @@ bundle_DownInterface(struct bundle *bundle) } memset(&ifrq, '\0', sizeof ifrq); - strncpy(ifrq.ifr_name, bundle->iface->name, sizeof ifrq.ifr_name - 1); + strncpy(ifrq.ifr_name, bundle->ifp.Name, sizeof ifrq.ifr_name - 1); ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0'; if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) { log_Printf(LogERROR, "bundle_DownInterface: ioctl(SIOCGIFFLAGS): %s\n", @@ -944,8 +985,7 @@ bundle_Destroy(struct bundle *bundle) /* In case we never made PHASE_NETWORK */ bundle_Notify(bundle, EX_ERRDEAD); - iface_Destroy(bundle->iface); - bundle->iface = NULL; + bundle->ifp.Name = NULL; } struct rtmsg { @@ -981,17 +1021,6 @@ bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst, rtmes.m_rtm.rtm_pid = getpid(); rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; - if (cmd == RTM_ADD || cmd == RTM_CHANGE) { - if (bundle->ncp.ipcp.cfg.sendpipe > 0) { - rtmes.m_rtm.rtm_rmx.rmx_sendpipe = bundle->ncp.ipcp.cfg.sendpipe; - rtmes.m_rtm.rtm_inits |= RTV_SPIPE; - } - if (bundle->ncp.ipcp.cfg.recvpipe > 0) { - rtmes.m_rtm.rtm_rmx.rmx_recvpipe = bundle->ncp.ipcp.cfg.recvpipe; - rtmes.m_rtm.rtm_inits |= RTV_RPIPE; - } - } - memset(&rtdata, '\0', sizeof rtdata); rtdata.sin_len = sizeof rtdata; rtdata.sin_family = AF_INET; @@ -1003,11 +1032,24 @@ bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst, cp += rtdata.sin_len; if (cmd == RTM_ADD) { if (gateway.s_addr == INADDR_ANY) { - if (!ssh) - log_Printf(LogERROR, "bundle_SetRoute: Cannot add a route with" - " destination 0.0.0.0\n"); - close(s); - return result; + /* Add a route through the interface */ + struct sockaddr_dl dl; + const char *iname; + int ilen; + + iname = Index2Nam(bundle->ifp.Index); + ilen = strlen(iname); + dl.sdl_len = sizeof dl - sizeof dl.sdl_data + ilen; + dl.sdl_family = AF_LINK; + dl.sdl_index = bundle->ifp.Index; + dl.sdl_type = 0; + dl.sdl_nlen = ilen; + dl.sdl_alen = 0; + dl.sdl_slen = 0; + strncpy(dl.sdl_data, iname, sizeof dl.sdl_data); + memcpy(cp, &dl, dl.sdl_len); + cp += dl.sdl_len; + rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY; } else { rtdata.sin_addr = gateway; memcpy(cp, &rtdata, rtdata.sin_len); @@ -1040,7 +1082,7 @@ failed: (rtmes.m_rtm.rtm_errno == 0 && errno == EEXIST))) { if (!bang) { log_Printf(LogWARN, "Add route failed: %s already exists\n", - dst.s_addr == 0 ? "default" : inet_ntoa(dst)); + inet_ntoa(dst)); result = 0; /* Don't add to our dynamic list */ } else { rtmes.m_rtm.rtm_type = cmd = RTM_CHANGE; @@ -1197,10 +1239,9 @@ bundle_ShowStatus(struct cmdargs const *arg) int remaining; prompt_Printf(arg->prompt, "Phase %s\n", bundle_PhaseName(arg->bundle)); - prompt_Printf(arg->prompt, " Title: %s\n", arg->bundle->argv[0]); prompt_Printf(arg->prompt, " Device: %s\n", arg->bundle->dev.Name); prompt_Printf(arg->prompt, " Interface: %s @ %lubps\n", - arg->bundle->iface->name, arg->bundle->ifSpeed); + arg->bundle->ifp.Name, arg->bundle->ifp.Speed); prompt_Printf(arg->prompt, "\nDefaults:\n"); prompt_Printf(arg->prompt, " Label: %s\n", arg->bundle->cfg.label); @@ -1239,17 +1280,6 @@ bundle_ShowStatus(struct cmdargs const *arg) else prompt_Printf(arg->prompt, "unspecified\n"); - prompt_Printf(arg->prompt, " sendpipe: "); - if (arg->bundle->ncp.ipcp.cfg.sendpipe > 0) - prompt_Printf(arg->prompt, "%ld\n", arg->bundle->ncp.ipcp.cfg.sendpipe); - else - prompt_Printf(arg->prompt, "unspecified\n"); - prompt_Printf(arg->prompt, " recvpipe: "); - if (arg->bundle->ncp.ipcp.cfg.recvpipe > 0) - prompt_Printf(arg->prompt, "%ld\n", arg->bundle->ncp.ipcp.cfg.recvpipe); - else - prompt_Printf(arg->prompt, "unspecified\n"); - prompt_Printf(arg->prompt, " Sticky Routes: %s\n", optval(arg->bundle, OPT_SROUTES)); prompt_Printf(arg->prompt, " ID check: %s\n", @@ -1260,14 +1290,10 @@ bundle_ShowStatus(struct cmdargs const *arg) optval(arg->bundle, OPT_PASSWDAUTH)); prompt_Printf(arg->prompt, " Proxy: %s\n", optval(arg->bundle, OPT_PROXY)); - prompt_Printf(arg->prompt, " Proxyall: %s\n", - optval(arg->bundle, OPT_PROXYALL)); prompt_Printf(arg->prompt, " Throughput: %s\n", optval(arg->bundle, OPT_THROUGHPUT)); prompt_Printf(arg->prompt, " Utmp Logging: %s\n", optval(arg->bundle, OPT_UTMP)); - prompt_Printf(arg->prompt, " Iface-Alias: %s\n", - optval(arg->bundle, OPT_IFACEALIAS)); return 0; } @@ -1610,6 +1636,11 @@ bundle_SetMode(struct bundle *bundle, struct datalink *dl, int mode) /* Regenerate phys_type and adjust autoload & idle timers */ bundle_LinksRemoved(bundle); + if (omode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO) && + bundle->phase != PHASE_NETWORK) + /* No auto links left */ + ipcp_CleanInterface(&bundle->ncp.ipcp); + return 1; } @@ -1660,7 +1691,7 @@ bundle_setsid(struct bundle *bundle, int holdsession) log_Printf(LogPHASE, "%d -> %d: %s session control\n", (int)orig, (int)getpid(), holdsession ? "Passed" : "Dropped"); - timer_InitService(0); /* Start the Timer Service */ + timer_InitService(); break; default: close(fds[1]); @@ -1717,30 +1748,3 @@ bundle_setsid(struct bundle *bundle, int holdsession) break; } } - -int -bundle_HighestState(struct bundle *bundle) -{ - struct datalink *dl; - int result = DATALINK_CLOSED; - - for (dl = bundle->links; dl; dl = dl->next) - if (result < dl->state) - result = dl->state; - - return result; -} - -int -bundle_Exception(struct bundle *bundle, int fd) -{ - struct datalink *dl; - - for (dl = bundle->links; dl; dl = dl->next) - if (dl->physical->fd == fd) { - datalink_Down(dl, CLOSE_NORMAL); - return 1; - } - - return 0; -} |
