From bcc332bdb0fffe5e7900c7e26954f062c95b0c23 Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Sat, 13 Dec 1997 02:37:33 +0000 Subject: [PATCH] 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). Up the version number (1.5 -> 1.6). 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. --- usr.sbin/ppp/Makefile | 4 +- usr.sbin/ppp/ccp.c | 4 +- usr.sbin/ppp/command.c | 38 +++++--- usr.sbin/ppp/filter.c | 15 ++-- usr.sbin/ppp/fsm.c | 5 +- usr.sbin/ppp/ipcp.c | 39 ++++++-- usr.sbin/ppp/ipcp.h | 3 +- usr.sbin/ppp/iplist.c | 200 +++++++++++++++++++++++++++++++++++++++++ usr.sbin/ppp/iplist.h | 24 +++++ usr.sbin/ppp/main.c | 4 +- usr.sbin/ppp/os.c | 79 +++++++--------- usr.sbin/ppp/os.h | 5 +- usr.sbin/ppp/phase.c | 4 +- usr.sbin/ppp/ppp.8 | 86 +++++++++++++----- usr.sbin/ppp/ppp.8.m4 | 86 +++++++++++++----- usr.sbin/ppp/route.c | 42 +++++++-- usr.sbin/ppp/route.h | 3 +- usr.sbin/ppp/vars.c | 6 +- 18 files changed, 504 insertions(+), 143 deletions(-) create mode 100644 usr.sbin/ppp/iplist.c create mode 100644 usr.sbin/ppp/iplist.h diff --git a/usr.sbin/ppp/Makefile b/usr.sbin/ppp/Makefile index 67cff1883c5..40ecd39dd2e 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 4891135cd17..b9c8d909d8b 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 71366fd4ebc..4268241b871 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 @@ -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 b154e1abbc3..d1527999505 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 48f9d072071..6ad03e25949 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 dc91900dc0a..624ea88e652 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 9d65e8e4c37..f4aa9bd61de 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 00000000000..dce202a5b98 --- /dev/null +++ b/usr.sbin/ppp/iplist.c @@ -0,0 +1,200 @@ +/* + * $Id:$ + */ + +#include +#include +#include + +#include +#include + +#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..cee4debba2b --- /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 c7baf09c2e8..4d64a69b710 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 1f13b346a6c..05dbf81d3fe 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 @@ -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 0c19f2e282c..7d6cc5e2a79 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 4b6d1759834..219b76420ed 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 @@ -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 8f64191a552..caef2d0e3ba 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 8f64191a552..caef2d0e3ba 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 c1c0b33f0ea..31329374ad8 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 23b56ef89e9..fddf0f7851a 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 a6429a2c71a..281e16893c9 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 @@ -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; -- 2.45.2