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 * 206140ba11SBrian Somers * $Id: ipcp.c,v 1.50.2.6 1998/02/02 19:32:31 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 *); 787a6f8720SBrian Somers static void IpcpDecodeConfig(struct bundle *, u_char *, int, int); 791ae349f5Scvs2svn 807308ec68SBrian Somers struct ipcpstate IpcpInfo = { 817308ec68SBrian Somers { 821ae349f5Scvs2svn "IPCP", 831ae349f5Scvs2svn PROTO_IPCP, 841ae349f5Scvs2svn IPCP_MAXCODE, 851ae349f5Scvs2svn 0, 861ae349f5Scvs2svn ST_INITIAL, 871ae349f5Scvs2svn 0, 0, 0, 881ae349f5Scvs2svn {0, 0, 0, NULL, NULL, NULL}, /* FSM timer */ 891ae349f5Scvs2svn {0, 0, 0, NULL, NULL, NULL}, /* Open timer */ 901ae349f5Scvs2svn {0, 0, 0, NULL, NULL, NULL}, /* Stopped timer */ 911ae349f5Scvs2svn LogIPCP, 927a6f8720SBrian Somers NULL, /* link */ 937a6f8720SBrian Somers NULL, /* bundle */ 941ae349f5Scvs2svn IpcpLayerUp, 951ae349f5Scvs2svn IpcpLayerDown, 961ae349f5Scvs2svn IpcpLayerStart, 971ae349f5Scvs2svn IpcpLayerFinish, 981ae349f5Scvs2svn IpcpInitRestartCounter, 991ae349f5Scvs2svn IpcpSendConfigReq, 1001ae349f5Scvs2svn IpcpSendTerminateReq, 1011ae349f5Scvs2svn IpcpSendTerminateAck, 1021ae349f5Scvs2svn IpcpDecodeConfig, 1037308ec68SBrian Somers }, 1047308ec68SBrian Somers MAX_VJ_STATES, 1057308ec68SBrian Somers 1 1061ae349f5Scvs2svn }; 1071ae349f5Scvs2svn 1081ae349f5Scvs2svn static const char *cftypes[] = { 1091ae349f5Scvs2svn /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ 1101ae349f5Scvs2svn "???", 1111ae349f5Scvs2svn "IPADDRS", /* 1: IP-Addresses */ /* deprecated */ 1121ae349f5Scvs2svn "COMPPROTO", /* 2: IP-Compression-Protocol */ 1131ae349f5Scvs2svn "IPADDR", /* 3: IP-Address */ 1141ae349f5Scvs2svn }; 1151ae349f5Scvs2svn 1161ae349f5Scvs2svn #define NCFTYPES (sizeof cftypes/sizeof cftypes[0]) 1171ae349f5Scvs2svn 1181ae349f5Scvs2svn static const char *cftypes128[] = { 1191ae349f5Scvs2svn /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ 1201ae349f5Scvs2svn "???", 1211ae349f5Scvs2svn "PRIDNS", /* 129: Primary DNS Server Address */ 1221ae349f5Scvs2svn "PRINBNS", /* 130: Primary NBNS Server Address */ 1231ae349f5Scvs2svn "SECDNS", /* 131: Secondary DNS Server Address */ 1241ae349f5Scvs2svn "SECNBNS", /* 132: Secondary NBNS Server Address */ 1251ae349f5Scvs2svn }; 1261ae349f5Scvs2svn 1271ae349f5Scvs2svn #define NCFTYPES128 (sizeof cftypes128/sizeof cftypes128[0]) 1281ae349f5Scvs2svn 1291ae349f5Scvs2svn void 1301ae349f5Scvs2svn IpcpAddInOctets(int n) 1311ae349f5Scvs2svn { 13229e275ceSBrian Somers throughput_addin(&IpcpInfo.throughput, n); 1331ae349f5Scvs2svn } 1341ae349f5Scvs2svn 1351ae349f5Scvs2svn void 1361ae349f5Scvs2svn IpcpAddOutOctets(int n) 1371ae349f5Scvs2svn { 13829e275ceSBrian Somers throughput_addout(&IpcpInfo.throughput, n); 1391ae349f5Scvs2svn } 1401ae349f5Scvs2svn 1411ae349f5Scvs2svn int 1421ae349f5Scvs2svn ReportIpcpStatus(struct cmdargs const *arg) 1431ae349f5Scvs2svn { 1441ae349f5Scvs2svn if (!VarTerm) 1451ae349f5Scvs2svn return 1; 1467308ec68SBrian Somers fprintf(VarTerm, "%s [%s]\n", IpcpInfo.fsm.name, 1477308ec68SBrian Somers StateNames[IpcpInfo.fsm.state]); 1487308ec68SBrian Somers if (IpcpInfo.fsm.state == ST_OPENED) { 14942e91bc7SBrian Somers fprintf(VarTerm, " His side: %s, %s\n", 1501ae349f5Scvs2svn inet_ntoa(IpcpInfo.his_ipaddr), vj2asc(IpcpInfo.his_compproto)); 15142e91bc7SBrian Somers fprintf(VarTerm, " My side: %s, %s\n", 1521ae349f5Scvs2svn inet_ntoa(IpcpInfo.want_ipaddr), vj2asc(IpcpInfo.want_compproto)); 1531ae349f5Scvs2svn } 1541ae349f5Scvs2svn 15542e91bc7SBrian Somers fprintf(VarTerm, "\nDefaults:\n"); 1561ae349f5Scvs2svn fprintf(VarTerm, " My Address: %s/%d\n", 15729e275ceSBrian Somers inet_ntoa(IpcpInfo.DefMyAddress.ipaddr), IpcpInfo.DefMyAddress.width); 15829e275ceSBrian Somers if (iplist_isvalid(&IpcpInfo.DefHisChoice)) 15942e91bc7SBrian Somers fprintf(VarTerm, " His Address: %s\n", 16042e91bc7SBrian Somers IpcpInfo.DefHisChoice.src); 1611ae349f5Scvs2svn else 1621ae349f5Scvs2svn fprintf(VarTerm, " His Address: %s/%d\n", 16329e275ceSBrian Somers inet_ntoa(IpcpInfo.DefHisAddress.ipaddr), 16429e275ceSBrian Somers IpcpInfo.DefHisAddress.width); 16529e275ceSBrian Somers if (IpcpInfo.HaveTriggerAddress) 16629e275ceSBrian Somers fprintf(VarTerm, " Negotiation(trigger): %s\n", 16729e275ceSBrian Somers inet_ntoa(IpcpInfo.TriggerAddress)); 1681ae349f5Scvs2svn else 1691ae349f5Scvs2svn fprintf(VarTerm, " Negotiation(trigger): MYADDR\n"); 17042e91bc7SBrian Somers fprintf(VarTerm, " Initial VJ slots: %d\n", IpcpInfo.VJInitSlots); 17142e91bc7SBrian Somers fprintf(VarTerm, " Initial VJ compression: %s\n", 17242e91bc7SBrian Somers IpcpInfo.VJInitComp ? "on" : "off"); 1731ae349f5Scvs2svn 1741ae349f5Scvs2svn fprintf(VarTerm, "\n"); 17529e275ceSBrian Somers throughput_disp(&IpcpInfo.throughput, VarTerm); 1761ae349f5Scvs2svn 1771ae349f5Scvs2svn return 0; 1781ae349f5Scvs2svn } 1791ae349f5Scvs2svn 1801ae349f5Scvs2svn void 1811ae349f5Scvs2svn IpcpDefAddress() 1821ae349f5Scvs2svn { 1837308ec68SBrian Somers /* Setup default IP addresses (`hostname` -> 0.0.0.0) */ 1841ae349f5Scvs2svn struct hostent *hp; 1851ae349f5Scvs2svn char name[200]; 1861ae349f5Scvs2svn 18729e275ceSBrian Somers memset(&IpcpInfo.DefMyAddress, '\0', sizeof IpcpInfo.DefMyAddress); 18829e275ceSBrian Somers memset(&IpcpInfo.DefHisAddress, '\0', sizeof IpcpInfo.DefHisAddress); 18929e275ceSBrian Somers IpcpInfo.HaveTriggerAddress = 0; 1901ae349f5Scvs2svn if (gethostname(name, sizeof name) == 0) { 1911ae349f5Scvs2svn hp = gethostbyname(name); 19229e275ceSBrian Somers if (hp && hp->h_addrtype == AF_INET) 19329e275ceSBrian Somers memcpy(&IpcpInfo.DefMyAddress.ipaddr.s_addr, hp->h_addr, hp->h_length); 1941ae349f5Scvs2svn } 1951ae349f5Scvs2svn } 1961ae349f5Scvs2svn 1971ae349f5Scvs2svn int 1981ae349f5Scvs2svn SetInitVJ(struct cmdargs const *args) 1991ae349f5Scvs2svn { 2001ae349f5Scvs2svn if (args->argc != 2) 2011ae349f5Scvs2svn return -1; 2021ae349f5Scvs2svn if (!strcasecmp(args->argv[0], "slots")) { 2031ae349f5Scvs2svn int slots; 2041ae349f5Scvs2svn 2051ae349f5Scvs2svn slots = atoi(args->argv[1]); 2061ae349f5Scvs2svn if (slots < 4 || slots > 16) 2071ae349f5Scvs2svn return 1; 20829e275ceSBrian Somers IpcpInfo.VJInitSlots = slots; 2091ae349f5Scvs2svn return 0; 2101ae349f5Scvs2svn } else if (!strcasecmp(args->argv[0], "slotcomp")) { 2111ae349f5Scvs2svn if (!strcasecmp(args->argv[1], "on")) 21229e275ceSBrian Somers IpcpInfo.VJInitComp = 1; 2131ae349f5Scvs2svn else if (!strcasecmp(args->argv[1], "off")) 21429e275ceSBrian Somers IpcpInfo.VJInitComp = 0; 2151ae349f5Scvs2svn else 2161ae349f5Scvs2svn return 2; 2171ae349f5Scvs2svn return 0; 2181ae349f5Scvs2svn } 2191ae349f5Scvs2svn return -1; 2201ae349f5Scvs2svn } 2211ae349f5Scvs2svn 2221ae349f5Scvs2svn void 2237a6f8720SBrian Somers IpcpInit(struct bundle *bundle, struct link *l) 2241ae349f5Scvs2svn { 2257308ec68SBrian Somers /* Initialise ourselves */ 2267a6f8720SBrian Somers FsmInit(&IpcpInfo.fsm, bundle, l); 22729e275ceSBrian Somers if (iplist_isvalid(&IpcpInfo.DefHisChoice)) 22829e275ceSBrian Somers iplist_setrandpos(&IpcpInfo.DefHisChoice); 22929e275ceSBrian Somers IpcpInfo.his_compproto = 0; 23029e275ceSBrian Somers IpcpInfo.his_reject = IpcpInfo.my_reject = 0; 23129e275ceSBrian Somers 2321ae349f5Scvs2svn if ((mode & MODE_DEDICATED) && !GetLabel()) { 23329e275ceSBrian Somers IpcpInfo.want_ipaddr.s_addr = IpcpInfo.his_ipaddr.s_addr = INADDR_ANY; 23429e275ceSBrian Somers IpcpInfo.his_ipaddr.s_addr = INADDR_ANY; 2351ae349f5Scvs2svn } else { 23629e275ceSBrian Somers IpcpInfo.want_ipaddr.s_addr = IpcpInfo.DefMyAddress.ipaddr.s_addr; 23729e275ceSBrian Somers IpcpInfo.his_ipaddr.s_addr = IpcpInfo.DefHisAddress.ipaddr.s_addr; 2381ae349f5Scvs2svn } 2391ae349f5Scvs2svn 2401ae349f5Scvs2svn /* 2411ae349f5Scvs2svn * Some implementations of PPP require that we send a 2421ae349f5Scvs2svn * *special* value as our address, even though the rfc specifies 2431ae349f5Scvs2svn * full negotiation (e.g. "0.0.0.0" or Not "0.0.0.0"). 2441ae349f5Scvs2svn */ 24529e275ceSBrian Somers if (IpcpInfo.HaveTriggerAddress) { 24629e275ceSBrian Somers IpcpInfo.want_ipaddr.s_addr = IpcpInfo.TriggerAddress.s_addr; 24729e275ceSBrian Somers LogPrintf(LogIPCP, "Using trigger address %s\n", 24829e275ceSBrian Somers inet_ntoa(IpcpInfo.TriggerAddress)); 2491ae349f5Scvs2svn } 25029e275ceSBrian Somers 2511ae349f5Scvs2svn if (Enabled(ConfVjcomp)) 25229e275ceSBrian Somers IpcpInfo.want_compproto = (PROTO_VJCOMP << 16) + 25329e275ceSBrian Somers ((IpcpInfo.VJInitSlots - 1) << 8) + 25429e275ceSBrian Somers IpcpInfo.VJInitComp; 2551ae349f5Scvs2svn else 2561ae349f5Scvs2svn IpcpInfo.want_compproto = 0; 2576140ba11SBrian Somers VjInit(IpcpInfo.VJInitSlots - 1); 25829e275ceSBrian Somers 2591ae349f5Scvs2svn IpcpInfo.heis1172 = 0; 2607308ec68SBrian Somers IpcpInfo.fsm.maxconfig = 10; 26129e275ceSBrian Somers throughput_init(&IpcpInfo.throughput); 2621ae349f5Scvs2svn } 2631ae349f5Scvs2svn 2641ae349f5Scvs2svn static void 2651ae349f5Scvs2svn IpcpInitRestartCounter(struct fsm * fp) 2661ae349f5Scvs2svn { 2677308ec68SBrian Somers /* Set fsm timer load */ 2681ae349f5Scvs2svn fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 2691ae349f5Scvs2svn fp->restart = 5; 2701ae349f5Scvs2svn } 2711ae349f5Scvs2svn 2721ae349f5Scvs2svn static void 2731ae349f5Scvs2svn IpcpSendConfigReq(struct fsm *fp) 2741ae349f5Scvs2svn { 2757308ec68SBrian Somers /* Send config REQ please */ 2768c07a7b2SBrian Somers struct physical *p = link2physical(fp->link); 2771ae349f5Scvs2svn u_char *cp; 2781ae349f5Scvs2svn struct lcp_opt o; 2791ae349f5Scvs2svn 2801ae349f5Scvs2svn cp = ReqBuff; 2811ae349f5Scvs2svn LogPrintf(LogIPCP, "IpcpSendConfigReq\n"); 2828c07a7b2SBrian Somers if ((p && !Physical_IsSync(p)) || !REJECTED(&IpcpInfo, TY_IPADDR)) { 2831ae349f5Scvs2svn o.id = TY_IPADDR; 2841ae349f5Scvs2svn o.len = 6; 2851ae349f5Scvs2svn *(u_long *)o.data = IpcpInfo.want_ipaddr.s_addr; 2861ae349f5Scvs2svn cp += LcpPutConf(LogIPCP, cp, &o, cftypes[o.id], 2871ae349f5Scvs2svn inet_ntoa(IpcpInfo.want_ipaddr)); 2881ae349f5Scvs2svn } 2891ae349f5Scvs2svn 2901ae349f5Scvs2svn if (IpcpInfo.want_compproto && !REJECTED(&IpcpInfo, TY_COMPPROTO)) { 2911ae349f5Scvs2svn const char *args; 2921ae349f5Scvs2svn o.id = TY_COMPPROTO; 2931ae349f5Scvs2svn if (IpcpInfo.heis1172) { 2941ae349f5Scvs2svn o.len = 4; 2951ae349f5Scvs2svn *(u_short *)o.data = htons(PROTO_VJCOMP); 2961ae349f5Scvs2svn args = ""; 2971ae349f5Scvs2svn } else { 2981ae349f5Scvs2svn o.len = 6; 2991ae349f5Scvs2svn *(u_long *)o.data = htonl(IpcpInfo.want_compproto); 3001ae349f5Scvs2svn args = vj2asc(IpcpInfo.want_compproto); 3011ae349f5Scvs2svn } 3021ae349f5Scvs2svn cp += LcpPutConf(LogIPCP, cp, &o, cftypes[o.id], args); 3031ae349f5Scvs2svn } 3041ae349f5Scvs2svn FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 3051ae349f5Scvs2svn } 3061ae349f5Scvs2svn 3071ae349f5Scvs2svn static void 3081ae349f5Scvs2svn IpcpSendTerminateReq(struct fsm * fp) 3091ae349f5Scvs2svn { 3107308ec68SBrian Somers /* Term REQ just sent by FSM */ 3111ae349f5Scvs2svn } 3121ae349f5Scvs2svn 3131ae349f5Scvs2svn static void 3141ae349f5Scvs2svn IpcpSendTerminateAck(struct fsm * fp) 3151ae349f5Scvs2svn { 3167308ec68SBrian Somers /* Send Term ACK please */ 3171ae349f5Scvs2svn LogPrintf(LogIPCP, "IpcpSendTerminateAck\n"); 3181ae349f5Scvs2svn FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 3191ae349f5Scvs2svn } 3201ae349f5Scvs2svn 3211ae349f5Scvs2svn static void 3221ae349f5Scvs2svn IpcpLayerStart(struct fsm * fp) 3231ae349f5Scvs2svn { 3247308ec68SBrian Somers /* We're about to start up ! */ 3251ae349f5Scvs2svn LogPrintf(LogIPCP, "IpcpLayerStart.\n"); 3261ae349f5Scvs2svn } 3271ae349f5Scvs2svn 3281ae349f5Scvs2svn static void 3291ae349f5Scvs2svn IpcpLayerFinish(struct fsm * fp) 3301ae349f5Scvs2svn { 3317308ec68SBrian Somers /* We're now down */ 3321ae349f5Scvs2svn LogPrintf(LogIPCP, "IpcpLayerFinish.\n"); 3337308ec68SBrian Somers /* Better tell LCP that it's all over (we're the only NCP) */ 3341ae349f5Scvs2svn reconnect(RECON_FALSE); 3357308ec68SBrian Somers LcpClose(&LcpInfo.fsm); 3361ae349f5Scvs2svn } 3371ae349f5Scvs2svn 3381ae349f5Scvs2svn static void 3391ae349f5Scvs2svn IpcpLayerDown(struct fsm * fp) 3401ae349f5Scvs2svn { 3417308ec68SBrian Somers /* About to come down */ 3421ae349f5Scvs2svn LogPrintf(LogIPCP, "IpcpLayerDown.\n"); 34329e275ceSBrian Somers throughput_stop(&IpcpInfo.throughput); 34429e275ceSBrian Somers throughput_log(&IpcpInfo.throughput, LogIPCP, NULL); 3451ae349f5Scvs2svn } 3461ae349f5Scvs2svn 3471ae349f5Scvs2svn static void 3481ae349f5Scvs2svn IpcpLayerUp(struct fsm *fp) 3491ae349f5Scvs2svn { 3507308ec68SBrian Somers /* We're now up */ 3511ae349f5Scvs2svn char tbuff[100]; 3521ae349f5Scvs2svn 3531ae349f5Scvs2svn Prompt(); 3541ae349f5Scvs2svn LogPrintf(LogIPCP, "IpcpLayerUp(%d).\n", fp->state); 3551ae349f5Scvs2svn snprintf(tbuff, sizeof tbuff, "myaddr = %s ", 3561ae349f5Scvs2svn inet_ntoa(IpcpInfo.want_ipaddr)); 3571ae349f5Scvs2svn 3581ae349f5Scvs2svn if (IpcpInfo.his_compproto >> 16 == PROTO_VJCOMP) 3591ae349f5Scvs2svn VjInit((IpcpInfo.his_compproto >> 8) & 255); 3601ae349f5Scvs2svn 3611ae349f5Scvs2svn LogPrintf(LogIsKept(LogIPCP) ? LogIPCP : LogLINK, " %s hisaddr = %s\n", 3621ae349f5Scvs2svn tbuff, inet_ntoa(IpcpInfo.his_ipaddr)); 3637a6f8720SBrian Somers if (bundle_SetIPaddress(fp->bundle, IpcpInfo.want_ipaddr, 3647a6f8720SBrian Somers IpcpInfo.his_ipaddr) < 0) { 3651ae349f5Scvs2svn if (VarTerm) 3661ae349f5Scvs2svn LogPrintf(LogERROR, "IpcpLayerUp: unable to set ip address\n"); 3671ae349f5Scvs2svn return; 3681ae349f5Scvs2svn } 3691ae349f5Scvs2svn #ifndef NOALIAS 3701ae349f5Scvs2svn if (mode & MODE_ALIAS) 3711ae349f5Scvs2svn VarPacketAliasSetAddress(IpcpInfo.want_ipaddr); 3721ae349f5Scvs2svn #endif 3737a6f8720SBrian Somers bundle_Linkup(fp->bundle); 37429e275ceSBrian Somers throughput_start(&IpcpInfo.throughput); 3751ae349f5Scvs2svn StartIdleTimer(); 3761ae349f5Scvs2svn } 3771ae349f5Scvs2svn 3781ae349f5Scvs2svn void 3791ae349f5Scvs2svn IpcpUp() 3801ae349f5Scvs2svn { 3817308ec68SBrian Somers /* Lower layers are ready.... go */ 3827308ec68SBrian Somers FsmUp(&IpcpInfo.fsm); 3831ae349f5Scvs2svn LogPrintf(LogIPCP, "IPCP Up event!!\n"); 3841ae349f5Scvs2svn } 3851ae349f5Scvs2svn 3861ae349f5Scvs2svn void 3877308ec68SBrian Somers IpcpDown() 3887308ec68SBrian Somers { 3897308ec68SBrian Somers /* Physical link is gone - sudden death */ 3907308ec68SBrian Somers if (IpcpInfo.fsm.state >= ST_CLOSED) { 3917308ec68SBrian Somers FsmDown(&IpcpInfo.fsm); 3927308ec68SBrian Somers /* FsmDown() results in an IpcpLayerDown() if we're currently open. */ 3937308ec68SBrian Somers IpcpLayerFinish(&IpcpInfo.fsm); 3947308ec68SBrian Somers } 3957308ec68SBrian Somers } 3967308ec68SBrian Somers 3977308ec68SBrian Somers void 3981ae349f5Scvs2svn IpcpOpen() 3991ae349f5Scvs2svn { 4007308ec68SBrian Somers /* Start IPCP please */ 4017308ec68SBrian Somers FsmOpen(&IpcpInfo.fsm); 4021ae349f5Scvs2svn } 4031ae349f5Scvs2svn 4041ae349f5Scvs2svn static int 4051ae349f5Scvs2svn AcceptableAddr(struct in_range *prange, struct in_addr ipaddr) 4061ae349f5Scvs2svn { 4077308ec68SBrian Somers /* Is the given IP in the given range ? */ 4081ae349f5Scvs2svn LogPrintf(LogDEBUG, "requested = %x\n", htonl(ipaddr.s_addr)); 4091ae349f5Scvs2svn LogPrintf(LogDEBUG, "range = %x\n", htonl(prange->ipaddr.s_addr)); 4101ae349f5Scvs2svn LogPrintf(LogDEBUG, "/%x\n", htonl(prange->mask.s_addr)); 4111ae349f5Scvs2svn LogPrintf(LogDEBUG, "%x, %x\n", htonl(prange->ipaddr.s_addr & prange-> 4121ae349f5Scvs2svn mask.s_addr), htonl(ipaddr.s_addr & prange->mask.s_addr)); 4131ae349f5Scvs2svn return (prange->ipaddr.s_addr & prange->mask.s_addr) == 4141ae349f5Scvs2svn (ipaddr.s_addr & prange->mask.s_addr) && ipaddr.s_addr; 4151ae349f5Scvs2svn } 4161ae349f5Scvs2svn 4171ae349f5Scvs2svn static void 4187a6f8720SBrian Somers IpcpDecodeConfig(struct bundle *bundle, u_char * cp, int plen, int mode_type) 4191ae349f5Scvs2svn { 4207308ec68SBrian Somers /* Deal with incoming PROTO_IPCP */ 4211ae349f5Scvs2svn int type, length; 4221ae349f5Scvs2svn u_long *lp, compproto; 4231ae349f5Scvs2svn struct compreq *pcomp; 4241ae349f5Scvs2svn struct in_addr ipaddr, dstipaddr, dnsstuff, ms_info_req; 4251ae349f5Scvs2svn char tbuff[100]; 4261ae349f5Scvs2svn char tbuff2[100]; 4271ae349f5Scvs2svn 4281ae349f5Scvs2svn ackp = AckBuff; 4291ae349f5Scvs2svn nakp = NakBuff; 4301ae349f5Scvs2svn rejp = RejBuff; 4311ae349f5Scvs2svn 4321ae349f5Scvs2svn while (plen >= sizeof(struct fsmconfig)) { 4331ae349f5Scvs2svn type = *cp; 4341ae349f5Scvs2svn length = cp[1]; 4351ae349f5Scvs2svn if (type < NCFTYPES) 4361ae349f5Scvs2svn snprintf(tbuff, sizeof tbuff, " %s[%d] ", cftypes[type], length); 4371ae349f5Scvs2svn else if (type > 128 && type < 128 + NCFTYPES128) 4381ae349f5Scvs2svn snprintf(tbuff, sizeof tbuff, " %s[%d] ", cftypes128[type-128], length); 4391ae349f5Scvs2svn else 4401ae349f5Scvs2svn snprintf(tbuff, sizeof tbuff, " <%d>[%d] ", type, length); 4411ae349f5Scvs2svn 4421ae349f5Scvs2svn switch (type) { 4431ae349f5Scvs2svn case TY_IPADDR: /* RFC1332 */ 4441ae349f5Scvs2svn lp = (u_long *) (cp + 2); 4451ae349f5Scvs2svn ipaddr.s_addr = *lp; 4461ae349f5Scvs2svn LogPrintf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 4471ae349f5Scvs2svn 4481ae349f5Scvs2svn switch (mode_type) { 4491ae349f5Scvs2svn case MODE_REQ: 45029e275ceSBrian Somers if (iplist_isvalid(&IpcpInfo.DefHisChoice)) { 4511ae349f5Scvs2svn if (ipaddr.s_addr == INADDR_ANY || 45229e275ceSBrian Somers iplist_ip2pos(&IpcpInfo.DefHisChoice, ipaddr) < 0 || 4537a6f8720SBrian Somers bundle_TrySetIPaddress(bundle, IpcpInfo.DefMyAddress.ipaddr, 4547a6f8720SBrian Somers ipaddr)) { 4551ae349f5Scvs2svn LogPrintf(LogIPCP, "%s: Address invalid or already in use\n", 4561ae349f5Scvs2svn inet_ntoa(ipaddr)); 4577a6f8720SBrian Somers IpcpInfo.his_ipaddr = ChooseHisAddr 4587a6f8720SBrian Somers (bundle, IpcpInfo.DefMyAddress.ipaddr); 4591ae349f5Scvs2svn if (IpcpInfo.his_ipaddr.s_addr == INADDR_ANY) { 4601ae349f5Scvs2svn memcpy(rejp, cp, length); 4611ae349f5Scvs2svn rejp += length; 4621ae349f5Scvs2svn } else { 4631ae349f5Scvs2svn memcpy(nakp, cp, 2); 4641ae349f5Scvs2svn memcpy(nakp+2, &IpcpInfo.his_ipaddr.s_addr, length - 2); 4651ae349f5Scvs2svn nakp += length; 4661ae349f5Scvs2svn } 4671ae349f5Scvs2svn break; 4681ae349f5Scvs2svn } 46929e275ceSBrian Somers } else if (!AcceptableAddr(&IpcpInfo.DefHisAddress, ipaddr)) { 4701ae349f5Scvs2svn /* 4711ae349f5Scvs2svn * If destination address is not acceptable, insist to use what we 4721ae349f5Scvs2svn * want to use. 4731ae349f5Scvs2svn */ 4741ae349f5Scvs2svn memcpy(nakp, cp, 2); 4751ae349f5Scvs2svn memcpy(nakp+2, &IpcpInfo.his_ipaddr.s_addr, length - 2); 4761ae349f5Scvs2svn nakp += length; 4771ae349f5Scvs2svn break; 4781ae349f5Scvs2svn } 4791ae349f5Scvs2svn IpcpInfo.his_ipaddr = ipaddr; 4801ae349f5Scvs2svn memcpy(ackp, cp, length); 4811ae349f5Scvs2svn ackp += length; 4821ae349f5Scvs2svn break; 4831ae349f5Scvs2svn case MODE_NAK: 48429e275ceSBrian Somers if (AcceptableAddr(&IpcpInfo.DefMyAddress, ipaddr)) { 4851ae349f5Scvs2svn /* Use address suggested by peer */ 4861ae349f5Scvs2svn snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s ", tbuff, 4871ae349f5Scvs2svn inet_ntoa(IpcpInfo.want_ipaddr)); 4881ae349f5Scvs2svn LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 4891ae349f5Scvs2svn IpcpInfo.want_ipaddr = ipaddr; 4901ae349f5Scvs2svn } else { 4911ae349f5Scvs2svn LogPrintf(LogIPCP, "%s: Unacceptable address!\n", inet_ntoa(ipaddr)); 4927308ec68SBrian Somers FsmClose(&IpcpInfo.fsm); 4931ae349f5Scvs2svn } 4941ae349f5Scvs2svn break; 4951ae349f5Scvs2svn case MODE_REJ: 4961ae349f5Scvs2svn IpcpInfo.his_reject |= (1 << type); 4971ae349f5Scvs2svn break; 4981ae349f5Scvs2svn } 4991ae349f5Scvs2svn break; 5001ae349f5Scvs2svn case TY_COMPPROTO: 5011ae349f5Scvs2svn lp = (u_long *) (cp + 2); 5021ae349f5Scvs2svn compproto = htonl(*lp); 5031ae349f5Scvs2svn LogPrintf(LogIPCP, "%s %s\n", tbuff, vj2asc(compproto)); 5041ae349f5Scvs2svn 5051ae349f5Scvs2svn switch (mode_type) { 5061ae349f5Scvs2svn case MODE_REQ: 5071ae349f5Scvs2svn if (!Acceptable(ConfVjcomp)) { 5081ae349f5Scvs2svn memcpy(rejp, cp, length); 5091ae349f5Scvs2svn rejp += length; 5101ae349f5Scvs2svn } else { 5111ae349f5Scvs2svn pcomp = (struct compreq *) (cp + 2); 5121ae349f5Scvs2svn switch (length) { 5131ae349f5Scvs2svn case 4: /* RFC1172 */ 5141ae349f5Scvs2svn if (ntohs(pcomp->proto) == PROTO_VJCOMP) { 5151ae349f5Scvs2svn LogPrintf(LogWARN, "Peer is speaking RFC1172 compression protocol !\n"); 5161ae349f5Scvs2svn IpcpInfo.heis1172 = 1; 5171ae349f5Scvs2svn IpcpInfo.his_compproto = compproto; 5181ae349f5Scvs2svn memcpy(ackp, cp, length); 5191ae349f5Scvs2svn ackp += length; 5201ae349f5Scvs2svn } else { 5211ae349f5Scvs2svn memcpy(nakp, cp, 2); 5221ae349f5Scvs2svn pcomp->proto = htons(PROTO_VJCOMP); 5231ae349f5Scvs2svn memcpy(nakp+2, &pcomp, 2); 5241ae349f5Scvs2svn nakp += length; 5251ae349f5Scvs2svn } 5261ae349f5Scvs2svn break; 5271ae349f5Scvs2svn case 6: /* RFC1332 */ 5281ae349f5Scvs2svn if (ntohs(pcomp->proto) == PROTO_VJCOMP 52929e275ceSBrian Somers && pcomp->slots < MAX_VJ_STATES && pcomp->slots > 2) { 5301ae349f5Scvs2svn IpcpInfo.his_compproto = compproto; 5311ae349f5Scvs2svn IpcpInfo.heis1172 = 0; 5321ae349f5Scvs2svn memcpy(ackp, cp, length); 5331ae349f5Scvs2svn ackp += length; 5341ae349f5Scvs2svn } else { 5351ae349f5Scvs2svn memcpy(nakp, cp, 2); 5361ae349f5Scvs2svn pcomp->proto = htons(PROTO_VJCOMP); 53729e275ceSBrian Somers pcomp->slots = MAX_VJ_STATES - 1; 5381ae349f5Scvs2svn pcomp->compcid = 0; 5391ae349f5Scvs2svn memcpy(nakp+2, &pcomp, sizeof pcomp); 5401ae349f5Scvs2svn nakp += length; 5411ae349f5Scvs2svn } 5421ae349f5Scvs2svn break; 5431ae349f5Scvs2svn default: 5441ae349f5Scvs2svn memcpy(rejp, cp, length); 5451ae349f5Scvs2svn rejp += length; 5461ae349f5Scvs2svn break; 5471ae349f5Scvs2svn } 5481ae349f5Scvs2svn } 5491ae349f5Scvs2svn break; 5501ae349f5Scvs2svn case MODE_NAK: 5511ae349f5Scvs2svn LogPrintf(LogIPCP, "%s changing compproto: %08x --> %08x\n", 5521ae349f5Scvs2svn tbuff, IpcpInfo.want_compproto, compproto); 5531ae349f5Scvs2svn IpcpInfo.want_compproto = compproto; 5541ae349f5Scvs2svn break; 5551ae349f5Scvs2svn case MODE_REJ: 5561ae349f5Scvs2svn IpcpInfo.his_reject |= (1 << type); 5571ae349f5Scvs2svn break; 5581ae349f5Scvs2svn } 5591ae349f5Scvs2svn break; 5601ae349f5Scvs2svn case TY_IPADDRS: /* RFC1172 */ 5611ae349f5Scvs2svn lp = (u_long *) (cp + 2); 5621ae349f5Scvs2svn ipaddr.s_addr = *lp; 5631ae349f5Scvs2svn lp = (u_long *) (cp + 6); 5641ae349f5Scvs2svn dstipaddr.s_addr = *lp; 5651ae349f5Scvs2svn snprintf(tbuff2, sizeof tbuff2, "%s %s,", tbuff, inet_ntoa(ipaddr)); 5661ae349f5Scvs2svn LogPrintf(LogIPCP, "%s %s\n", tbuff2, inet_ntoa(dstipaddr)); 5671ae349f5Scvs2svn 5681ae349f5Scvs2svn switch (mode_type) { 5691ae349f5Scvs2svn case MODE_REQ: 5701ae349f5Scvs2svn IpcpInfo.his_ipaddr = ipaddr; 5711ae349f5Scvs2svn IpcpInfo.want_ipaddr = dstipaddr; 5721ae349f5Scvs2svn memcpy(ackp, cp, length); 5731ae349f5Scvs2svn ackp += length; 5741ae349f5Scvs2svn break; 5751ae349f5Scvs2svn case MODE_NAK: 5761ae349f5Scvs2svn snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s", tbuff, 5771ae349f5Scvs2svn inet_ntoa(IpcpInfo.want_ipaddr)); 5781ae349f5Scvs2svn LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 5791ae349f5Scvs2svn IpcpInfo.want_ipaddr = ipaddr; 5801ae349f5Scvs2svn IpcpInfo.his_ipaddr = dstipaddr; 5811ae349f5Scvs2svn break; 5821ae349f5Scvs2svn case MODE_REJ: 5831ae349f5Scvs2svn IpcpInfo.his_reject |= (1 << type); 5841ae349f5Scvs2svn break; 5851ae349f5Scvs2svn } 5861ae349f5Scvs2svn break; 5871ae349f5Scvs2svn 5881ae349f5Scvs2svn /* 5891ae349f5Scvs2svn * MS extensions for MS's PPP 5901ae349f5Scvs2svn */ 5911ae349f5Scvs2svn 5921ae349f5Scvs2svn #ifndef NOMSEXT 5931ae349f5Scvs2svn case TY_PRIMARY_DNS: /* MS PPP DNS negotiation hack */ 5941ae349f5Scvs2svn case TY_SECONDARY_DNS: 5951ae349f5Scvs2svn if (!Enabled(ConfMSExt)) { 5961ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NS req - rejected - msext disabled\n"); 5971ae349f5Scvs2svn IpcpInfo.my_reject |= (1 << type); 5981ae349f5Scvs2svn memcpy(rejp, cp, length); 5991ae349f5Scvs2svn rejp += length; 6001ae349f5Scvs2svn break; 6011ae349f5Scvs2svn } 6021ae349f5Scvs2svn switch (mode_type) { 6031ae349f5Scvs2svn case MODE_REQ: 6041ae349f5Scvs2svn lp = (u_long *) (cp + 2); 6051ae349f5Scvs2svn dnsstuff.s_addr = *lp; 60629e275ceSBrian Somers ms_info_req.s_addr = IpcpInfo.ns_entries 60729e275ceSBrian Somers [(type - TY_PRIMARY_DNS) ? 1 : 0].s_addr; 6081ae349f5Scvs2svn if (dnsstuff.s_addr != ms_info_req.s_addr) { 6091ae349f5Scvs2svn 6101ae349f5Scvs2svn /* 6111ae349f5Scvs2svn * So the client has got the DNS stuff wrong (first request) so 6121ae349f5Scvs2svn * we'll tell 'em how it is 6131ae349f5Scvs2svn */ 6141ae349f5Scvs2svn memcpy(nakp, cp, 2); /* copy first two (type/length) */ 6151ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NS req %d:%s->%s - nak\n", 6161ae349f5Scvs2svn type, 6171ae349f5Scvs2svn inet_ntoa(dnsstuff), 6181ae349f5Scvs2svn inet_ntoa(ms_info_req)); 6191ae349f5Scvs2svn memcpy(nakp+2, &ms_info_req, length); 6201ae349f5Scvs2svn nakp += length; 6211ae349f5Scvs2svn break; 6221ae349f5Scvs2svn } 6231ae349f5Scvs2svn 6241ae349f5Scvs2svn /* 6251ae349f5Scvs2svn * Otherwise they have it right (this time) so we send a ack packet 6261ae349f5Scvs2svn * back confirming it... end of story 6271ae349f5Scvs2svn */ 6281ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NS req %d:%s ok - ack\n", 6291ae349f5Scvs2svn type, 6301ae349f5Scvs2svn inet_ntoa(ms_info_req)); 6311ae349f5Scvs2svn memcpy(ackp, cp, length); 6321ae349f5Scvs2svn ackp += length; 6331ae349f5Scvs2svn break; 6341ae349f5Scvs2svn case MODE_NAK: /* what does this mean?? */ 6351ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NS req %d - NAK??\n", type); 6361ae349f5Scvs2svn break; 6371ae349f5Scvs2svn case MODE_REJ: /* confused?? me to :) */ 6381ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NS req %d - REJ??\n", type); 6391ae349f5Scvs2svn break; 6401ae349f5Scvs2svn } 6411ae349f5Scvs2svn break; 6421ae349f5Scvs2svn 6431ae349f5Scvs2svn case TY_PRIMARY_NBNS: /* MS PPP NetBIOS nameserver hack */ 6441ae349f5Scvs2svn case TY_SECONDARY_NBNS: 6451ae349f5Scvs2svn if (!Enabled(ConfMSExt)) { 6461ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NBNS req - rejected - msext disabled\n"); 6471ae349f5Scvs2svn IpcpInfo.my_reject |= (1 << type); 6481ae349f5Scvs2svn memcpy(rejp, cp, length); 6491ae349f5Scvs2svn rejp += length; 6501ae349f5Scvs2svn break; 6511ae349f5Scvs2svn } 6521ae349f5Scvs2svn switch (mode_type) { 6531ae349f5Scvs2svn case MODE_REQ: 6541ae349f5Scvs2svn lp = (u_long *) (cp + 2); 6551ae349f5Scvs2svn dnsstuff.s_addr = *lp; 65629e275ceSBrian Somers ms_info_req.s_addr = IpcpInfo.nbns_entries 65729e275ceSBrian Somers [(type - TY_PRIMARY_NBNS) ? 1 : 0].s_addr; 6581ae349f5Scvs2svn if (dnsstuff.s_addr != ms_info_req.s_addr) { 6591ae349f5Scvs2svn memcpy(nakp, cp, 2); 6601ae349f5Scvs2svn memcpy(nakp+2, &ms_info_req.s_addr, length); 6611ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NBNS req %d:%s->%s - nak\n", 6621ae349f5Scvs2svn type, 6631ae349f5Scvs2svn inet_ntoa(dnsstuff), 6641ae349f5Scvs2svn inet_ntoa(ms_info_req)); 6651ae349f5Scvs2svn nakp += length; 6661ae349f5Scvs2svn break; 6671ae349f5Scvs2svn } 6681ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NBNS req %d:%s ok - ack\n", 6691ae349f5Scvs2svn type, 6701ae349f5Scvs2svn inet_ntoa(ms_info_req)); 6711ae349f5Scvs2svn memcpy(ackp, cp, length); 6721ae349f5Scvs2svn ackp += length; 6731ae349f5Scvs2svn break; 6741ae349f5Scvs2svn case MODE_NAK: 6751ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NBNS req %d - NAK??\n", type); 6761ae349f5Scvs2svn break; 6771ae349f5Scvs2svn case MODE_REJ: 6781ae349f5Scvs2svn LogPrintf(LogIPCP, "MS NBNS req %d - REJ??\n", type); 6791ae349f5Scvs2svn break; 6801ae349f5Scvs2svn } 6811ae349f5Scvs2svn break; 6821ae349f5Scvs2svn 6831ae349f5Scvs2svn #endif 6841ae349f5Scvs2svn 6851ae349f5Scvs2svn default: 6861ae349f5Scvs2svn IpcpInfo.my_reject |= (1 << type); 6871ae349f5Scvs2svn memcpy(rejp, cp, length); 6881ae349f5Scvs2svn rejp += length; 6891ae349f5Scvs2svn break; 6901ae349f5Scvs2svn } 6911ae349f5Scvs2svn plen -= length; 6921ae349f5Scvs2svn cp += length; 6931ae349f5Scvs2svn } 6941ae349f5Scvs2svn } 6951ae349f5Scvs2svn 6961ae349f5Scvs2svn void 6971ae349f5Scvs2svn IpcpInput(struct mbuf * bp) 6981ae349f5Scvs2svn { 6997308ec68SBrian Somers /* Got PROTO_IPCP from link */ 7007308ec68SBrian Somers FsmInput(&IpcpInfo.fsm, bp); 7011ae349f5Scvs2svn } 7021ae349f5Scvs2svn 7031ae349f5Scvs2svn int 7047a6f8720SBrian Somers UseHisaddr(struct bundle *bundle, const char *hisaddr, int setaddr) 7051ae349f5Scvs2svn { 7067308ec68SBrian Somers /* Use `hisaddr' for the peers address (set iface if `setaddr') */ 70729e275ceSBrian Somers memset(&IpcpInfo.DefHisAddress, '\0', sizeof IpcpInfo.DefHisAddress); 70829e275ceSBrian Somers iplist_reset(&IpcpInfo.DefHisChoice); 7091ae349f5Scvs2svn if (strpbrk(hisaddr, ",-")) { 71029e275ceSBrian Somers iplist_setsrc(&IpcpInfo.DefHisChoice, hisaddr); 71129e275ceSBrian Somers if (iplist_isvalid(&IpcpInfo.DefHisChoice)) { 71229e275ceSBrian Somers iplist_setrandpos(&IpcpInfo.DefHisChoice); 7137a6f8720SBrian Somers IpcpInfo.his_ipaddr = ChooseHisAddr(bundle, IpcpInfo.want_ipaddr); 7141ae349f5Scvs2svn if (IpcpInfo.his_ipaddr.s_addr == INADDR_ANY) { 71529e275ceSBrian Somers LogPrintf(LogWARN, "%s: None available !\n", IpcpInfo.DefHisChoice.src); 7161ae349f5Scvs2svn return(0); 7171ae349f5Scvs2svn } 71829e275ceSBrian Somers IpcpInfo.DefHisAddress.ipaddr.s_addr = IpcpInfo.his_ipaddr.s_addr; 71929e275ceSBrian Somers IpcpInfo.DefHisAddress.mask.s_addr = INADDR_BROADCAST; 72029e275ceSBrian Somers IpcpInfo.DefHisAddress.width = 32; 7211ae349f5Scvs2svn } else { 7221ae349f5Scvs2svn LogPrintf(LogWARN, "%s: Invalid range !\n", hisaddr); 7231ae349f5Scvs2svn return 0; 7241ae349f5Scvs2svn } 72529e275ceSBrian Somers } else if (ParseAddr(1, &hisaddr, &IpcpInfo.DefHisAddress.ipaddr, 72629e275ceSBrian Somers &IpcpInfo.DefHisAddress.mask, 72729e275ceSBrian Somers &IpcpInfo.DefHisAddress.width) != 0) { 72829e275ceSBrian Somers IpcpInfo.his_ipaddr.s_addr = IpcpInfo.DefHisAddress.ipaddr.s_addr; 7291ae349f5Scvs2svn 7307a6f8720SBrian Somers if (setaddr && bundle_SetIPaddress(bundle, IpcpInfo.DefMyAddress.ipaddr, 7317a6f8720SBrian Somers IpcpInfo.DefHisAddress.ipaddr) < 0) { 73229e275ceSBrian Somers IpcpInfo.DefMyAddress.ipaddr.s_addr = INADDR_ANY; 73329e275ceSBrian Somers IpcpInfo.DefHisAddress.ipaddr.s_addr = INADDR_ANY; 7341ae349f5Scvs2svn return 0; 7351ae349f5Scvs2svn } 7361ae349f5Scvs2svn } else 7371ae349f5Scvs2svn return 0; 7381ae349f5Scvs2svn 7391ae349f5Scvs2svn return 1; 7401ae349f5Scvs2svn } 741