diff options
author | brian <brian@cvs.openbsd.org> | 1997-12-15 22:44:59 +0000 |
---|---|---|
committer | brian <brian@cvs.openbsd.org> | 1997-12-15 22:44:59 +0000 |
commit | e541f2807aed975b8fd01868cb0ca2954d485929 (patch) | |
tree | 8042bb48c2dcb99a152b1564f7aed2ea171b0248 /usr.sbin | |
parent | 663ebcdb374a129f4e61508b6a066b4b1c51fb8e (diff) |
Allow random IP number allocation to peer.
Validate the peers suggested IP by attempting to make a routing table
entry.
Give up IPCP negotiation if the peer NAKs us with an unusable IP.
Always SIOCDIFADDR then SIOCAIFADDR when configuring the tun device.
Using SIOCSIFDSTADDR allows duplicate dst addresses (which we don't
want)!!!
Allow up to 200 interface names (was 50) (now that ppp can play server
properly).
Cosmetic:
Log unexpected CCP packets in the CCP log rather than the ERROR log.
Log unexpected Config Reqs in the appropriate LCP/IPCP/CCP log rather
than the ERROR log.
Log failed route additions and deletions with WARN, not TCPIP.
Log the option id and length for unrecognised IPCP options.
Change some .Sq to .Ar in the man page.
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/ppp/ccp.c | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/command.c | 38 | ||||
-rw-r--r-- | usr.sbin/ppp/filter.c | 15 | ||||
-rw-r--r-- | usr.sbin/ppp/fsm.c | 5 | ||||
-rw-r--r-- | usr.sbin/ppp/ipcp.c | 39 | ||||
-rw-r--r-- | usr.sbin/ppp/ipcp.h | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/iplist.c | 200 | ||||
-rw-r--r-- | usr.sbin/ppp/iplist.h | 24 | ||||
-rw-r--r-- | usr.sbin/ppp/main.c | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/os.c | 79 | ||||
-rw-r--r-- | usr.sbin/ppp/os.h | 5 | ||||
-rw-r--r-- | usr.sbin/ppp/phase.c | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp.8 | 86 | ||||
-rw-r--r-- | usr.sbin/ppp/route.c | 42 | ||||
-rw-r--r-- | usr.sbin/ppp/route.h | 3 |
15 files changed, 437 insertions, 114 deletions
diff --git a/usr.sbin/ppp/ccp.c b/usr.sbin/ppp/ccp.c index 3382390346f..b60f072f32c 100644 --- a/usr.sbin/ppp/ccp.c +++ b/usr.sbin/ppp/ccp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ccp.c,v 1.3 1997/12/06 12:09:12 brian Exp $ + * $Id: ccp.c,v 1.4 1997/12/15 22:44:50 brian Exp $ * * TODO: * o Support other compression protocols @@ -372,7 +372,7 @@ CcpInput(struct mbuf *bp) FsmInput(&CcpFsm, bp); else { if (phase > PHASE_NETWORK) - LogPrintf(LogERROR, "Unexpected CCP in phase %d\n", phase); + LogPrintf(LogCCP, "Error: Unexpected CCP in phase %d\n", phase); pfree(bp); } } diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c index b3d9fa71ee1..32762743ddf 100644 --- a/usr.sbin/ppp/command.c +++ b/usr.sbin/ppp/command.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: command.c,v 1.3 1997/12/08 20:09:06 brian Exp $ + * $Id: command.c,v 1.4 1997/12/15 22:44:50 brian Exp $ * */ #include <sys/param.h> @@ -53,6 +53,7 @@ #include "fsm.h" #include "phase.h" #include "lcp.h" +#include "iplist.h" #include "ipcp.h" #include "modem.h" #include "filter.h" @@ -1187,18 +1188,17 @@ SetInterfaceAddr(struct cmdargs const *arg) HaveTriggerAddress = 0; ifnetmask.s_addr = 0; + iplist_reset(&DefHisChoice); if (arg->argc > 0) { - if (ParseAddr(arg->argc, arg->argv, - &DefMyAddress.ipaddr, - &DefMyAddress.mask, - &DefMyAddress.width) == 0) + if (!ParseAddr(arg->argc, arg->argv, &DefMyAddress.ipaddr, + &DefMyAddress.mask, &DefMyAddress.width)) return 1; if (arg->argc > 1) { - if (ParseAddr(arg->argc, arg->argv+1, - &DefHisAddress.ipaddr, - &DefHisAddress.mask, - &DefHisAddress.width) == 0) + if (strpbrk(arg->argv[1], ",-")) + iplist_setsrc(&DefHisChoice, arg->argv[1]); + else if (!ParseAddr(arg->argc, arg->argv+1, &DefHisAddress.ipaddr, + &DefHisAddress.mask, &DefHisAddress.width)) return 2; if (arg->argc > 2) { ifnetmask = GetIpAddr(arg->argv[2]); @@ -1222,11 +1222,23 @@ SetInterfaceAddr(struct cmdargs const *arg) DefHisAddress.width = 0; } IpcpInfo.want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr; - IpcpInfo.his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr; + if (iplist_isvalid(&DefHisChoice)) { + iplist_setrandpos(&DefHisChoice); + IpcpInfo.his_ipaddr = ChooseHisAddr(IpcpInfo.want_ipaddr); + if (IpcpInfo.his_ipaddr.s_addr == INADDR_ANY) { + LogPrintf(LogWARN, "%s: None available !\n", DefHisChoice.src); + return 3; + } + DefHisAddress.ipaddr.s_addr = IpcpInfo.his_ipaddr.s_addr; + DefHisAddress.mask.s_addr = 0xffffffff; + DefHisAddress.width = 32; + } else { + IpcpInfo.his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr; - if ((mode & MODE_AUTO) && - OsSetIpaddress(DefMyAddress.ipaddr, DefHisAddress.ipaddr, ifnetmask) < 0) - return 4; + if ((mode & MODE_AUTO) && + OsSetIpaddress(DefMyAddress.ipaddr, DefHisAddress.ipaddr) < 0) + return 4; + } return 0; } diff --git a/usr.sbin/ppp/filter.c b/usr.sbin/ppp/filter.c index 119ce0f3f09..755bdec856a 100644 --- a/usr.sbin/ppp/filter.c +++ b/usr.sbin/ppp/filter.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: filter.c,v 1.1 1997/11/23 20:27:33 brian Exp $ + * $Id: filter.c,v 1.2 1997/12/15 22:44:51 brian Exp $ * * TODO: Shoud send ICMP error message when we discard packets. */ @@ -75,9 +75,11 @@ ParseAddr(int argc, LogPrintf(LogWARN, "ParseAddr: address/mask is expected.\n"); return (0); } - pmask->s_addr = 0xffffffff; /* Assume 255.255.255.255 as default */ - cp = strchr(*argv, '/'); + if (pmask) + pmask->s_addr = 0xffffffff; /* Assume 255.255.255.255 as default */ + + cp = pmask || pwidth ? strchr(*argv, '/') : NULL; len = cp ? cp - *argv : strlen(*argv); if (strncasecmp(*argv, "HISADDR", len) == 0) @@ -106,8 +108,11 @@ ParseAddr(int argc, bits = 32; } - *pwidth = bits; - pmask->s_addr = htonl(netmasks[bits]); + if (pwidth) + *pwidth = bits; + + if (pmask) + pmask->s_addr = htonl(netmasks[bits]); return (1); } diff --git a/usr.sbin/ppp/fsm.c b/usr.sbin/ppp/fsm.c index 17bc691b012..6f6af4089c8 100644 --- a/usr.sbin/ppp/fsm.c +++ b/usr.sbin/ppp/fsm.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: fsm.c,v 1.2 1997/12/06 12:08:56 brian Exp $ + * $Id: fsm.c,v 1.3 1997/12/15 22:44:52 brian Exp $ * * TODO: * o Refer loglevel for log output @@ -367,7 +367,8 @@ FsmRecvConfigReq(struct fsm * fp, struct fsmheader * lhp, struct mbuf * bp) pfree(bp); return; case ST_CLOSING: - LogPrintf(LogERROR, "Got ConfigReq while state = %d\n", fp->state); + LogPrintf(fp->LogLevel, "Error: Got ConfigReq while state = %d\n", + fp->state); case ST_STOPPING: pfree(bp); return; diff --git a/usr.sbin/ppp/ipcp.c b/usr.sbin/ppp/ipcp.c index a8a967cfee0..60eeda60f82 100644 --- a/usr.sbin/ppp/ipcp.c +++ b/usr.sbin/ppp/ipcp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ipcp.c,v 1.4 1997/12/06 22:43:47 brian Exp $ + * $Id: ipcp.c,v 1.5 1997/12/15 22:44:52 brian Exp $ * * TODO: * o More RFC1772 backwoard compatibility @@ -44,6 +44,7 @@ #include "fsm.h" #include "lcpproto.h" #include "lcp.h" +#include "iplist.h" #include "ipcp.h" #include "slcompress.h" #include "os.h" @@ -53,6 +54,7 @@ #include "vjcomp.h" #include "ip.h" #include "throughput.h" +#include "route.h" #ifndef NOMSEXT struct in_addr ns_entries[2]; @@ -62,6 +64,7 @@ struct in_addr nbns_entries[2]; struct ipcpstate IpcpInfo; struct in_range DefMyAddress; struct in_range DefHisAddress; +struct iplist DefHisChoice; struct in_addr TriggerAddress; int HaveTriggerAddress; @@ -184,6 +187,8 @@ IpcpDefAddress() void IpcpInit() { + if (iplist_isvalid(&DefHisChoice)) + iplist_setrandpos(&DefHisChoice); FsmInit(&IpcpFsm); memset(&IpcpInfo, '\0', sizeof(struct ipcpstate)); if ((mode & MODE_DEDICATED) && !GetLabel()) { @@ -305,7 +310,7 @@ IpcpLayerUp(struct fsm * fp) LogPrintf(LogIsKept(LogIPCP) ? LogIPCP : LogLINK, " %s hisaddr = %s\n", tbuff, inet_ntoa(IpcpInfo.his_ipaddr)); - if (OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr, ifnetmask) < 0) { + if (OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr) < 0) { if (VarTerm) LogPrintf(LogERROR, "IpcpLayerUp: unable to set ip address\n"); return; @@ -366,7 +371,7 @@ IpcpDecodeConfig(u_char * cp, int plen, int mode_type) else if (type > 128 && type < 128 + NCFTYPES128) snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes128[type-128], length); else - snprintf(tbuff, sizeof(tbuff), " ??? "); + snprintf(tbuff, sizeof(tbuff), " <%d>[%d] ", type, length); switch (type) { case TY_IPADDR: /* RFC1332 */ @@ -376,13 +381,29 @@ IpcpDecodeConfig(u_char * cp, int plen, int mode_type) switch (mode_type) { case MODE_REQ: - if (!AcceptableAddr(&DefHisAddress, ipaddr)) { + if (iplist_isvalid(&DefHisChoice)) { + if (iplist_ip2pos(&DefHisChoice, ipaddr) < 0 || + OsTrySetIpaddress(DefMyAddress.ipaddr, ipaddr) != 0) { + LogPrintf(LogIPCP, "%s: Address invalid or already in use\n", + inet_ntoa(ipaddr)); + IpcpInfo.his_ipaddr = ChooseHisAddr(DefMyAddress.ipaddr); + if (IpcpInfo.his_ipaddr.s_addr == INADDR_ANY) { + memcpy(rejp, cp, length); + rejp += length; + } else { + memcpy(nakp, cp, 2); + memcpy(nakp+2, &IpcpInfo.his_ipaddr.s_addr, length - 2); + nakp += length; + } + break; + } + } else if (!AcceptableAddr(&DefHisAddress, ipaddr)) { /* * If destination address is not acceptable, insist to use what we * want to use. */ memcpy(nakp, cp, 2); - memcpy(nakp+2, &IpcpInfo.his_ipaddr.s_addr, length); + memcpy(nakp+2, &IpcpInfo.his_ipaddr.s_addr, length - 2); nakp += length; break; } @@ -392,14 +413,14 @@ IpcpDecodeConfig(u_char * cp, int plen, int mode_type) break; case MODE_NAK: if (AcceptableAddr(&DefMyAddress, ipaddr)) { - - /* - * Use address suggested by peer. - */ + /* Use address suggested by peer */ snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s ", tbuff, inet_ntoa(IpcpInfo.want_ipaddr)); LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); IpcpInfo.want_ipaddr = ipaddr; + } else { + LogPrintf(LogIPCP, "%s: Unacceptable address!\n", inet_ntoa(ipaddr)); + FsmClose(&IpcpFsm); } break; case MODE_REJ: diff --git a/usr.sbin/ppp/ipcp.h b/usr.sbin/ppp/ipcp.h index 50b0f8ba195..a8522ce7f5b 100644 --- a/usr.sbin/ppp/ipcp.h +++ b/usr.sbin/ppp/ipcp.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ipcp.h,v 1.1 1997/11/23 20:27:34 brian Exp $ + * $Id: ipcp.h,v 1.2 1997/12/15 22:44:53 brian Exp $ * * TODO: */ @@ -65,6 +65,7 @@ struct in_range { extern struct ipcpstate IpcpInfo; extern struct in_range DefMyAddress; extern struct in_range DefHisAddress; +extern struct iplist DefHisChoice; extern struct in_addr TriggerAddress; extern int HaveTriggerAddress; extern struct fsm IpcpFsm; diff --git a/usr.sbin/ppp/iplist.c b/usr.sbin/ppp/iplist.c new file mode 100644 index 00000000000..9fe3c59b375 --- /dev/null +++ b/usr.sbin/ppp/iplist.c @@ -0,0 +1,200 @@ +/* + * $Id: iplist.c,v 1.1 1997/12/15 22:44:53 brian Exp $ + */ + +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <stdlib.h> +#include <string.h> + +#include "command.h" +#include "mbuf.h" +#include "log.h" +#include "defs.h" +#include "iplist.h" + +static int +do_inet_aton(const char *start, const char *end, struct in_addr *ip) +{ + static char ipstr[16]; + + if (end - start > 15) { + LogPrintf(LogWARN, "%.*s: Invalid IP address\n", end-start, start); + return 0; + } + strncpy(ipstr, start, end-start); + ipstr[end-start] = '\0'; + return inet_aton(ipstr, ip); +} + +static void +iplist_first(struct iplist *list) +{ + list->cur.pos = -1; +} + +static int +iplist_setrange(struct iplist *list, char *range) +{ + char *ptr, *to; + + if ((ptr = strpbrk(range, ",-")) == NULL) { + if (!inet_aton(range, &list->cur.ip)) + return 0; + list->cur.lstart = ntohl(list->cur.ip.s_addr); + list->cur.nItems = 1; + } else { + if (!do_inet_aton(range, ptr, &list->cur.ip)) + return 0; + if (*ptr == ',') { + list->cur.lstart = ntohl(list->cur.ip.s_addr); + list->cur.nItems = 1; + } else { + struct in_addr endip; + + to = ptr+1; + if ((ptr = strpbrk(to, ",-")) == NULL) + ptr = to + strlen(to); + if (*to == '-') + return 0; + if (!do_inet_aton(to, ptr, &endip)) + return 0; + list->cur.lstart = ntohl(list->cur.ip.s_addr); + list->cur.nItems = ntohl(endip.s_addr) - list->cur.lstart + 1; + if (list->cur.nItems < 1) + return 0; + } + } + list->cur.srcitem = 0; + list->cur.srcptr = range; + return 1; +} + +static int +iplist_nextrange(struct iplist *list) +{ + char *ptr, *to, *end; + + ptr = list->cur.srcptr; + if (ptr != NULL && (ptr = strchr(ptr, ',')) != NULL) + ptr++; + else + ptr = list->src; + + while (*ptr != '\0' && !iplist_setrange(list, ptr)) { + if ((end = strchr(ptr, ',')) == NULL) + end = ptr + strlen(ptr); + if (end == ptr) + return 0; + LogPrintf(LogWARN, "%.*s: Invalid IP range (skipping)\n", end - ptr, ptr); + to = ptr; + do + *to = *end++; + while (*to++ != '\0'); + if (*ptr == '\0') + ptr = list->src; + } + + return 1; +} + +struct in_addr +iplist_next(struct iplist *list) +{ + if (list->cur.pos == -1) { + list->cur.srcptr = NULL; + if (!iplist_nextrange(list)) { + list->cur.ip.s_addr = INADDR_ANY; + return list->cur.ip; + } + } else if (++list->cur.srcitem == list->cur.nItems) { + if (!iplist_nextrange(list)) { + list->cur.ip.s_addr = INADDR_ANY; + list->cur.pos = -1; + return list->cur.ip; + } + } else + list->cur.ip.s_addr = htonl(list->cur.lstart + list->cur.srcitem); + list->cur.pos++; + + return list->cur.ip; +} + +int +iplist_setsrc(struct iplist *list, const char *src) +{ + strncpy(list->src, src, sizeof(list->src)); + list->src[sizeof(list->src)-1] = '\0'; + list->cur.srcptr = list->src; + do { + if (iplist_nextrange(list)) + list->nItems += list->cur.nItems; + else + return 0; + } while (list->cur.srcptr != list->src); + return 1; +} + +void +iplist_reset(struct iplist *list) +{ + list->src[0] = '\0'; + list->nItems = 0; + list->cur.pos = -1; +} + +struct in_addr +iplist_setcurpos(struct iplist *list, int pos) +{ + if (pos < 0 || pos >= list->nItems) { + list->cur.pos = -1; + list->cur.ip.s_addr = INADDR_ANY; + return list->cur.ip; + } + + list->cur.srcptr = NULL; + list->cur.pos = 0; + while (1) { + iplist_nextrange(list); + if (pos < list->cur.nItems) { + if (pos) { + list->cur.srcitem = pos; + list->cur.pos += pos; + list->cur.ip.s_addr = htonl(list->cur.lstart + list->cur.srcitem); + } + break; + } + pos -= list->cur.nItems; + list->cur.pos += list->cur.nItems; + } + + return list->cur.ip; +} + +struct in_addr +iplist_setrandpos(struct iplist *list) +{ + randinit(); + return iplist_setcurpos(list, random() % list->nItems); +} + +int +iplist_ip2pos(struct iplist *list, struct in_addr ip) +{ + struct iplist_cur cur; + int f, result; + + result = -1; + memcpy(&cur, &list->cur, sizeof(cur)); + + for (iplist_first(list), f = 0; f < list->nItems; f++) + if (iplist_next(list).s_addr == ip.s_addr) { + result = list->cur.pos; + break; + } + + memcpy(&list->cur, &cur, sizeof(list->cur)); + return result; +} diff --git a/usr.sbin/ppp/iplist.h b/usr.sbin/ppp/iplist.h new file mode 100644 index 00000000000..00923a03cb5 --- /dev/null +++ b/usr.sbin/ppp/iplist.h @@ -0,0 +1,24 @@ +/* + * $Id: iplist.h,v 1.1 1997/12/15 22:44:54 brian Exp $ + */ + +struct iplist { + struct iplist_cur { + struct in_addr ip; + int pos; + char *srcptr; + int srcitem; + u_long lstart, nItems; + } cur; + int nItems; + char src[LINE_LEN]; +}; + +extern int iplist_setsrc(struct iplist *, const char *); +extern void iplist_reset(struct iplist *); +extern struct in_addr iplist_setcurpos(struct iplist *, int); +extern struct in_addr iplist_setrandpos(struct iplist *); +extern int iplist_ip2pos(struct iplist *, struct in_addr); +extern struct in_addr iplist_next(struct iplist *); + +#define iplist_isvalid(x) ((x)->src[0] != '\0') diff --git a/usr.sbin/ppp/main.c b/usr.sbin/ppp/main.c index 4b8fee244a0..0c4c5b3ebc8 100644 --- a/usr.sbin/ppp/main.c +++ b/usr.sbin/ppp/main.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: main.c,v 1.2 1997/12/06 12:09:00 brian Exp $ + * $Id: main.c,v 1.3 1997/12/15 22:44:54 brian Exp $ * * TODO: * o Add commands for traffic summary, version display, etc. @@ -413,7 +413,7 @@ main(int argc, char **argv) fprintf(VarTerm, "Warning: No default entry is given in config file.\n"); if (OpenTunnel(&tunno) < 0) { - LogPrintf(LogWARN, "open_tun: %s\n", strerror(errno)); + LogPrintf(LogWARN, "OpenTunnel: %s\n", strerror(errno)); return EX_START; } if (mode & MODE_INTER) { diff --git a/usr.sbin/ppp/os.c b/usr.sbin/ppp/os.c index 20ca02e261f..298ec0ab353 100644 --- a/usr.sbin/ppp/os.c +++ b/usr.sbin/ppp/os.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: os.c,v 1.2 1997/12/06 12:09:01 brian Exp $ + * $Id: os.c,v 1.3 1997/12/15 22:44:55 brian Exp $ * */ #include <sys/param.h> @@ -66,15 +66,16 @@ static struct ifreq ifrq; static struct in_addr oldmine, oldhis; static int linkup; +enum set_method { SET_UP, SET_DOWN, SET_TRY }; + static int SetIpDevice(struct in_addr myaddr, struct in_addr hisaddr, struct in_addr netmask, - int updown) + enum set_method how) { struct sockaddr_in *sock_in; int s; - int changeaddr = 0; u_long mask, addr; s = ID0socket(AF_INET, SOCK_DGRAM, 0); @@ -82,7 +83,7 @@ SetIpDevice(struct in_addr myaddr, LogPrintf(LogERROR, "SetIpDevice: socket(): %s\n", strerror(errno)); return (-1); } - if (updown == 0) { + if (how == SET_DOWN) { if (Enabled(ConfProxy)) cifproxyarp(s, oldhis.s_addr); if (oldmine.s_addr == 0 && oldhis.s_addr == 0) { @@ -100,10 +101,7 @@ SetIpDevice(struct in_addr myaddr, } oldmine.s_addr = oldhis.s_addr = 0; } else { - - /* - * If given addresses are alreay set, then ignore this request. - */ + /* If given addresses are alreay set, then ignore this request */ if (oldmine.s_addr == myaddr.s_addr && oldhis.s_addr == hisaddr.s_addr) { close(s); return (0); @@ -113,27 +111,29 @@ SetIpDevice(struct in_addr myaddr, * If different address has been set, then delete it first. */ if (oldmine.s_addr || oldhis.s_addr) { - changeaddr = 1; + memset(&ifra.ifra_addr, '\0', sizeof(ifra.ifra_addr)); + memset(&ifra.ifra_broadaddr, '\0', sizeof(ifra.ifra_addr)); + memset(&ifra.ifra_mask, '\0', sizeof(ifra.ifra_addr)); + if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0) { + LogPrintf(LogERROR, "SetIpDevice: ioctl(SIOCDIFADDR): %s\n", + strerror(errno)); + close(s); + return (-1); + } } - /* - * Set interface address - */ + /* Set interface address */ sock_in = (struct sockaddr_in *) & (ifra.ifra_addr); sock_in->sin_family = AF_INET; - sock_in->sin_addr = oldmine = myaddr; + sock_in->sin_addr = myaddr; sock_in->sin_len = sizeof(*sock_in); - /* - * Set destination address - */ + /* Set destination address */ sock_in = (struct sockaddr_in *) & (ifra.ifra_broadaddr); sock_in->sin_family = AF_INET; - sock_in->sin_addr = oldhis = hisaddr; + sock_in->sin_addr = hisaddr; sock_in->sin_len = sizeof(*sock_in); - /* - * */ addr = ntohl(myaddr.s_addr); if (IN_CLASSA(addr)) mask = IN_CLASSA_NET; @@ -153,31 +153,16 @@ SetIpDevice(struct in_addr myaddr, sock_in->sin_addr.s_addr = htonl(mask); sock_in->sin_len = sizeof(*sock_in); - if (changeaddr) { - - /* - * Interface already exists. Just change the address. - */ - memcpy(&ifrq.ifr_addr, &ifra.ifra_addr, sizeof(struct sockaddr)); - if (ID0ioctl(s, SIOCSIFADDR, &ifra) < 0) - LogPrintf(LogERROR, "SetIpDevice: ioctl(SIFADDR): %s\n", - strerror(errno)); - memcpy(&ifrq.ifr_dstaddr, &ifra.ifra_broadaddr, sizeof(struct sockaddr)); - if (ID0ioctl(s, SIOCSIFDSTADDR, &ifrq) < 0) - LogPrintf(LogERROR, "SetIpDevice: ioctl(SIFDSTADDR): %s\n", - strerror(errno)); -#ifdef notdef - memcpy(&ifrq.ifr_broadaddr, &ifra.ifra_mask, sizeof(struct sockaddr)); - if (ID0ioctl(s, SIOCSIFBRDADDR, &ifrq) < 0) - LogPrintf(LogERROR, "SetIpDevice: ioctl(SIFBRDADDR): %s\n", + if (ID0ioctl(s, SIOCAIFADDR, &ifra) < 0) { + if (how != SET_TRY) + LogPrintf(LogERROR, "SetIpDevice: ioctl(SIOCAIFADDR): %s\n", strerror(errno)); -#endif - } else if (ID0ioctl(s, SIOCAIFADDR, &ifra) < 0) { - LogPrintf(LogERROR, "SetIpDevice: ioctl(SIOCAIFADDR): %s\n", - strerror(errno)); close(s); return (-1); } + + oldhis.s_addr = hisaddr.s_addr; + oldmine.s_addr = myaddr.s_addr; if (Enabled(ConfProxy)) sifproxyarp(s, hisaddr.s_addr); } @@ -186,11 +171,15 @@ SetIpDevice(struct in_addr myaddr, } int -OsSetIpaddress(struct in_addr myaddr, - struct in_addr hisaddr, - struct in_addr netmask) +OsTrySetIpaddress(struct in_addr myaddr, struct in_addr hisaddr) +{ + return (SetIpDevice(myaddr, hisaddr, ifnetmask, SET_TRY)); +} + +int +OsSetIpaddress(struct in_addr myaddr, struct in_addr hisaddr) { - return (SetIpDevice(myaddr, hisaddr, netmask, 1)); + return (SetIpDevice(myaddr, hisaddr, ifnetmask, SET_UP)); } static struct in_addr peer_addr; @@ -284,7 +273,7 @@ OsInterfaceDown(int final) return (-1); } zeroaddr.s_addr = 0; - SetIpDevice(zeroaddr, zeroaddr, zeroaddr, 0); + SetIpDevice(zeroaddr, zeroaddr, zeroaddr, SET_DOWN); close(s); return (0); diff --git a/usr.sbin/ppp/os.h b/usr.sbin/ppp/os.h index 42a3f685ff7..65d3cb83c99 100644 --- a/usr.sbin/ppp/os.h +++ b/usr.sbin/ppp/os.h @@ -15,14 +15,15 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: os.h,v 1.1 1997/11/23 20:27:35 brian Exp $ + * $Id: os.h,v 1.2 1997/12/15 22:44:55 brian Exp $ * * TODO: */ extern char *IfDevName; -extern int OsSetIpaddress(struct in_addr, struct in_addr, struct in_addr); +extern int OsSetIpaddress(struct in_addr, struct in_addr); +extern int OsTrySetIpaddress(struct in_addr, struct in_addr); extern int OsInterfaceDown(int); extern int OpenTunnel(int *); extern void OsLinkup(void); diff --git a/usr.sbin/ppp/phase.c b/usr.sbin/ppp/phase.c index 126bc62b84b..7d1d1eed619 100644 --- a/usr.sbin/ppp/phase.c +++ b/usr.sbin/ppp/phase.c @@ -1,5 +1,5 @@ /* - * $Id: phase.c,v 1.2 1997/12/07 23:55:08 brian Exp $ + * $Id: phase.c,v 1.3 1997/12/15 22:44:56 brian Exp $ */ #include <sys/param.h> @@ -16,9 +16,9 @@ #include "auth.h" #include "pap.h" #include "chap.h" +#include "defs.h" #include "ipcp.h" #include "ccp.h" -#include "defs.h" #include "main.h" #include "loadalias.h" #include "vars.h" diff --git a/usr.sbin/ppp/ppp.8 b/usr.sbin/ppp/ppp.8 index a2e072bfb20..3ad5b14f497 100644 --- a/usr.sbin/ppp/ppp.8 +++ b/usr.sbin/ppp/ppp.8 @@ -1,4 +1,4 @@ -.\" $Id: ppp.8,v 1.3 1997/12/07 04:09:08 brian Exp $ +.\" $Id: ppp.8,v 1.4 1997/12/15 22:44:57 brian Exp $ .Dd 20 September 1995 .Os OpenBSD .Dt PPP 8 @@ -2117,24 +2117,52 @@ of the address we will insist on. If the /n bit is omitted, it defaults to /32 unless the IP address is 0.0.0.0 in which case the mask defaults to /0. +.Pp +.Ar Hisaddr +may also be specified as a range of IP numbers in the format + +.Dl a.b.c.d[-d.e.f.g][,h.i.j.k[-l,m,n,o]]... + +for example: + +.Dl set ifaddr 10.0.0.1 10.0.1.2-10.0.1.10,10.0.1.20 + +will only negotiate +.Ar 10.0.0.1 +as the local IP number, but will assign any of the given 10 IP +numbers to the peer. If the peer requests one of these numbers, +and that number is not already in use, +.Nm +will grant the peers request. This is useful if the peer wants +to re-establish a link using the same IP number as was previously +allocated. If the peer requests an IP number that's either outside +of this range or is already in use, +.Nm +will start by suggesting a random unused IP number from the range. +If the peer doesn't subsequently agree, +.Nm +will suggest each of the other numbers in succession until a number +is chosen or until too many IPCP Configure Requests have been sent. + +.Pp If -.Dq triggeraddr +.Ar triggeraddr is specified, it is used in place of -.Dq myaddr +.Ar myaddr in the initial IPCP negotiation. However, only an address in the -.Dq myaddr +.Ar myaddr range will be accepted. .It set loopback on|off When set to -.Dq on +.Ar on (the default), .Nm will automatically loop back packets being sent out with a destination address equal to that of the .Em PPP interface. If set to -.Dq off , +.Ar off , .Nm will send the packet, probably resulting in an ICMP redirect from the other end. @@ -2144,9 +2172,11 @@ This command allows the adjustment of the current log level. Refer to the Logging Facility section for further details. .It set login chat-script -This chat-script compliments the dial-script. If both are specified, -the login script will be executed after the dial script. Escape -sequences available in the dial script are also available here. +This +.Ar chat-script +compliments the dial-script. If both are specified, the login +script will be executed after the dial script. Escape sequences +available in the dial script are also available here. .It set mru value The default MRU is 1500. If it is increased, the other side *may* @@ -2163,14 +2193,19 @@ Increasing it is not valid as the peer is not necessarily able to receive the increased packet size. .It set openmode active|passive -By default, openmode is always active. That is, +By default, +.Ar openmode +is always +.Ar active . +That is, .Nm -will always initiate LCP/IPCP/CCP negotiation. If you want to wait for the -peer to initiate negotiations, you may use the value -.Dq passive . +will always initiate LCP/IPCP/CCP negotiation. If you want to wait +for the peer to initiate negotiations, you may use the value +.Ar passive . .It set parity odd|even|none|mark -This allows the line parity to be set. The default value is none. +This allows the line parity to be set. The default value is +.Ar none . .It set phone telno[|telno]...[:telno[|telno]...]... This allows the specification of the phone number to be used in @@ -2191,29 +2226,29 @@ mode, each number is attempted at most once. .It set reconnect timeout ntries Should the line drop unexpectedly (due to loss of CD or LQR failure), a connection will be re-established after the given -.Dq timeout . +.Ar timeout . The line will be re-connected at most -.Dq ntries +.Ar ntries times. -.Dq Ntries +.Ar Ntries defaults to zero. A value of -.Dq random +.Ar random for -.Dq timeout +.Ar timeout will result in a variable pause, somewhere between 0 and 30 seconds. .It set redial seconds[.nseconds] [attempts] .Nm Ppp can be instructed to attempt to redial -.Dq attempts +.Ar attempts times. If more than one number is specified (see .Dq set phone above), a pause of -.Dq nseconds +.Ar nseconds is taken before dialing each number. A pause of -.Dq seconds +.Ar seconds is taken before starting at the first number again. A value of -.Dq random +.Ar random may be used here too. .It set stopped [LCPseconds [IPCPseconds [CCPseconds]]] @@ -2224,7 +2259,10 @@ the stopped state for the given number of .Dq seconds . This option may be useful if you see .Nm -failing to respond in the stopped state. Use +failing to respond in the stopped state, or if you wish to +.Dq set openmode passive +and time out if the peer doesn't send a Configure Request within the +given time. Use .Dq set log +lcp +ipcp +ccp to make .Nm diff --git a/usr.sbin/ppp/route.c b/usr.sbin/ppp/route.c index f3b761c08ba..1c3281ab3f1 100644 --- a/usr.sbin/ppp/route.c +++ b/usr.sbin/ppp/route.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: route.c,v 1.3 1997/12/07 04:09:09 brian Exp $ + * $Id: route.c,v 1.4 1997/12/15 22:44:58 brian Exp $ * */ @@ -48,6 +48,9 @@ #include "defs.h" #include "vars.h" #include "id.h" +#include "os.h" +#include "ipcp.h" +#include "iplist.h" #include "route.h" static int IfIndex; @@ -142,17 +145,19 @@ OsSetRoute(int cmd, LogPrintf(LogTCPIP, "OsSetRoute: Mask = %s\n", inet_ntoa(mask)); switch (rtmes.m_rtm.rtm_errno) { case EEXIST: - LogPrintf(LogTCPIP, "Add route failed: Already exists\n"); + LogPrintf(LogWARN, "Add route failed: %s already exists\n", + inet_ntoa(dst)); break; case ESRCH: - LogPrintf(LogTCPIP, "Del route failed: Non-existent\n"); + LogPrintf(LogWARN, "Del route failed: %s: Non-existent\n", + inet_ntoa(dst)); break; case 0: - LogPrintf(LogTCPIP, "%s route failed: %s\n", cmdstr, strerror(errno)); + LogPrintf(LogWARN, "%s route failed: %s\n", cmdstr, strerror(errno)); break; case ENOBUFS: default: - LogPrintf(LogTCPIP, "%s route failed: %s\n", + LogPrintf(LogWARN, "%s route failed: %s\n", cmdstr, strerror(rtmes.m_rtm.rtm_errno)); break; } @@ -283,7 +288,7 @@ p_flags(u_long f, const char *format) static const char * Index2Nam(int idx) { - static char ifs[50][6]; + static char ifs[200][6]; /* We could have 256 tun devices ! */ static int nifs, debug_done; if (!nifs) { @@ -493,3 +498,28 @@ GetIfIndex(char *name) idx++; return -1; } + +struct in_addr +ChooseHisAddr(const struct in_addr gw) +{ + struct in_addr try; + int f; + + for (f = 0; f < DefHisChoice.nItems; f++) { + try = iplist_next(&DefHisChoice); + LogPrintf(LogDEBUG, "ChooseHisAddr: Check item %d (%s)\n", + f, inet_ntoa(try)); + if (OsTrySetIpaddress(gw, try) == 0) { + LogPrintf(LogIPCP, "ChooseHisAddr: Selected IP address %s\n", + inet_ntoa(try)); + break; + } + } + + if (f == DefHisChoice.nItems) { + LogPrintf(LogDEBUG, "ChooseHisAddr: All addresses in use !\n"); + try.s_addr = INADDR_ANY; + } + + return try; +} diff --git a/usr.sbin/ppp/route.h b/usr.sbin/ppp/route.h index 8a2629042be..407ec1307ee 100644 --- a/usr.sbin/ppp/route.h +++ b/usr.sbin/ppp/route.h @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: route.h,v 1.1 1997/11/23 20:27:35 brian Exp $ + * $Id: route.h,v 1.2 1997/12/15 22:44:58 brian Exp $ * */ @@ -25,3 +25,4 @@ extern int GetIfIndex(char *); extern int ShowRoute(struct cmdargs const *); extern void OsSetRoute(int, struct in_addr, struct in_addr, struct in_addr); extern void DeleteIfRoutes(int); +extern struct in_addr ChooseHisAddr(const struct in_addr); |