11ae349f5Scvs2svn /* 21ae349f5Scvs2svn * PPP IP Control Protocol (IPCP) Module 31ae349f5Scvs2svn * 41ae349f5Scvs2svn * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 51ae349f5Scvs2svn * 61ae349f5Scvs2svn * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 71ae349f5Scvs2svn * 81ae349f5Scvs2svn * Redistribution and use in source and binary forms are permitted 91ae349f5Scvs2svn * provided that the above copyright notice and this paragraph are 101ae349f5Scvs2svn * duplicated in all such forms and that any documentation, 111ae349f5Scvs2svn * advertising materials, and other materials related to such 121ae349f5Scvs2svn * distribution and use acknowledge that the software was developed 131ae349f5Scvs2svn * by the Internet Initiative Japan, Inc. The name of the 141ae349f5Scvs2svn * IIJ may not be used to endorse or promote products derived 151ae349f5Scvs2svn * from this software without specific prior written permission. 161ae349f5Scvs2svn * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 171ae349f5Scvs2svn * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 181ae349f5Scvs2svn * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 191ae349f5Scvs2svn * 2083d1af55SBrian Somers * $Id: ipcp.c,v 1.50.2.7 1998/02/02 19:33:36 brian Exp $ 211ae349f5Scvs2svn * 221ae349f5Scvs2svn * TODO: 231ae349f5Scvs2svn * o More RFC1772 backwoard compatibility 241ae349f5Scvs2svn */ 251ae349f5Scvs2svn #include <sys/param.h> 261ae349f5Scvs2svn #include <netinet/in_systm.h> 271ae349f5Scvs2svn #include <netinet/in.h> 281ae349f5Scvs2svn #include <netinet/ip.h> 291ae349f5Scvs2svn #include <arpa/inet.h> 301ae349f5Scvs2svn #include <sys/socket.h> 311ae349f5Scvs2svn #include <netdb.h> 321ae349f5Scvs2svn 331ae349f5Scvs2svn #include <stdio.h> 341ae349f5Scvs2svn #include <stdlib.h> 351ae349f5Scvs2svn #include <string.h> 366140ba11SBrian Somers #include <termios.h> 371ae349f5Scvs2svn #include <unistd.h> 381ae349f5Scvs2svn 391ae349f5Scvs2svn #include "command.h" 401ae349f5Scvs2svn #include "mbuf.h" 411ae349f5Scvs2svn #include "log.h" 421ae349f5Scvs2svn #include "defs.h" 431ae349f5Scvs2svn #include "timer.h" 441ae349f5Scvs2svn #include "fsm.h" 451ae349f5Scvs2svn #include "lcpproto.h" 461ae349f5Scvs2svn #include "lcp.h" 471ae349f5Scvs2svn #include "iplist.h" 4829e275ceSBrian Somers #include "throughput.h" 491ae349f5Scvs2svn #include "ipcp.h" 501ae349f5Scvs2svn #include "slcompress.h" 517a6f8720SBrian Somers #include "bundle.h" 521ae349f5Scvs2svn #include "phase.h" 531ae349f5Scvs2svn #include "loadalias.h" 541ae349f5Scvs2svn #include "vars.h" 551ae349f5Scvs2svn #include "vjcomp.h" 561ae349f5Scvs2svn #include "ip.h" 571ae349f5Scvs2svn #include "route.h" 581ae349f5Scvs2svn #include "filter.h" 598c07a7b2SBrian Somers #include "hdlc.h" 606140ba11SBrian Somers #include "async.h" 618c07a7b2SBrian Somers #include "link.h" 6263b73463SBrian Somers #include "physical.h" 631ae349f5Scvs2svn 6429e275ceSBrian Somers struct compreq { 6529e275ceSBrian Somers u_short proto; 6629e275ceSBrian Somers u_char slots; 6729e275ceSBrian Somers u_char compcid; 6829e275ceSBrian Somers }; 691ae349f5Scvs2svn 701ae349f5Scvs2svn static void IpcpLayerUp(struct fsm *); 711ae349f5Scvs2svn static void IpcpLayerDown(struct fsm *); 727308ec68SBrian Somers static void IpcpLayerStart(struct fsm *); 737308ec68SBrian Somers static void IpcpLayerFinish(struct fsm *); 741ae349f5Scvs2svn static void IpcpInitRestartCounter(struct fsm *); 757308ec68SBrian Somers static void IpcpSendConfigReq(struct fsm *); 767308ec68SBrian Somers static void IpcpSendTerminateReq(struct fsm *); 777308ec68SBrian Somers static void IpcpSendTerminateAck(struct fsm *); 7883d1af55SBrian Somers static void IpcpDecodeConfig(struct fsm *, u_char *, int, int); 7983d1af55SBrian Somers 8083d1af55SBrian Somers static struct fsm_callbacks ipcp_Callbacks = { 8183d1af55SBrian Somers IpcpLayerUp, 8283d1af55SBrian Somers IpcpLayerDown, 8383d1af55SBrian Somers IpcpLayerStart, 8483d1af55SBrian Somers IpcpLayerFinish, 8583d1af55SBrian Somers IpcpInitRestartCounter, 8683d1af55SBrian Somers IpcpSendConfigReq, 8783d1af55SBrian Somers IpcpSendTerminateReq, 8883d1af55SBrian Somers IpcpSendTerminateAck, 8983d1af55SBrian Somers IpcpDecodeConfig, 9083d1af55SBrian Somers }; 911ae349f5Scvs2svn 927308ec68SBrian Somers struct ipcpstate IpcpInfo = { 937308ec68SBrian Somers { 941ae349f5Scvs2svn "IPCP", 951ae349f5Scvs2svn PROTO_IPCP, 961ae349f5Scvs2svn IPCP_MAXCODE, 971ae349f5Scvs2svn 0, 981ae349f5Scvs2svn ST_INITIAL, 991ae349f5Scvs2svn 0, 0, 0, 1001ae349f5Scvs2svn {0, 0, 0, NULL, NULL, NULL}, /* FSM timer */ 1011ae349f5Scvs2svn {0, 0, 0, NULL, NULL, NULL}, /* Open timer */ 1021ae349f5Scvs2svn {0, 0, 0, NULL, NULL, NULL}, /* Stopped timer */ 1031ae349f5Scvs2svn LogIPCP, 1047a6f8720SBrian Somers NULL, /* link */ 1057a6f8720SBrian Somers NULL, /* bundle */ 10683d1af55SBrian Somers &ipcp_Callbacks, 1077308ec68SBrian Somers }, 1087308ec68SBrian Somers MAX_VJ_STATES, 1097308ec68SBrian Somers 1 1101ae349f5Scvs2svn }; 1111ae349f5Scvs2svn 1121ae349f5Scvs2svn static const char *cftypes[] = { 1131ae349f5Scvs2svn /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ 1141ae349f5Scvs2svn "???", 1151ae349f5Scvs2svn "IPADDRS", /* 1: IP-Addresses */ /* deprecated */ 1161ae349f5Scvs2svn "COMPPROTO", /* 2: IP-Compression-Protocol */ 1171ae349f5Scvs2svn "IPADDR", /* 3: IP-Address */ 1181ae349f5Scvs2svn }; 1191ae349f5Scvs2svn 1201ae349f5Scvs2svn #define NCFTYPES (sizeof cftypes/sizeof cftypes[0]) 1211ae349f5Scvs2svn 1221ae349f5Scvs2svn static const char *cftypes128[] = { 1231ae349f5Scvs2svn /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ 1241ae349f5Scvs2svn "???", 1251ae349f5Scvs2svn "PRIDNS", /* 129: Primary DNS Server Address */ 1261ae349f5Scvs2svn "PRINBNS", /* 130: Primary NBNS Server Address */ 1271ae349f5Scvs2svn "SECDNS", /* 131: Secondary DNS Server Address */ 1281ae349f5Scvs2svn "SECNBNS", /* 132: Secondary NBNS Server Address */ 1291ae349f5Scvs2svn }; 1301ae349f5Scvs2svn 1311ae349f5Scvs2svn #define NCFTYPES128 (sizeof cftypes128/sizeof cftypes128[0]) 1321ae349f5Scvs2svn 1331ae349f5Scvs2svn void 1341ae349f5Scvs2svn IpcpAddInOctets(int n) 1351ae349f5Scvs2svn { 13629e275ceSBrian Somers throughput_addin(&IpcpInfo.throughput, n); 1371ae349f5Scvs2svn } 1381ae349f5Scvs2svn 1391ae349f5Scvs2svn void 1401ae349f5Scvs2svn IpcpAddOutOctets(int n) 1411ae349f5Scvs2svn { 14229e275ceSBrian Somers throughput_addout(&IpcpInfo.throughput, n); 1431ae349f5Scvs2svn } 1441ae349f5Scvs2svn 1451ae349f5Scvs2svn int 1461ae349f5Scvs2svn ReportIpcpStatus(struct cmdargs const *arg) 1471ae349f5Scvs2svn { 1481ae349f5Scvs2svn if (!VarTerm) 1491ae349f5Scvs2svn return 1; 1507308ec68SBrian Somers fprintf(VarTerm, "%s [%s]\n", IpcpInfo.fsm.name, 1517308ec68SBrian Somers StateNames[IpcpInfo.fsm.state]); 1527308ec68SBrian Somers if (IpcpInfo.fsm.state == ST_OPENED) { 15342e91bc7SBrian Somers fprintf(VarTerm, " His side: %s, %s\n", 1541ae349f5Scvs2svn inet_ntoa(IpcpInfo.his_ipaddr), vj2asc(IpcpInfo.his_compproto)); 15542e91bc7SBrian Somers fprintf(VarTerm, " My side: %s, %s\n", 1561ae349f5Scvs2svn inet_ntoa(IpcpInfo.want_ipaddr), vj2asc(IpcpInfo.want_compproto)); 1571ae349f5Scvs2svn } 1581ae349f5Scvs2svn 15942e91bc7SBrian Somers fprintf(VarTerm, "\nDefaults:\n"); 1601ae349f5Scvs2svn fprintf(VarTerm, " My Address: %s/%d\n", 16129e275ceSBrian Somers inet_ntoa(IpcpInfo.DefMyAddress.ipaddr), IpcpInfo.DefMyAddress.width); 16229e275ceSBrian Somers if (iplist_isvalid(&IpcpInfo.DefHisChoice)) 16342e91bc7SBrian Somers fprintf(VarTerm, " His Address: %s\n", 16442e91bc7SBrian Somers IpcpInfo.DefHisChoice.src); 1651ae349f5Scvs2svn else 1661ae349f5Scvs2svn fprintf(VarTerm, " His Address: %s/%d\n", 16729e275ceSBrian Somers inet_ntoa(IpcpInfo.DefHisAddress.ipaddr), 16829e275ceSBrian Somers IpcpInfo.DefHisAddress.width); 16929e275ceSBrian Somers if (IpcpInfo.HaveTriggerAddress) 17029e275ceSBrian Somers fprintf(VarTerm, " Negotiation(trigger): %s\n", 17129e275ceSBrian Somers inet_ntoa(IpcpInfo.TriggerAddress)); 1721ae349f5Scvs2svn else 1731ae349f5Scvs2svn fprintf(VarTerm, " Negotiation(trigger): MYADDR\n"); 17442e91bc7SBrian Somers fprintf(VarTerm, " Initial VJ slots: %d\n", IpcpInfo.VJInitSlots); 17542e91bc7SBrian Somers fprintf(VarTerm, " Initial VJ compression: %s\n", 17642e91bc7SBrian Somers IpcpInfo.VJInitComp ? "on" : "off"); 1771ae349f5Scvs2svn 1781ae349f5Scvs2svn fprintf(VarTerm, "\n"); 17929e275ceSBrian Somers throughput_disp(&IpcpInfo.throughput, VarTerm); 1801ae349f5Scvs2svn 1811ae349f5Scvs2svn return 0; 1821ae349f5Scvs2svn } 1831ae349f5Scvs2svn 1841ae349f5Scvs2svn void 1851ae349f5Scvs2svn IpcpDefAddress() 1861ae349f5Scvs2svn { 1877308ec68SBrian Somers /* Setup default IP addresses (`hostname` -> 0.0.0.0) */ 1881ae349f5Scvs2svn struct hostent *hp; 1891ae349f5Scvs2svn char name[200]; 1901ae349f5Scvs2svn 19129e275ceSBrian Somers memset(&IpcpInfo.DefMyAddress, '\0', sizeof IpcpInfo.DefMyAddress); 19229e275ceSBrian Somers memset(&IpcpInfo.DefHisAddress, '\0', sizeof IpcpInfo.DefHisAddress); 19329e275ceSBrian Somers IpcpInfo.HaveTriggerAddress = 0; 1941ae349f5Scvs2svn if (gethostname(name, sizeof name) == 0) { 1951ae349f5Scvs2svn hp = gethostbyname(name); 19629e275ceSBrian Somers if (hp && hp->h_addrtype == AF_INET) 19729e275ceSBrian Somers memcpy(&IpcpInfo.DefMyAddress.ipaddr.s_addr, hp->h_addr, hp->h_length); 1981ae349f5Scvs2svn } 1991ae349f5Scvs2svn } 2001ae349f5Scvs2svn 2011ae349f5Scvs2svn int 2021ae349f5Scvs2svn SetInitVJ(struct cmdargs const *args) 2031ae349f5Scvs2svn { 2041ae349f5Scvs2svn if (args->argc != 2) 2051ae349f5Scvs2svn return -1; 2061ae349f5Scvs2svn if (!strcasecmp(args->argv[0], "slots")) { 2071ae349f5Scvs2svn int slots; 2081ae349f5Scvs2svn 2091ae349f5Scvs2svn slots = atoi(args->argv[1]); 2101ae349f5Scvs2svn if (slots < 4 || slots > 16) 2111ae349f5Scvs2svn return 1; 21229e275ceSBrian Somers IpcpInfo.VJInitSlots = slots; 2131ae349f5Scvs2svn return 0; 2141ae349f5Scvs2svn } else if (!strcasecmp(args->argv[0], "slotcomp")) { 2151ae349f5Scvs2svn if (!strcasecmp(args->argv[1], "on")) 21629e275ceSBrian Somers IpcpInfo.VJInitComp = 1; 2171ae349f5Scvs2svn else if (!strcasecmp(args->argv[1], "off")) 21829e275ceSBrian Somers IpcpInfo.VJInitComp = 0; 2191ae349f5Scvs2svn else 2201ae349f5Scvs2svn return 2; 2211ae349f5Scvs2svn return 0; 2221ae349f5Scvs2svn } 2231ae349f5Scvs2svn return -1; 2241ae349f5Scvs2svn } 2251ae349f5Scvs2svn 2261ae349f5Scvs2svn void 2277a6f8720SBrian Somers IpcpInit(struct bundle *bundle, struct link *l) 2281ae349f5Scvs2svn { 2297308ec68SBrian Somers /* Initialise ourselves */ 2307a6f8720SBrian Somers FsmInit(&IpcpInfo.fsm, bundle, l); 23129e275ceSBrian Somers if (iplist_isvalid(&IpcpInfo.DefHisChoice)) 23229e275ceSBrian Somers iplist_setrandpos(&IpcpInfo.DefHisChoice); 23329e275ceSBrian Somers IpcpInfo.his_compproto = 0; 23429e275ceSBrian Somers IpcpInfo.his_reject = IpcpInfo.my_reject = 0; 23529e275ceSBrian Somers 2361ae349f5Scvs2svn if ((mode & MODE_DEDICATED) && !GetLabel()) { 23729e275ceSBrian Somers IpcpInfo.want_ipaddr.s_addr = IpcpInfo.his_ipaddr.s_addr = INADDR_ANY; 23829e275ceSBrian Somers IpcpInfo.his_ipaddr.s_addr = INADDR_ANY; 2391ae349f5Scvs2svn } else { 24029e275ceSBrian Somers IpcpInfo.want_ipaddr.s_addr = IpcpInfo.DefMyAddress.ipaddr.s_addr; 24129e275ceSBrian Somers IpcpInfo.his_ipaddr.s_addr = IpcpInfo.DefHisAddress.ipaddr.s_addr; 2421ae349f5Scvs2svn } 2431ae349f5Scvs2svn 2441ae349f5Scvs2svn /* 2451ae349f5Scvs2svn * Some implementations of PPP require that we send a 2461ae349f5Scvs2svn * *special* value as our address, even though the rfc specifies 2471ae349f5Scvs2svn * full negotiation (e.g. "0.0.0.0" or Not "0.0.0.0"). 2481ae349f5Scvs2svn */ 24929e275ceSBrian Somers if (IpcpInfo.HaveTriggerAddress) { 25029e275ceSBrian Somers IpcpInfo.want_ipaddr.s_addr = IpcpInfo.TriggerAddress.s_addr; 25129e275ceSBrian Somers LogPrintf(LogIPCP, "Using trigger address %s\n", 25229e275ceSBrian Somers inet_ntoa(IpcpInfo.TriggerAddress)); 2531ae349f5Scvs2svn } 25429e275ceSBrian Somers 2551ae349f5Scvs2svn if (Enabled(ConfVjcomp)) 25629e275ceSBrian Somers IpcpInfo.want_compproto = (PROTO_VJCOMP << 16) + 25729e275ceSBrian Somers ((IpcpInfo.VJInitSlots - 1) << 8) + 25829e275ceSBrian Somers IpcpInfo.VJInitComp; 2591ae349f5Scvs2svn else 2601ae349f5Scvs2svn IpcpInfo.want_compproto = 0; 2616140ba11SBrian Somers VjInit(IpcpInfo.VJInitSlots - 1); 26229e275ceSBrian Somers 2631ae349f5Scvs2svn IpcpInfo.heis1172 = 0; 2647308ec68SBrian Somers IpcpInfo.fsm.maxconfig = 10; 26529e275ceSBrian Somers throughput_init(&IpcpInfo.throughput); 2661ae349f5Scvs2svn } 2671ae349f5Scvs2svn 2681ae349f5Scvs2svn static void 2691ae349f5Scvs2svn IpcpInitRestartCounter(struct fsm * fp) 2701ae349f5Scvs2svn { 2717308ec68SBrian Somers /* Set fsm timer load */ 2721ae349f5Scvs2svn fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 2731ae349f5Scvs2svn fp->restart = 5; 2741ae349f5Scvs2svn } 2751ae349f5Scvs2svn 2761ae349f5Scvs2svn static void 2771ae349f5Scvs2svn IpcpSendConfigReq(struct fsm *fp) 2781ae349f5Scvs2svn { 2797308ec68SBrian Somers /* Send config REQ please */ 2808c07a7b2SBrian Somers struct physical *p = link2physical(fp->link); 28183d1af55SBrian Somers struct ipcpstate *ipcp = fsm2ipcp(fp); 2821ae349f5Scvs2svn u_char *cp; 2831ae349f5Scvs2svn struct lcp_opt o; 2841ae349f5Scvs2svn 2851ae349f5Scvs2svn cp = ReqBuff; 2861ae349f5Scvs2svn LogPrintf(LogIPCP, "IpcpSendConfigReq\n"); 28783d1af55SBrian Somers if ((p && !Physical_IsSync(p)) || !REJECTED(ipcp, TY_IPADDR)) { 2881ae349f5Scvs2svn o.id = TY_IPADDR; 2891ae349f5Scvs2svn o.len = 6; 29083d1af55SBrian Somers *(u_long *)o.data = ipcp->want_ipaddr.s_addr; 2911ae349f5Scvs2svn cp += LcpPutConf(LogIPCP, cp, &o, cftypes[o.id], 29283d1af55SBrian Somers inet_ntoa(ipcp->want_ipaddr)); 2931ae349f5Scvs2svn } 2941ae349f5Scvs2svn 29583d1af55SBrian Somers if (ipcp->want_compproto && !REJECTED(ipcp, TY_COMPPROTO)) { 2961ae349f5Scvs2svn const char *args; 2971ae349f5Scvs2svn o.id = TY_COMPPROTO; 29883d1af55SBrian Somers if (ipcp->heis1172) { 2991ae349f5Scvs2svn o.len = 4; 3001ae349f5Scvs2svn *(u_short *)o.data = htons(PROTO_VJCOMP); 3011ae349f5Scvs2svn args = ""; 3021ae349f5Scvs2svn } else { 3031ae349f5Scvs2svn o.len = 6; 30483d1af55SBrian Somers *(u_long *)o.data = htonl(ipcp->want_compproto); 30583d1af55SBrian Somers args = vj2asc(ipcp->want_compproto); 3061ae349f5Scvs2svn } 3071ae349f5Scvs2svn cp += LcpPutConf(LogIPCP, cp, &o, cftypes[o.id], args); 3081ae349f5Scvs2svn } 3091ae349f5Scvs2svn FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 3101ae349f5Scvs2svn } 3111ae349f5Scvs2svn 3121ae349f5Scvs2svn static void 3131ae349f5Scvs2svn IpcpSendTerminateReq(struct fsm * fp) 3141ae349f5Scvs2svn { 3157308ec68SBrian Somers /* Term REQ just sent by FSM */ 3161ae349f5Scvs2svn } 3171ae349f5Scvs2svn 3181ae349f5Scvs2svn static void 3191ae349f5Scvs2svn IpcpSendTerminateAck(struct fsm * fp) 3201ae349f5Scvs2svn { 3217308ec68SBrian Somers /* Send Term ACK please */ 3221ae349f5Scvs2svn LogPrintf(LogIPCP, "IpcpSendTerminateAck\n"); 3231ae349f5Scvs2svn FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 3241ae349f5Scvs2svn } 3251ae349f5Scvs2svn 3261ae349f5Scvs2svn static void 3271ae349f5Scvs2svn IpcpLayerStart(struct fsm * fp) 3281ae349f5Scvs2svn { 3297308ec68SBrian Somers /* We're about to start up ! */ 3301ae349f5Scvs2svn LogPrintf(LogIPCP, "IpcpLayerStart.\n"); 3311ae349f5Scvs2svn } 3321ae349f5Scvs2svn 3331ae349f5Scvs2svn static void 3341ae349f5Scvs2svn IpcpLayerFinish(struct fsm * fp) 3351ae349f5Scvs2svn { 3367308ec68SBrian Somers /* We're now down */ 3371ae349f5Scvs2svn LogPrintf(LogIPCP, "IpcpLayerFinish.\n"); 3387308ec68SBrian Somers /* Better tell LCP that it's all over (we're the only NCP) */ 3391ae349f5Scvs2svn reconnect(RECON_FALSE); 3407308ec68SBrian Somers LcpClose(&LcpInfo.fsm); 3411ae349f5Scvs2svn } 3421ae349f5Scvs2svn 3431ae349f5Scvs2svn static void 3441ae349f5Scvs2svn IpcpLayerDown(struct fsm *fp) 3451ae349f5Scvs2svn { 3467308ec68SBrian Somers /* About to come down */ 34783d1af55SBrian Somers struct ipcpstate *ipcp = fsm2ipcp(fp); 3481ae349f5Scvs2svn LogPrintf(LogIPCP, "IpcpLayerDown.\n"); 34983d1af55SBrian Somers throughput_stop(&ipcp->throughput); 35083d1af55SBrian Somers throughput_log(&ipcp->throughput, LogIPCP, NULL); 3511ae349f5Scvs2svn } 3521ae349f5Scvs2svn 3531ae349f5Scvs2svn static void 3541ae349f5Scvs2svn IpcpLayerUp(struct fsm *fp) 3551ae349f5Scvs2svn { 3567308ec68SBrian Somers /* We're now up */ 35783d1af55SBrian Somers struct ipcpstate *ipcp = fsm2ipcp(fp); 3581ae349f5Scvs2svn char tbuff[100]; 3591ae349f5Scvs2svn 3601ae349f5Scvs2svn Prompt(); 3611ae349f5Scvs2svn LogPrintf(LogIPCP, "IpcpLayerUp(%d).\n", fp->state); 36283d1af55SBrian Somers snprintf(tbuff, sizeof tbuff, "myaddr = %s ", inet_ntoa(ipcp->want_ipaddr)); 3631ae349f5Scvs2svn 36483d1af55SBrian Somers if (ipcp->his_compproto >> 16 == PROTO_VJCOMP) 36583d1af55SBrian Somers VjInit((ipcp->his_compproto >> 8) & 255); 3661ae349f5Scvs2svn 3671ae349f5Scvs2svn LogPrintf(LogIsKept(LogIPCP) ? LogIPCP : LogLINK, " %s hisaddr = %s\n", 36883d1af55SBrian Somers tbuff, inet_ntoa(ipcp->his_ipaddr)); 36983d1af55SBrian Somers if (bundle_SetIPaddress(fp->bundle, ipcp->want_ipaddr, 37083d1af55SBrian Somers ipcp->his_ipaddr) < 0) { 3711ae349f5Scvs2svn if (VarTerm) 3721ae349f5Scvs2svn LogPrintf(LogERROR, "IpcpLayerUp: unable to set ip address\n"); 3731ae349f5Scvs2svn return; 3741ae349f5Scvs2svn } 3751ae349f5Scvs2svn #ifndef NOALIAS 3761ae349f5Scvs2svn if (mode & MODE_ALIAS) 37783d1af55SBrian Somers VarPacketAliasSetAddress(ipcp->want_ipaddr); 3781ae349f5Scvs2svn #endif 3797a6f8720SBrian Somers bundle_Linkup(fp->bundle); 38083d1af55SBrian Somers throughput_start(&ipcp->throughput); 3811ae349f5Scvs2svn StartIdleTimer(); 3821ae349f5Scvs2svn } 3831ae349f5Scvs2svn 3841ae349f5Scvs2svn void 3851ae349f5Scvs2svn IpcpUp() 3861ae349f5Scvs2svn { 3877308ec68SBrian Somers /* Lower layers are ready.... go */ 3887308ec68SBrian Somers FsmUp(&IpcpInfo.fsm); 3891ae349f5Scvs2svn LogPrintf(LogIPCP, "IPCP Up event!!\n"); 3901ae349f5Scvs2svn } 3911ae349f5Scvs2svn 3921ae349f5Scvs2svn void 3931ae349f5Scvs2svn IpcpOpen() 3941ae349f5Scvs2svn { 3957308ec68SBrian Somers /* Start IPCP please */ 3967308ec68SBrian Somers FsmOpen(&IpcpInfo.fsm); 3971ae349f5Scvs2svn } 3981ae349f5Scvs2svn 3991ae349f5Scvs2svn static int 4001ae349f5Scvs2svn AcceptableAddr(struct in_range *prange, struct in_addr ipaddr) 4011ae349f5Scvs2svn { 4027308ec68SBrian Somers /* Is the given IP in the given range ? */ 4031ae349f5Scvs2svn LogPrintf(LogDEBUG, "requested = %x\n", htonl(ipaddr.s_addr)); 4041ae349f5Scvs2svn LogPrintf(LogDEBUG, "range = %x\n", htonl(prange->ipaddr.s_addr)); 4051ae349f5Scvs2svn LogPrintf(LogDEBUG, "/%x\n", htonl(prange->mask.s_addr)); 4061ae349f5Scvs2svn LogPrintf(LogDEBUG, "%x, %x\n", htonl(prange->ipaddr.s_addr & prange-> 4071ae349f5Scvs2svn mask.s_addr), htonl(ipaddr.s_addr & prange->mask.s_addr)); 4081ae349f5Scvs2svn return (prange->ipaddr.s_addr & prange->mask.s_addr) == 4091ae349f5Scvs2svn (ipaddr.s_addr & prange->mask.s_addr) && ipaddr.s_addr; 4101ae349f5Scvs2svn } 4111ae349f5Scvs2svn 4121ae349f5Scvs2svn static void 41383d1af55SBrian Somers IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type) 4141ae349f5Scvs2svn { 4157308ec68SBrian Somers /* Deal with incoming PROTO_IPCP */ 41683d1af55SBrian Somers struct ipcpstate *ipcp = fsm2ipcp(fp); 4171ae349f5Scvs2svn int type, length; 4181ae349f5Scvs2svn u_long *lp, compproto; 4191ae349f5Scvs2svn struct compreq *pcomp; 4201ae349f5Scvs2svn struct in_addr ipaddr, dstipaddr, dnsstuff, ms_info_req; 4211ae349f5Scvs2svn char tbuff[100]; 4221ae349f5Scvs2svn char tbuff2[100]; 4231ae349f5Scvs2svn 4241ae349f5Scvs2svn ackp = AckBuff; 4251ae349f5Scvs2svn nakp = NakBuff; 4261ae349f5Scvs2svn rejp = RejBuff; 4271ae349f5Scvs2svn 4281ae349f5Scvs2svn while (plen >= sizeof(struct fsmconfig)) { 4291ae349f5Scvs2svn type = *cp; 4301ae349f5Scvs2svn length = cp[1]; 4311ae349f5Scvs2svn if (type < NCFTYPES) 4321ae349f5Scvs2svn snprintf(tbuff, sizeof tbuff, " %s[%d] ", cftypes[type], length); 4331ae349f5Scvs2svn else if (type > 128 && type < 128 + NCFTYPES128) 4341ae349f5Scvs2svn snprintf(tbuff, sizeof tbuff, " %s[%d] ", cftypes128[type-128], length); 4351ae349f5Scvs2svn else 4361ae349f5Scvs2svn snprintf(tbuff, sizeof tbuff, " <%d>[%d] ", type, length); 4371ae349f5Scvs2svn 4381ae349f5Scvs2svn switch (type) { 4391ae349f5Scvs2svn case TY_IPADDR: /* RFC1332 */ 4401ae349f5Scvs2svn lp = (u_long *) (cp + 2); 4411ae349f5Scvs2svn ipaddr.s_addr = *lp; 4421ae349f5Scvs2svn LogPrintf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 4431ae349f5Scvs2svn 4441ae349f5Scvs2svn switch (mode_type) { 4451ae349f5Scvs2svn case MODE_REQ: 44683d1af55SBrian Somers if (iplist_isvalid(&ipcp->DefHisChoice)) { 4471ae349f5Scvs2svn if (ipaddr.s_addr == INADDR_ANY || 44883d1af55SBrian Somers iplist_ip2pos(&ipcp->DefHisChoice, ipaddr) < 0 || 44983d1af55SBrian Somers bundle_TrySetIPaddress(fp->bundle, ipcp->DefMyAddress.ipaddr, 4507a6f8720SBrian Somers ipaddr)) { 4511ae349f5Scvs2svn LogPrintf(LogIPCP, "%s: Address invalid or already in use\n", 4521ae349f5Scvs2svn inet_ntoa(ipaddr)); 45383d1af55SBrian Somers ipcp->his_ipaddr = ChooseHisAddr 45483d1af55SBrian Somers (fp->bundle, ipcp->DefMyAddress.ipaddr); 45583d1af55SBrian Somers if (ipcp->his_ipaddr.s_addr == INADDR_ANY) { 4561ae349f5Scvs2svn memcpy(rejp, cp, length); 4571ae349f5Scvs2svn rejp += length; 4581ae349f5Scvs2svn } else { 4591ae349f5Scvs2svn memcpy(nakp, cp, 2); 46083d1af55SBrian Somers memcpy(nakp+2, &ipcp->his_ipaddr.s_addr, length - 2); 4611ae349f5Scvs2svn nakp += length; 4621ae349f5Scvs2svn } 4631ae349f5Scvs2svn break; 4641ae349f5Scvs2svn } 46583d1af55SBrian Somers } else if (!AcceptableAddr(&ipcp->DefHisAddress, ipaddr)) { 4661ae349f5Scvs2svn /* 4671ae349f5Scvs2svn * If destination address is not acceptable, insist to use what we 4681ae349f5Scvs2svn * want to use. 4691ae349f5Scvs2svn */ 4701ae349f5Scvs2svn memcpy(nakp, cp, 2); 47183d1af55SBrian Somers memcpy(nakp+2, &ipcp->his_ipaddr.s_addr, length - 2); 4721ae349f5Scvs2svn nakp += length; 4731ae349f5Scvs2svn break; 4741ae349f5Scvs2svn } 47583d1af55SBrian Somers ipcp->his_ipaddr = ipaddr; 4761ae349f5Scvs2svn memcpy(ackp, cp, length); 4771ae349f5Scvs2svn ackp += length; 4781ae349f5Scvs2svn break; 4791ae349f5Scvs2svn case MODE_NAK: 48083d1af55SBrian Somers if (AcceptableAddr(&ipcp->DefMyAddress, ipaddr)) { 4811ae349f5Scvs2svn /* Use address suggested by peer */ 4821ae349f5Scvs2svn snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s ", tbuff, 48383d1af55SBrian Somers inet_ntoa(ipcp->want_ipaddr)); 4841ae349f5Scvs2svn LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 48583d1af55SBrian Somers ipcp->want_ipaddr = ipaddr; 4861ae349f5Scvs2svn } else { 4871ae349f5Scvs2svn LogPrintf(LogIPCP, "%s: Unacceptable address!\n", inet_ntoa(ipaddr)); 48883d1af55SBrian Somers FsmClose(&ipcp->fsm); 4891ae349f5Scvs2svn } 4901ae349f5Scvs2svn break; 4911ae349f5Scvs2svn case MODE_REJ: 49283d1af55SBrian Somers ipcp->his_reject |= (1 << type); 4931ae349f5Scvs2svn break; 4941ae349f5Scvs2svn } 4951ae349f5Scvs2svn break; 4961ae349f5Scvs2svn case TY_COMPPROTO: 4971ae349f5Scvs2svn lp = (u_long *) (cp + 2); 4981ae349f5Scvs2svn compproto = htonl(*lp); 4991ae349f5Scvs2svn LogPrintf(LogIPCP, "%s %s\n", tbuff, vj2asc(compproto)); 5001ae349f5Scvs2svn 5011ae349f5Scvs2svn switch (mode_type) { 5021ae349f5Scvs2svn case MODE_REQ: 5031ae349f5Scvs2svn if (!Acceptable(ConfVjcomp)) { 5041ae349f5Scvs2svn memcpy(rejp, cp, length); 5051ae349f5Scvs2svn rejp += length; 5061ae349f5Scvs2svn } else { 5071ae349f5Scvs2svn pcomp = (struct compreq *) (cp + 2); 5081ae349f5Scvs2svn switch (length) { 5091ae349f5Scvs2svn case 4: /* RFC1172 */ 5101ae349f5Scvs2svn if (ntohs(pcomp->proto) == PROTO_VJCOMP) { 5111ae349f5Scvs2svn LogPrintf(LogWARN, "Peer is speaking RFC1172 compression protocol !\n"); 51283d1af55SBrian Somers ipcp->heis1172 = 1; 51383d1af55SBrian Somers ipcp->his_compproto = compproto; 5141ae349f5Scvs2svn memcpy(ackp, cp, length); 5151ae349f5Scvs2svn ackp += length; 5161ae349f5Scvs2svn } else { 5171ae349f5Scvs2svn memcpy(nakp, cp, 2); 5181ae349f5Scvs2svn pcomp->proto = htons(PROTO_VJCOMP); 5191ae349f5Scvs2svn memcpy(nakp+2, &pcomp, 2); 5201ae349f5Scvs2svn nakp += length; 5211ae349f5Scvs2svn } 5221ae349f5Scvs2svn break; 5231ae349f5Scvs2svn case 6: /* RFC1332 */ 5241ae349f5Scvs2svn if (ntohs(pcomp->proto) == PROTO_VJCOMP 52529e275ceSBrian Somers && pcomp->slots < MAX_VJ_STATES && pcomp->slots > 2) { 52683d1af55SBrian Somers ipcp->his_compproto = compproto; 52783d1af55SBrian Somers ipcp->heis1172 = 0; 5281ae349f5Scvs2svn memcpy(ackp, cp, length); 5291ae349f5Scvs2svn ackp += length; 5301ae349f5Scvs2svn } else { 5311ae349f5Scvs2svn memcpy(nakp, cp, 2); 5321ae349f5Scvs2svn pcomp->proto = htons(PROTO_VJCOMP); 53329e275ceSBrian Somers pcomp->slots = MAX_VJ_STATES - 1; 5341ae349f5Scvs2svn pcomp->compcid = 0; 5351ae349f5Scvs2svn memcpy(nakp+2, &pcomp, sizeof pcomp); 5361ae349f5Scvs2svn nakp += length; 5371ae349f5Scvs2svn } 5381ae349f5Scvs2svn break; 5391ae349f5Scvs2svn default: 5401ae349f5Scvs2svn memcpy(rejp, cp, length); 5411ae349f5Scvs2svn rejp += length; 5421ae349f5Scvs2svn break; 5431ae349f5Scvs2svn } 5441ae349f5Scvs2svn } 5451ae349f5Scvs2svn break; 5461ae349f5Scvs2svn case MODE_NAK: 5471ae349f5Scvs2svn LogPrintf(LogIPCP, "%s changing compproto: %08x --> %08x\n", 54883d1af55SBrian Somers tbuff, ipcp->want_compproto, compproto); 54983d1af55SBrian Somers ipcp->want_compproto = compproto; 5501ae349f5Scvs2svn break; 5511ae349f5Scvs2svn case MODE_REJ: 55283d1af55SBrian Somers ipcp->his_reject |= (1 << type); 5531ae349f5Scvs2svn break; 5541ae349f5Scvs2svn } 5551ae349f5Scvs2svn break; 5561ae349f5Scvs2svn case TY_IPADDRS: /* RFC1172 */ 5571ae349f5Scvs2svn lp = (u_long *) (cp + 2); 5581ae349f5Scvs2svn ipaddr.s_addr = *lp; 5591ae349f5Scvs2svn lp = (u_long *) (cp + 6); 5601ae349f5Scvs2svn dstipaddr.s_addr = *lp; 5611ae349f5Scvs2svn snprintf(tbuff2, sizeof tbuff2, "%s %s,", tbuff, inet_ntoa(ipaddr)); 5621ae349f5Scvs2svn LogPrintf(LogIPCP, "%s %s\n", tbuff2, inet_ntoa(dstipaddr)); 5631ae349f5Scvs2svn 5641ae349f5Scvs2svn switch (mode_type) { 5651ae349f5Scvs2svn case MODE_REQ: 56683d1af55SBrian Somers ipcp->his_ipaddr = ipaddr; 56783d1af55SBrian Somers ipcp->want_ipaddr = dstipaddr; 5681ae349f5Scvs2svn memcpy(ackp, cp, length); 5691ae349f5Scvs2svn ackp += length; 5701ae349f5Scvs2svn break; 5711ae349f5Scvs2svn case MODE_NAK: 5721ae349f5Scvs2svn snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s", tbuff, 57383d1af55SBrian Somers inet_ntoa(ipcp->want_ipaddr)); 5741ae349f5Scvs2svn LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 57583d1af55SBrian Somers ipcp->want_ipaddr = ipaddr; 57683d1af55SBrian Somers ipcp->his_ipaddr = dstipaddr; 5771ae349f5Scvs2svn break; 5781ae349f5Scvs2svn case MODE_REJ: 57983d1af55SBrian Somers ipcp->his_reject |= (1 << type); 5801ae349f5Scvs2svn break; 5811ae349f5Scvs2svn } 5821ae349f5Scvs2svn break; 5831ae349f5Scvs2svn 5841ae349f5Scvs2svn /* 5851ae349f5Scvs2svn * MS extensions for MS's PPP 5861ae349f5Scvs2svn */ 5871ae349f5Scvs2svn 5881ae349f5Scvs2svn #ifndef NOMSEXT 5891ae349f5Scvs2svn case TY_PRIMARY_DNS: /* MS PPP DNS negotiation hack */ 5901ae349f5Scvs2svn case TY_SECONDARY_DNS: 5911ae349f5Scvs2svn if (!Enabled(ConfMSExt)) { 5921ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NS req - rejected - msext disabled\n"); 59383d1af55SBrian Somers ipcp->my_reject |= (1 << type); 5941ae349f5Scvs2svn memcpy(rejp, cp, length); 5951ae349f5Scvs2svn rejp += length; 5961ae349f5Scvs2svn break; 5971ae349f5Scvs2svn } 5981ae349f5Scvs2svn switch (mode_type) { 5991ae349f5Scvs2svn case MODE_REQ: 6001ae349f5Scvs2svn lp = (u_long *) (cp + 2); 6011ae349f5Scvs2svn dnsstuff.s_addr = *lp; 60283d1af55SBrian Somers ms_info_req.s_addr = ipcp->ns_entries 60329e275ceSBrian Somers [(type - TY_PRIMARY_DNS) ? 1 : 0].s_addr; 6041ae349f5Scvs2svn if (dnsstuff.s_addr != ms_info_req.s_addr) { 6051ae349f5Scvs2svn 6061ae349f5Scvs2svn /* 6071ae349f5Scvs2svn * So the client has got the DNS stuff wrong (first request) so 6081ae349f5Scvs2svn * we'll tell 'em how it is 6091ae349f5Scvs2svn */ 6101ae349f5Scvs2svn memcpy(nakp, cp, 2); /* copy first two (type/length) */ 6111ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NS req %d:%s->%s - nak\n", 6121ae349f5Scvs2svn type, 6131ae349f5Scvs2svn inet_ntoa(dnsstuff), 6141ae349f5Scvs2svn inet_ntoa(ms_info_req)); 6151ae349f5Scvs2svn memcpy(nakp+2, &ms_info_req, length); 6161ae349f5Scvs2svn nakp += length; 6171ae349f5Scvs2svn break; 6181ae349f5Scvs2svn } 6191ae349f5Scvs2svn 6201ae349f5Scvs2svn /* 6211ae349f5Scvs2svn * Otherwise they have it right (this time) so we send a ack packet 6221ae349f5Scvs2svn * back confirming it... end of story 6231ae349f5Scvs2svn */ 6241ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NS req %d:%s ok - ack\n", 6251ae349f5Scvs2svn type, 6261ae349f5Scvs2svn inet_ntoa(ms_info_req)); 6271ae349f5Scvs2svn memcpy(ackp, cp, length); 6281ae349f5Scvs2svn ackp += length; 6291ae349f5Scvs2svn break; 6301ae349f5Scvs2svn case MODE_NAK: /* what does this mean?? */ 6311ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NS req %d - NAK??\n", type); 6321ae349f5Scvs2svn break; 6331ae349f5Scvs2svn case MODE_REJ: /* confused?? me to :) */ 6341ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NS req %d - REJ??\n", type); 6351ae349f5Scvs2svn break; 6361ae349f5Scvs2svn } 6371ae349f5Scvs2svn break; 6381ae349f5Scvs2svn 6391ae349f5Scvs2svn case TY_PRIMARY_NBNS: /* MS PPP NetBIOS nameserver hack */ 6401ae349f5Scvs2svn case TY_SECONDARY_NBNS: 6411ae349f5Scvs2svn if (!Enabled(ConfMSExt)) { 6421ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NBNS req - rejected - msext disabled\n"); 64383d1af55SBrian Somers ipcp->my_reject |= (1 << type); 6441ae349f5Scvs2svn memcpy(rejp, cp, length); 6451ae349f5Scvs2svn rejp += length; 6461ae349f5Scvs2svn break; 6471ae349f5Scvs2svn } 6481ae349f5Scvs2svn switch (mode_type) { 6491ae349f5Scvs2svn case MODE_REQ: 6501ae349f5Scvs2svn lp = (u_long *) (cp + 2); 6511ae349f5Scvs2svn dnsstuff.s_addr = *lp; 65283d1af55SBrian Somers ms_info_req.s_addr = ipcp->nbns_entries 65329e275ceSBrian Somers [(type - TY_PRIMARY_NBNS) ? 1 : 0].s_addr; 6541ae349f5Scvs2svn if (dnsstuff.s_addr != ms_info_req.s_addr) { 6551ae349f5Scvs2svn memcpy(nakp, cp, 2); 6561ae349f5Scvs2svn memcpy(nakp+2, &ms_info_req.s_addr, length); 6571ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NBNS req %d:%s->%s - nak\n", 6581ae349f5Scvs2svn type, 6591ae349f5Scvs2svn inet_ntoa(dnsstuff), 6601ae349f5Scvs2svn inet_ntoa(ms_info_req)); 6611ae349f5Scvs2svn nakp += length; 6621ae349f5Scvs2svn break; 6631ae349f5Scvs2svn } 6641ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NBNS req %d:%s ok - ack\n", 6651ae349f5Scvs2svn type, 6661ae349f5Scvs2svn inet_ntoa(ms_info_req)); 6671ae349f5Scvs2svn memcpy(ackp, cp, length); 6681ae349f5Scvs2svn ackp += length; 6691ae349f5Scvs2svn break; 6701ae349f5Scvs2svn case MODE_NAK: 6711ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NBNS req %d - NAK??\n", type); 6721ae349f5Scvs2svn break; 6731ae349f5Scvs2svn case MODE_REJ: 6741ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NBNS req %d - REJ??\n", type); 6751ae349f5Scvs2svn break; 6761ae349f5Scvs2svn } 6771ae349f5Scvs2svn break; 6781ae349f5Scvs2svn 6791ae349f5Scvs2svn #endif 6801ae349f5Scvs2svn 6811ae349f5Scvs2svn default: 68283d1af55SBrian Somers ipcp->my_reject |= (1 << type); 6831ae349f5Scvs2svn memcpy(rejp, cp, length); 6841ae349f5Scvs2svn rejp += length; 6851ae349f5Scvs2svn break; 6861ae349f5Scvs2svn } 6871ae349f5Scvs2svn plen -= length; 6881ae349f5Scvs2svn cp += length; 6891ae349f5Scvs2svn } 6901ae349f5Scvs2svn } 6911ae349f5Scvs2svn 6921ae349f5Scvs2svn void 6931ae349f5Scvs2svn IpcpInput(struct mbuf * bp) 6941ae349f5Scvs2svn { 6957308ec68SBrian Somers /* Got PROTO_IPCP from link */ 6967308ec68SBrian Somers FsmInput(&IpcpInfo.fsm, bp); 6971ae349f5Scvs2svn } 6981ae349f5Scvs2svn 6991ae349f5Scvs2svn int 7007a6f8720SBrian Somers UseHisaddr(struct bundle *bundle, const char *hisaddr, int setaddr) 7011ae349f5Scvs2svn { 7027308ec68SBrian Somers /* Use `hisaddr' for the peers address (set iface if `setaddr') */ 70329e275ceSBrian Somers memset(&IpcpInfo.DefHisAddress, '\0', sizeof IpcpInfo.DefHisAddress); 70429e275ceSBrian Somers iplist_reset(&IpcpInfo.DefHisChoice); 7051ae349f5Scvs2svn if (strpbrk(hisaddr, ",-")) { 70629e275ceSBrian Somers iplist_setsrc(&IpcpInfo.DefHisChoice, hisaddr); 70729e275ceSBrian Somers if (iplist_isvalid(&IpcpInfo.DefHisChoice)) { 70829e275ceSBrian Somers iplist_setrandpos(&IpcpInfo.DefHisChoice); 7097a6f8720SBrian Somers IpcpInfo.his_ipaddr = ChooseHisAddr(bundle, IpcpInfo.want_ipaddr); 7101ae349f5Scvs2svn if (IpcpInfo.his_ipaddr.s_addr == INADDR_ANY) { 71129e275ceSBrian Somers LogPrintf(LogWARN, "%s: None available !\n", IpcpInfo.DefHisChoice.src); 7121ae349f5Scvs2svn return(0); 7131ae349f5Scvs2svn } 71429e275ceSBrian Somers IpcpInfo.DefHisAddress.ipaddr.s_addr = IpcpInfo.his_ipaddr.s_addr; 71529e275ceSBrian Somers IpcpInfo.DefHisAddress.mask.s_addr = INADDR_BROADCAST; 71629e275ceSBrian Somers IpcpInfo.DefHisAddress.width = 32; 7171ae349f5Scvs2svn } else { 7181ae349f5Scvs2svn LogPrintf(LogWARN, "%s: Invalid range !\n", hisaddr); 7191ae349f5Scvs2svn return 0; 7201ae349f5Scvs2svn } 72129e275ceSBrian Somers } else if (ParseAddr(1, &hisaddr, &IpcpInfo.DefHisAddress.ipaddr, 72229e275ceSBrian Somers &IpcpInfo.DefHisAddress.mask, 72329e275ceSBrian Somers &IpcpInfo.DefHisAddress.width) != 0) { 72429e275ceSBrian Somers IpcpInfo.his_ipaddr.s_addr = IpcpInfo.DefHisAddress.ipaddr.s_addr; 7251ae349f5Scvs2svn 7267a6f8720SBrian Somers if (setaddr && bundle_SetIPaddress(bundle, IpcpInfo.DefMyAddress.ipaddr, 7277a6f8720SBrian Somers IpcpInfo.DefHisAddress.ipaddr) < 0) { 72829e275ceSBrian Somers IpcpInfo.DefMyAddress.ipaddr.s_addr = INADDR_ANY; 72929e275ceSBrian Somers IpcpInfo.DefHisAddress.ipaddr.s_addr = INADDR_ANY; 7301ae349f5Scvs2svn return 0; 7311ae349f5Scvs2svn } 7321ae349f5Scvs2svn } else 7331ae349f5Scvs2svn return 0; 7341ae349f5Scvs2svn 7351ae349f5Scvs2svn return 1; 7361ae349f5Scvs2svn } 737