diff options
-rw-r--r-- | usr.sbin/ppp/Makefile | 4 | ||||
-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/ppp.8.m4 | 86 | ||||
-rw-r--r-- | usr.sbin/ppp/route.c | 42 | ||||
-rw-r--r-- | usr.sbin/ppp/route.h | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/vars.c | 6 |
18 files changed, 504 insertions, 143 deletions
diff --git a/usr.sbin/ppp/Makefile b/usr.sbin/ppp/Makefile index 67cff18..40ecd39 100644 --- a/usr.sbin/ppp/Makefile +++ b/usr.sbin/ppp/Makefile @@ -1,8 +1,8 @@ -# $Id: Makefile,v 1.32 1997/11/22 03:37:21 brian Exp $ +# $Id: Makefile,v 1.33 1997/12/03 10:23:44 brian Exp $ PROG= ppp SRCS= arp.c async.c auth.c ccp.c chap.c chat.c command.c deflate.c \ - defs.c filter.c fsm.c hdlc.c id.c ip.c ipcp.c lcp.c \ + defs.c filter.c fsm.c hdlc.c id.c ip.c ipcp.c iplist.c lcp.c \ log.c lqr.c main.c mbuf.c modem.c os.c pap.c phase.c \ pred.c route.c server.c sig.c slcompress.c systems.c throughput.c \ timer.c tun.c vars.c vjcomp.c diff --git a/usr.sbin/ppp/ccp.c b/usr.sbin/ppp/ccp.c index 4891135..b9c8d90 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.22 1997/12/03 23:27:53 brian Exp $ + * $Id: ccp.c,v 1.23 1997/12/04 18:49:32 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 71366fd..4268241 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.107 1997/12/07 04:09:10 brian Exp $ + * $Id: command.c,v 1.108 1997/12/08 20:09:10 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 b154e1a..d152799 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.18 1997/11/12 18:47:30 brian Exp $ + * $Id: filter.c,v 1.19 1997/11/22 03:37:30 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 48f9d07..6ad03e2 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.22 1997/11/22 03:37:31 brian Exp $ + * $Id: fsm.c,v 1.23 1997/12/03 10:23:46 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 dc91900..624ea88 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.40 1997/12/04 18:49:35 brian Exp $ + * $Id: ipcp.c,v 1.41 1997/12/06 22:43:58 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 9d65e8e..f4aa9bd 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.13 1997/11/18 14:52:05 brian Exp $ + * $Id: ipcp.h,v 1.14 1997/11/22 03:37:35 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 0000000..dce202a --- /dev/null +++ b/usr.sbin/ppp/iplist.c @@ -0,0 +1,200 @@ +/* + * $Id:$ + */ + +#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 0000000..cee4deb --- /dev/null +++ b/usr.sbin/ppp/iplist.h @@ -0,0 +1,24 @@ +/* + * $Id:$ + */ + +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 c7baf09..4d64a69 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.105 1997/11/22 03:37:39 brian Exp $ + * $Id: main.c,v 1.106 1997/12/03 10:23:50 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 1f13b34..05dbf81 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.35 1997/11/22 03:37:42 brian Exp $ + * $Id: os.c,v 1.36 1997/12/03 10:23:51 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 0c19f2e..7d6cc5e 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.11 1997/11/16 22:15:09 brian Exp $ + * $Id: os.h,v 1.12 1997/11/22 03:37:42 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 4b6d175..219b764 100644 --- a/usr.sbin/ppp/phase.c +++ b/usr.sbin/ppp/phase.c @@ -1,5 +1,5 @@ /* - * $Id: phase.c,v 1.3 1997/11/22 03:37:43 brian Exp $ + * $Id: phase.c,v 1.4 1997/12/07 23:55:29 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 8f64191..caef2d0 100644 --- a/usr.sbin/ppp/ppp.8 +++ b/usr.sbin/ppp/ppp.8 @@ -1,4 +1,4 @@ -.\" $Id: ppp.8,v 1.82 1997/12/03 23:27:59 brian Exp $ +.\" $Id: ppp.8,v 1.83 1997/12/07 04:09:12 brian Exp $ .Dd 20 September 1995 .Os FreeBSD .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/ppp.8.m4 b/usr.sbin/ppp/ppp.8.m4 index 8f64191..caef2d0 100644 --- a/usr.sbin/ppp/ppp.8.m4 +++ b/usr.sbin/ppp/ppp.8.m4 @@ -1,4 +1,4 @@ -.\" $Id: ppp.8,v 1.82 1997/12/03 23:27:59 brian Exp $ +.\" $Id: ppp.8,v 1.83 1997/12/07 04:09:12 brian Exp $ .Dd 20 September 1995 .Os FreeBSD .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 c1c0b33..3132937 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.29 1997/12/04 18:49:39 brian Exp $ + * $Id: route.c,v 1.30 1997/12/07 04:09:15 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 23b56ef..fddf0f7 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.6 1997/10/26 01:03:38 brian Exp $ + * $Id: route.h,v 1.7 1997/11/22 03:37:45 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); diff --git a/usr.sbin/ppp/vars.c b/usr.sbin/ppp/vars.c index a6429a2..281e168 100644 --- a/usr.sbin/ppp/vars.c +++ b/usr.sbin/ppp/vars.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: vars.c,v 1.38 1997/12/03 10:23:53 brian Exp $ + * $Id: vars.c,v 1.39 1997/12/03 23:28:01 brian Exp $ * */ #include <sys/param.h> @@ -38,8 +38,8 @@ #include "vars.h" #include "auth.h" -char VarVersion[] = "PPP Version 1.5"; -char VarLocalVersion[] = "$Date: 1997/12/03 10:23:53 $"; +char VarVersion[] = "PPP Version 1.6"; +char VarLocalVersion[] = "$Date: 1997/12/03 23:28:01 $"; int Utmp = 0; int ipInOctets = 0; int ipOutOctets = 0; |