1af57ed9fSAtsushi Murai /* 2af57ed9fSAtsushi Murai * PPP IP Control Protocol (IPCP) Module 3af57ed9fSAtsushi Murai * 4af57ed9fSAtsushi Murai * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5af57ed9fSAtsushi Murai * 6af57ed9fSAtsushi Murai * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7af57ed9fSAtsushi Murai * 8af57ed9fSAtsushi Murai * Redistribution and use in source and binary forms are permitted 9af57ed9fSAtsushi Murai * provided that the above copyright notice and this paragraph are 10af57ed9fSAtsushi Murai * duplicated in all such forms and that any documentation, 11af57ed9fSAtsushi Murai * advertising materials, and other materials related to such 12af57ed9fSAtsushi Murai * distribution and use acknowledge that the software was developed 13af57ed9fSAtsushi Murai * by the Internet Initiative Japan, Inc. The name of the 14af57ed9fSAtsushi Murai * IIJ may not be used to endorse or promote products derived 15af57ed9fSAtsushi Murai * from this software without specific prior written permission. 16af57ed9fSAtsushi Murai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17af57ed9fSAtsushi Murai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18af57ed9fSAtsushi Murai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19af57ed9fSAtsushi Murai * 209780ef31SBrian Somers * $Id: ipcp.c,v 1.33 1997/10/29 01:19:40 brian Exp $ 21af57ed9fSAtsushi Murai * 22af57ed9fSAtsushi Murai * TODO: 23af57ed9fSAtsushi Murai * o More RFC1772 backwoard compatibility 24af57ed9fSAtsushi Murai */ 2575240ed1SBrian Somers #include <sys/param.h> 265b4c5b00SBrian Somers #include <netinet/in_systm.h> 275b4c5b00SBrian Somers #include <netinet/in.h> 285b4c5b00SBrian Somers #include <netinet/ip.h> 295b4c5b00SBrian Somers #include <arpa/inet.h> 305b4c5b00SBrian Somers #include <sys/socket.h> 3175240ed1SBrian Somers #include <netdb.h> 3275240ed1SBrian Somers 335b4c5b00SBrian Somers #include <limits.h> 3475240ed1SBrian Somers #include <stdio.h> 3575240ed1SBrian Somers #include <string.h> 3675240ed1SBrian Somers #include <unistd.h> 3775240ed1SBrian Somers 3875240ed1SBrian Somers #include "mbuf.h" 3975240ed1SBrian Somers #include "log.h" 4075240ed1SBrian Somers #include "defs.h" 4175240ed1SBrian Somers #include "timer.h" 42af57ed9fSAtsushi Murai #include "fsm.h" 43af57ed9fSAtsushi Murai #include "lcpproto.h" 44af57ed9fSAtsushi Murai #include "lcp.h" 45af57ed9fSAtsushi Murai #include "ipcp.h" 46af57ed9fSAtsushi Murai #include "slcompress.h" 47af57ed9fSAtsushi Murai #include "os.h" 48af57ed9fSAtsushi Murai #include "phase.h" 496ed9fb2fSBrian Somers #include "loadalias.h" 5075240ed1SBrian Somers #include "command.h" 51af57ed9fSAtsushi Murai #include "vars.h" 5275240ed1SBrian Somers #include "vjcomp.h" 536eaa6ac5SBrian Somers #include "ip.h" 54af57ed9fSAtsushi Murai 55927145beSBrian Somers #ifndef NOMSEXT 5675240ed1SBrian Somers struct in_addr ns_entries[2]; 5775240ed1SBrian Somers struct in_addr nbns_entries[2]; 58927145beSBrian Somers #endif 59d8e55738SJordan K. Hubbard 6075240ed1SBrian Somers struct ipcpstate IpcpInfo; 6175240ed1SBrian Somers struct in_range DefMyAddress; 6275240ed1SBrian Somers struct in_range DefHisAddress; 6375240ed1SBrian Somers struct in_addr TriggerAddress; 6475240ed1SBrian Somers int HaveTriggerAddress; 6575240ed1SBrian Somers struct pppTimer IpcpReportTimer; 6675240ed1SBrian Somers 67927145beSBrian Somers static void IpcpSendConfigReq(struct fsm *); 68927145beSBrian Somers static void IpcpSendTerminateAck(struct fsm *); 69927145beSBrian Somers static void IpcpSendTerminateReq(struct fsm *); 70927145beSBrian Somers static void IpcpDecodeConfig(u_char *, int, int); 71927145beSBrian Somers static void IpcpLayerStart(struct fsm *); 72927145beSBrian Somers static void IpcpLayerFinish(struct fsm *); 73927145beSBrian Somers static void IpcpLayerUp(struct fsm *); 74927145beSBrian Somers static void IpcpLayerDown(struct fsm *); 75927145beSBrian Somers static void IpcpInitRestartCounter(struct fsm *); 7675240ed1SBrian Somers static int IpcpOctetsIn(void); 7775240ed1SBrian Somers static int IpcpOctetsOut(void); 78af57ed9fSAtsushi Murai 79af57ed9fSAtsushi Murai static int lastInOctets, lastOutOctets; 805b4c5b00SBrian Somers static int StartingIpIn, StartingIpOut; 81af57ed9fSAtsushi Murai 82af57ed9fSAtsushi Murai #define REJECTED(p, x) (p->his_reject & (1<<x)) 83af57ed9fSAtsushi Murai 84af57ed9fSAtsushi Murai struct fsm IpcpFsm = { 85af57ed9fSAtsushi Murai "IPCP", 86af57ed9fSAtsushi Murai PROTO_IPCP, 87af57ed9fSAtsushi Murai IPCP_MAXCODE, 88af57ed9fSAtsushi Murai OPEN_ACTIVE, 89af57ed9fSAtsushi Murai ST_INITIAL, 90af57ed9fSAtsushi Murai 0, 0, 0, 91af57ed9fSAtsushi Murai 92af57ed9fSAtsushi Murai 0, 93af57ed9fSAtsushi Murai {0, 0, 0, NULL, NULL, NULL}, 94cb611434SBrian Somers {0, 0, 0, NULL, NULL, NULL}, 95cb611434SBrian Somers LogIPCP, 96af57ed9fSAtsushi Murai 97af57ed9fSAtsushi Murai IpcpLayerUp, 98af57ed9fSAtsushi Murai IpcpLayerDown, 99af57ed9fSAtsushi Murai IpcpLayerStart, 100af57ed9fSAtsushi Murai IpcpLayerFinish, 101af57ed9fSAtsushi Murai IpcpInitRestartCounter, 102af57ed9fSAtsushi Murai IpcpSendConfigReq, 103af57ed9fSAtsushi Murai IpcpSendTerminateReq, 104af57ed9fSAtsushi Murai IpcpSendTerminateAck, 105af57ed9fSAtsushi Murai IpcpDecodeConfig, 106af57ed9fSAtsushi Murai }; 107af57ed9fSAtsushi Murai 108af57ed9fSAtsushi Murai static char *cftypes[] = { 109af57ed9fSAtsushi Murai "???", "IPADDRS", "COMPPROTO", "IPADDR", 110af57ed9fSAtsushi Murai }; 111af57ed9fSAtsushi Murai 112af57ed9fSAtsushi Murai /* 113af57ed9fSAtsushi Murai * Function called every second. Updates connection period and idle period, 114af57ed9fSAtsushi Murai * also update LQR information. 115af57ed9fSAtsushi Murai */ 116af57ed9fSAtsushi Murai static void 117af57ed9fSAtsushi Murai IpcpReportFunc() 118af57ed9fSAtsushi Murai { 119af57ed9fSAtsushi Murai ipConnectSecs++; 120af57ed9fSAtsushi Murai if (lastInOctets == ipInOctets && lastOutOctets == ipOutOctets) 121af57ed9fSAtsushi Murai ipIdleSecs++; 122af57ed9fSAtsushi Murai lastInOctets = ipInOctets; 123af57ed9fSAtsushi Murai lastOutOctets = ipOutOctets; 124af57ed9fSAtsushi Murai StopTimer(&IpcpReportTimer); 125af57ed9fSAtsushi Murai IpcpReportTimer.state = TIMER_STOPPED; 126af57ed9fSAtsushi Murai StartTimer(&IpcpReportTimer); 127af57ed9fSAtsushi Murai } 128af57ed9fSAtsushi Murai 129af57ed9fSAtsushi Murai static void 130af57ed9fSAtsushi Murai IpcpStartReport() 131af57ed9fSAtsushi Murai { 132af57ed9fSAtsushi Murai ipIdleSecs = ipConnectSecs = 0; 133af57ed9fSAtsushi Murai StopTimer(&IpcpReportTimer); 134af57ed9fSAtsushi Murai IpcpReportTimer.state = TIMER_STOPPED; 135af57ed9fSAtsushi Murai IpcpReportTimer.load = SECTICKS; 136af57ed9fSAtsushi Murai IpcpReportTimer.func = IpcpReportFunc; 137af57ed9fSAtsushi Murai StartTimer(&IpcpReportTimer); 138af57ed9fSAtsushi Murai } 139af57ed9fSAtsushi Murai 140274e766cSBrian Somers int 141af57ed9fSAtsushi Murai ReportIpcpStatus() 142af57ed9fSAtsushi Murai { 143af57ed9fSAtsushi Murai struct ipcpstate *icp = &IpcpInfo; 144af57ed9fSAtsushi Murai struct fsm *fp = &IpcpFsm; 145af57ed9fSAtsushi Murai 146927145beSBrian Somers if (!VarTerm) 147290281edSAndrey A. Chernov return 1; 148927145beSBrian Somers fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]); 149927145beSBrian Somers fprintf(VarTerm, " his side: %s, %lx\n", 150927145beSBrian Somers inet_ntoa(icp->his_ipaddr), icp->his_compproto); 151927145beSBrian Somers fprintf(VarTerm, " my side: %s, %lx\n", 152927145beSBrian Somers inet_ntoa(icp->want_ipaddr), icp->want_compproto); 1535b4c5b00SBrian Somers fprintf(VarTerm, "Connected: %d secs, idle: %d secs\n\n", 1545b4c5b00SBrian Somers ipConnectSecs, ipIdleSecs); 1555b4c5b00SBrian Somers fprintf(VarTerm, " %d octets in, %d octets out\n", 1565b4c5b00SBrian Somers IpcpOctetsIn(), IpcpOctetsOut()); 1575b4c5b00SBrian Somers 158927145beSBrian Somers fprintf(VarTerm, "Defaults:\n"); 159927145beSBrian Somers fprintf(VarTerm, " My Address: %s/%d\n", 160927145beSBrian Somers inet_ntoa(DefMyAddress.ipaddr), DefMyAddress.width); 161927145beSBrian Somers fprintf(VarTerm, " His Address: %s/%d\n", 162927145beSBrian Somers inet_ntoa(DefHisAddress.ipaddr), DefHisAddress.width); 1633f6fd923SBrian Somers if (HaveTriggerAddress) 1643f6fd923SBrian Somers fprintf(VarTerm, " Negotiation(trigger): %s\n", inet_ntoa(TriggerAddress)); 1653f6fd923SBrian Somers else 1663f6fd923SBrian Somers fprintf(VarTerm, " Negotiation(trigger): MYADDR\n"); 167927145beSBrian Somers 168927145beSBrian Somers return 0; 169af57ed9fSAtsushi Murai } 170af57ed9fSAtsushi Murai 171af57ed9fSAtsushi Murai void 172af57ed9fSAtsushi Murai IpcpDefAddress() 173af57ed9fSAtsushi Murai { 174af57ed9fSAtsushi Murai struct hostent *hp; 175af57ed9fSAtsushi Murai char name[200]; 176af57ed9fSAtsushi Murai 17775240ed1SBrian Somers memset(&DefMyAddress, '\0', sizeof(DefMyAddress)); 17875240ed1SBrian Somers memset(&DefHisAddress, '\0', sizeof(DefHisAddress)); 1793f6fd923SBrian Somers TriggerAddress.s_addr = 0; 1803f6fd923SBrian Somers HaveTriggerAddress = 0; 181af57ed9fSAtsushi Murai if (gethostname(name, sizeof(name)) == 0) { 182af57ed9fSAtsushi Murai hp = gethostbyname(name); 183af57ed9fSAtsushi Murai if (hp && hp->h_addrtype == AF_INET) { 18475240ed1SBrian Somers memcpy(&DefMyAddress.ipaddr.s_addr, hp->h_addr, hp->h_length); 185af57ed9fSAtsushi Murai } 186af57ed9fSAtsushi Murai } 187af57ed9fSAtsushi Murai } 188af57ed9fSAtsushi Murai 189af57ed9fSAtsushi Murai void 190af57ed9fSAtsushi Murai IpcpInit() 191af57ed9fSAtsushi Murai { 192af57ed9fSAtsushi Murai struct ipcpstate *icp = &IpcpInfo; 193af57ed9fSAtsushi Murai 194af57ed9fSAtsushi Murai FsmInit(&IpcpFsm); 19575240ed1SBrian Somers memset(icp, '\0', sizeof(struct ipcpstate)); 196af57ed9fSAtsushi Murai if ((mode & MODE_DEDICATED) && !dstsystem) { 197af57ed9fSAtsushi Murai icp->want_ipaddr.s_addr = icp->his_ipaddr.s_addr = 0; 198af57ed9fSAtsushi Murai } else { 199af57ed9fSAtsushi Murai icp->want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr; 200af57ed9fSAtsushi Murai icp->his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr; 201af57ed9fSAtsushi Murai } 202549d663dSAtsushi Murai 203549d663dSAtsushi Murai /* 2045b4c5b00SBrian Somers * Some implementations of PPP require that we send a 2055b4c5b00SBrian Somers * *special* value as our address, even though the rfc specifies 2065b4c5b00SBrian Somers * full negotiation (e.g. "0.0.0.0" or Not "0.0.0.0"). 207549d663dSAtsushi Murai */ 2083f6fd923SBrian Somers if (HaveTriggerAddress) { 2093f6fd923SBrian Somers icp->want_ipaddr.s_addr = TriggerAddress.s_addr; 210cb611434SBrian Somers LogPrintf(LogIPCP, "Using trigger address %s\n", inet_ntoa(TriggerAddress)); 211549d663dSAtsushi Murai } 212af57ed9fSAtsushi Murai if (Enabled(ConfVjcomp)) 213ee5c6273SBrian Somers icp->want_compproto = (PROTO_VJCOMP << 16) | ((MAX_STATES - 1) << 8) | 1; 214af57ed9fSAtsushi Murai else 215af57ed9fSAtsushi Murai icp->want_compproto = 0; 216af57ed9fSAtsushi Murai icp->heis1172 = 0; 217af57ed9fSAtsushi Murai IpcpFsm.maxconfig = 10; 2185b4c5b00SBrian Somers StartingIpIn = ipInOctets; 2195b4c5b00SBrian Somers StartingIpOut = ipOutOctets; 220af57ed9fSAtsushi Murai } 221af57ed9fSAtsushi Murai 222af57ed9fSAtsushi Murai static void 223944f7098SBrian Somers IpcpInitRestartCounter(struct fsm * fp) 224af57ed9fSAtsushi Murai { 22553c9f6c0SAtsushi Murai fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 226af57ed9fSAtsushi Murai fp->restart = 5; 227af57ed9fSAtsushi Murai } 228af57ed9fSAtsushi Murai 229af57ed9fSAtsushi Murai static void 230944f7098SBrian Somers IpcpSendConfigReq(struct fsm * fp) 231af57ed9fSAtsushi Murai { 232af57ed9fSAtsushi Murai u_char *cp; 233af57ed9fSAtsushi Murai struct ipcpstate *icp = &IpcpInfo; 234af57ed9fSAtsushi Murai 235af57ed9fSAtsushi Murai cp = ReqBuff; 236cb611434SBrian Somers LogPrintf(LogIPCP, "IpcpSendConfigReq\n"); 23753c9f6c0SAtsushi Murai if (!DEV_IS_SYNC || !REJECTED(icp, TY_IPADDR)) 238af57ed9fSAtsushi Murai PutConfValue(&cp, cftypes, TY_IPADDR, 6, ntohl(icp->want_ipaddr.s_addr)); 239af57ed9fSAtsushi Murai if (icp->want_compproto && !REJECTED(icp, TY_COMPPROTO)) { 240af57ed9fSAtsushi Murai if (icp->heis1172) 241af57ed9fSAtsushi Murai PutConfValue(&cp, cftypes, TY_COMPPROTO, 4, icp->want_compproto >> 16); 242af57ed9fSAtsushi Murai else 243af57ed9fSAtsushi Murai PutConfValue(&cp, cftypes, TY_COMPPROTO, 6, icp->want_compproto); 244af57ed9fSAtsushi Murai } 245af57ed9fSAtsushi Murai FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 246af57ed9fSAtsushi Murai } 247af57ed9fSAtsushi Murai 248af57ed9fSAtsushi Murai static void 249944f7098SBrian Somers IpcpSendTerminateReq(struct fsm * fp) 250af57ed9fSAtsushi Murai { 251af57ed9fSAtsushi Murai /* XXX: No code yet */ 252af57ed9fSAtsushi Murai } 253af57ed9fSAtsushi Murai 254af57ed9fSAtsushi Murai static void 255944f7098SBrian Somers IpcpSendTerminateAck(struct fsm * fp) 256af57ed9fSAtsushi Murai { 257cb611434SBrian Somers LogPrintf(LogIPCP, "IpcpSendTerminateAck\n"); 258af57ed9fSAtsushi Murai FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 259af57ed9fSAtsushi Murai } 260af57ed9fSAtsushi Murai 261af57ed9fSAtsushi Murai static void 262944f7098SBrian Somers IpcpLayerStart(struct fsm * fp) 263af57ed9fSAtsushi Murai { 264cb611434SBrian Somers LogPrintf(LogIPCP, "IpcpLayerStart.\n"); 265af57ed9fSAtsushi Murai } 266af57ed9fSAtsushi Murai 267af57ed9fSAtsushi Murai static void 268944f7098SBrian Somers IpcpLayerFinish(struct fsm * fp) 269af57ed9fSAtsushi Murai { 270cb611434SBrian Somers LogPrintf(LogIPCP, "IpcpLayerFinish.\n"); 27125aa96acSBrian Somers reconnect(RECON_FALSE); 272af57ed9fSAtsushi Murai LcpClose(); 273af57ed9fSAtsushi Murai NewPhase(PHASE_TERMINATE); 274af57ed9fSAtsushi Murai } 275af57ed9fSAtsushi Murai 27675240ed1SBrian Somers static int 2775b4c5b00SBrian Somers IpcpOctetsIn() 2785b4c5b00SBrian Somers { 2795b4c5b00SBrian Somers return ipInOctets < StartingIpIn ? 2805b4c5b00SBrian Somers INT_MAX - StartingIpIn + ipInOctets - INT_MIN + 1 : 2815b4c5b00SBrian Somers ipInOctets - StartingIpIn; 2825b4c5b00SBrian Somers } 2835b4c5b00SBrian Somers 28475240ed1SBrian Somers static int 2855b4c5b00SBrian Somers IpcpOctetsOut() 2865b4c5b00SBrian Somers { 2875b4c5b00SBrian Somers return ipOutOctets < StartingIpOut ? 2885b4c5b00SBrian Somers INT_MAX - StartingIpOut + ipOutOctets - INT_MIN + 1 : 2895b4c5b00SBrian Somers ipOutOctets - StartingIpOut; 2905b4c5b00SBrian Somers } 2915b4c5b00SBrian Somers 292af57ed9fSAtsushi Murai static void 293944f7098SBrian Somers IpcpLayerDown(struct fsm * fp) 294af57ed9fSAtsushi Murai { 295cb611434SBrian Somers LogPrintf(LogIPCP, "IpcpLayerDown.\n"); 2965b4c5b00SBrian Somers LogPrintf(LogIPCP, "%d octets in, %d octets out\n", 2975b4c5b00SBrian Somers IpcpOctetsIn(), IpcpOctetsOut()); 298af57ed9fSAtsushi Murai StopTimer(&IpcpReportTimer); 2990fe7ca31SBrian Somers Prompt(); 300af57ed9fSAtsushi Murai } 301af57ed9fSAtsushi Murai 302af57ed9fSAtsushi Murai /* 303af57ed9fSAtsushi Murai * Called when IPCP has reached to OPEN state 304af57ed9fSAtsushi Murai */ 305af57ed9fSAtsushi Murai static void 306944f7098SBrian Somers IpcpLayerUp(struct fsm * fp) 307af57ed9fSAtsushi Murai { 308af57ed9fSAtsushi Murai char tbuff[100]; 309af57ed9fSAtsushi Murai 310274e766cSBrian Somers Prompt(); 311cb611434SBrian Somers LogPrintf(LogIPCP, "IpcpLayerUp(%d).\n", fp->state); 31299c02d39SWarner Losh snprintf(tbuff, sizeof(tbuff), "myaddr = %s ", 31399c02d39SWarner Losh inet_ntoa(IpcpInfo.want_ipaddr)); 31403604f35SBrian Somers 31503604f35SBrian Somers if (IpcpInfo.his_compproto >> 16 == PROTO_VJCOMP) 31603604f35SBrian Somers VjInit((IpcpInfo.his_compproto >> 8) & 255); 31703604f35SBrian Somers 318cb611434SBrian Somers LogPrintf(LogIsKept(LogIPCP) ? LogIPCP : LogLINK, " %s hisaddr = %s\n", 319927145beSBrian Somers tbuff, inet_ntoa(IpcpInfo.his_ipaddr)); 320274e766cSBrian Somers if (OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr, ifnetmask) < 0) { 321927145beSBrian Somers if (VarTerm) 322927145beSBrian Somers LogPrintf(LogERROR, "IpcpLayerUp: unable to set ip address\n"); 323274e766cSBrian Somers return; 324274e766cSBrian Somers } 3254eb8b164SBrian Somers if (mode & MODE_ALIAS) 326944f7098SBrian Somers VarPacketAliasSetAddress(IpcpInfo.want_ipaddr); 327af57ed9fSAtsushi Murai OsLinkup(); 3285b4c5b00SBrian Somers StartingIpIn = ipInOctets; 3295b4c5b00SBrian Somers StartingIpOut = ipOutOctets; 330af57ed9fSAtsushi Murai IpcpStartReport(); 331af57ed9fSAtsushi Murai StartIdleTimer(); 332af57ed9fSAtsushi Murai } 333af57ed9fSAtsushi Murai 334af57ed9fSAtsushi Murai void 335af57ed9fSAtsushi Murai IpcpUp() 336af57ed9fSAtsushi Murai { 337af57ed9fSAtsushi Murai FsmUp(&IpcpFsm); 338cb611434SBrian Somers LogPrintf(LogIPCP, "IPCP Up event!!\n"); 339af57ed9fSAtsushi Murai } 340af57ed9fSAtsushi Murai 341af57ed9fSAtsushi Murai void 342af57ed9fSAtsushi Murai IpcpOpen() 343af57ed9fSAtsushi Murai { 344af57ed9fSAtsushi Murai FsmOpen(&IpcpFsm); 345af57ed9fSAtsushi Murai } 346af57ed9fSAtsushi Murai 347af57ed9fSAtsushi Murai static int 348944f7098SBrian Somers AcceptableAddr(struct in_range * prange, struct in_addr ipaddr) 349af57ed9fSAtsushi Murai { 350afc7fa2cSBrian Somers LogPrintf(LogDEBUG, "requested = %x\n", htonl(ipaddr.s_addr)); 351afc7fa2cSBrian Somers LogPrintf(LogDEBUG, "range = %x\n", htonl(prange->ipaddr.s_addr)); 352927145beSBrian Somers LogPrintf(LogDEBUG, "/%x\n", htonl(prange->mask.s_addr)); 353927145beSBrian Somers LogPrintf(LogDEBUG, "%x, %x\n", htonl(prange->ipaddr.s_addr & prange-> 354927145beSBrian Somers mask.s_addr), htonl(ipaddr.s_addr & prange->mask.s_addr)); 355057df964SBrian Somers return (prange->ipaddr.s_addr & prange->mask.s_addr) == 356057df964SBrian Somers (ipaddr.s_addr & prange->mask.s_addr) && ipaddr.s_addr; 357af57ed9fSAtsushi Murai } 358af57ed9fSAtsushi Murai 359af57ed9fSAtsushi Murai static void 3609780ef31SBrian Somers IpcpDecodeConfig(u_char * cp, int plen, int mode_type) 361af57ed9fSAtsushi Murai { 36253c9f6c0SAtsushi Murai int type, length; 363af57ed9fSAtsushi Murai u_long *lp, compproto; 364af57ed9fSAtsushi Murai struct compreq *pcomp; 365d8e55738SJordan K. Hubbard struct in_addr ipaddr, dstipaddr, dnsstuff, ms_info_req; 366af57ed9fSAtsushi Murai char tbuff[100]; 36799c02d39SWarner Losh char tbuff2[100]; 368af57ed9fSAtsushi Murai 369af57ed9fSAtsushi Murai ackp = AckBuff; 370af57ed9fSAtsushi Murai nakp = NakBuff; 371af57ed9fSAtsushi Murai rejp = RejBuff; 372af57ed9fSAtsushi Murai 373af57ed9fSAtsushi Murai while (plen >= sizeof(struct fsmconfig)) { 374af57ed9fSAtsushi Murai type = *cp; 375af57ed9fSAtsushi Murai length = cp[1]; 376af57ed9fSAtsushi Murai if (type <= TY_IPADDR) 37799c02d39SWarner Losh snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); 378af57ed9fSAtsushi Murai else 37999c02d39SWarner Losh snprintf(tbuff, sizeof(tbuff), " "); 380af57ed9fSAtsushi Murai 381af57ed9fSAtsushi Murai switch (type) { 382af57ed9fSAtsushi Murai case TY_IPADDR: /* RFC1332 */ 383af57ed9fSAtsushi Murai lp = (u_long *) (cp + 2); 384af57ed9fSAtsushi Murai ipaddr.s_addr = *lp; 385cb611434SBrian Somers LogPrintf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 386af57ed9fSAtsushi Murai 3879780ef31SBrian Somers switch (mode_type) { 388af57ed9fSAtsushi Murai case MODE_REQ: 389af57ed9fSAtsushi Murai if (!AcceptableAddr(&DefHisAddress, ipaddr)) { 390af57ed9fSAtsushi Murai /* 391944f7098SBrian Somers * If destination address is not acceptable, insist to use what we 392944f7098SBrian Somers * want to use. 393af57ed9fSAtsushi Murai */ 39475240ed1SBrian Somers memcpy(nakp, cp, 2); 39575240ed1SBrian Somers memcpy(nakp+2, &IpcpInfo.his_ipaddr.s_addr, length); 396af57ed9fSAtsushi Murai nakp += length; 397af57ed9fSAtsushi Murai break; 398af57ed9fSAtsushi Murai } 399af57ed9fSAtsushi Murai IpcpInfo.his_ipaddr = ipaddr; 40075240ed1SBrian Somers memcpy(ackp, cp, length); 401af57ed9fSAtsushi Murai ackp += length; 402af57ed9fSAtsushi Murai break; 403af57ed9fSAtsushi Murai case MODE_NAK: 404af57ed9fSAtsushi Murai if (AcceptableAddr(&DefMyAddress, ipaddr)) { 405944f7098SBrian Somers 406af57ed9fSAtsushi Murai /* 407af57ed9fSAtsushi Murai * Use address suggested by peer. 408af57ed9fSAtsushi Murai */ 409afc7fa2cSBrian Somers snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s ", tbuff, 410afc7fa2cSBrian Somers inet_ntoa(IpcpInfo.want_ipaddr)); 411cb611434SBrian Somers LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 412af57ed9fSAtsushi Murai IpcpInfo.want_ipaddr = ipaddr; 413af57ed9fSAtsushi Murai } 414af57ed9fSAtsushi Murai break; 415af57ed9fSAtsushi Murai case MODE_REJ: 416af57ed9fSAtsushi Murai IpcpInfo.his_reject |= (1 << type); 417af57ed9fSAtsushi Murai break; 418af57ed9fSAtsushi Murai } 419af57ed9fSAtsushi Murai break; 420af57ed9fSAtsushi Murai case TY_COMPPROTO: 421af57ed9fSAtsushi Murai lp = (u_long *) (cp + 2); 422af57ed9fSAtsushi Murai compproto = htonl(*lp); 423cb611434SBrian Somers LogPrintf(LogIPCP, "%s %08x\n", tbuff, compproto); 424af57ed9fSAtsushi Murai 4259780ef31SBrian Somers switch (mode_type) { 426af57ed9fSAtsushi Murai case MODE_REQ: 427af57ed9fSAtsushi Murai if (!Acceptable(ConfVjcomp)) { 42875240ed1SBrian Somers memcpy(rejp, cp, length); 429af57ed9fSAtsushi Murai rejp += length; 430af57ed9fSAtsushi Murai } else { 431af57ed9fSAtsushi Murai pcomp = (struct compreq *) (cp + 2); 432af57ed9fSAtsushi Murai switch (length) { 433af57ed9fSAtsushi Murai case 4: /* RFC1172 */ 434af57ed9fSAtsushi Murai if (ntohs(pcomp->proto) == PROTO_VJCOMP) { 4354ef16f24SBrian Somers LogPrintf(LogWARN, "Peer is speaking RFC1172 compression protocol !\n"); 436af57ed9fSAtsushi Murai IpcpInfo.heis1172 = 1; 437af57ed9fSAtsushi Murai IpcpInfo.his_compproto = compproto; 43875240ed1SBrian Somers memcpy(ackp, cp, length); 439af57ed9fSAtsushi Murai ackp += length; 440af57ed9fSAtsushi Murai } else { 44175240ed1SBrian Somers memcpy(nakp, cp, 2); 442af57ed9fSAtsushi Murai pcomp->proto = htons(PROTO_VJCOMP); 44375240ed1SBrian Somers memcpy(nakp+2, &pcomp, 2); 444af57ed9fSAtsushi Murai nakp += length; 445af57ed9fSAtsushi Murai } 446af57ed9fSAtsushi Murai break; 447af57ed9fSAtsushi Murai case 6: /* RFC1332 */ 448af57ed9fSAtsushi Murai if (ntohs(pcomp->proto) == PROTO_VJCOMP 449af57ed9fSAtsushi Murai && pcomp->slots < MAX_STATES && pcomp->slots > 2) { 450af57ed9fSAtsushi Murai IpcpInfo.his_compproto = compproto; 451af57ed9fSAtsushi Murai IpcpInfo.heis1172 = 0; 45275240ed1SBrian Somers memcpy(ackp, cp, length); 453af57ed9fSAtsushi Murai ackp += length; 454af57ed9fSAtsushi Murai } else { 45575240ed1SBrian Somers memcpy(nakp, cp, 2); 456af57ed9fSAtsushi Murai pcomp->proto = htons(PROTO_VJCOMP); 457af57ed9fSAtsushi Murai pcomp->slots = MAX_STATES - 1; 458af57ed9fSAtsushi Murai pcomp->compcid = 0; 45975240ed1SBrian Somers memcpy(nakp+2, &pcomp, sizeof(pcomp)); 460af57ed9fSAtsushi Murai nakp += length; 461af57ed9fSAtsushi Murai } 462af57ed9fSAtsushi Murai break; 463af57ed9fSAtsushi Murai default: 46475240ed1SBrian Somers memcpy(rejp, cp, length); 465af57ed9fSAtsushi Murai rejp += length; 466af57ed9fSAtsushi Murai break; 467af57ed9fSAtsushi Murai } 468af57ed9fSAtsushi Murai } 469af57ed9fSAtsushi Murai break; 470af57ed9fSAtsushi Murai case MODE_NAK: 471cb611434SBrian Somers LogPrintf(LogIPCP, "%s changing compproto: %08x --> %08x\n", 472af57ed9fSAtsushi Murai tbuff, IpcpInfo.want_compproto, compproto); 473af57ed9fSAtsushi Murai IpcpInfo.want_compproto = compproto; 474af57ed9fSAtsushi Murai break; 475af57ed9fSAtsushi Murai case MODE_REJ: 476af57ed9fSAtsushi Murai IpcpInfo.his_reject |= (1 << type); 477af57ed9fSAtsushi Murai break; 478af57ed9fSAtsushi Murai } 479af57ed9fSAtsushi Murai break; 480af57ed9fSAtsushi Murai case TY_IPADDRS: /* RFC1172 */ 481af57ed9fSAtsushi Murai lp = (u_long *) (cp + 2); 482af57ed9fSAtsushi Murai ipaddr.s_addr = *lp; 483af57ed9fSAtsushi Murai lp = (u_long *) (cp + 6); 484af57ed9fSAtsushi Murai dstipaddr.s_addr = *lp; 485afc7fa2cSBrian Somers snprintf(tbuff2, sizeof(tbuff2), "%s %s,", tbuff, inet_ntoa(ipaddr)); 486afc7fa2cSBrian Somers LogPrintf(LogIPCP, "%s %s\n", tbuff2, inet_ntoa(dstipaddr)); 487af57ed9fSAtsushi Murai 4889780ef31SBrian Somers switch (mode_type) { 489af57ed9fSAtsushi Murai case MODE_REQ: 490af57ed9fSAtsushi Murai IpcpInfo.his_ipaddr = ipaddr; 491af57ed9fSAtsushi Murai IpcpInfo.want_ipaddr = dstipaddr; 49275240ed1SBrian Somers memcpy(ackp, cp, length); 493af57ed9fSAtsushi Murai ackp += length; 494af57ed9fSAtsushi Murai break; 495af57ed9fSAtsushi Murai case MODE_NAK: 496afc7fa2cSBrian Somers snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s", tbuff, 497afc7fa2cSBrian Somers inet_ntoa(IpcpInfo.want_ipaddr)); 498afc7fa2cSBrian Somers LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 499af57ed9fSAtsushi Murai IpcpInfo.want_ipaddr = ipaddr; 500af57ed9fSAtsushi Murai IpcpInfo.his_ipaddr = dstipaddr; 501af57ed9fSAtsushi Murai break; 502af57ed9fSAtsushi Murai case MODE_REJ: 503af57ed9fSAtsushi Murai IpcpInfo.his_reject |= (1 << type); 504af57ed9fSAtsushi Murai break; 505af57ed9fSAtsushi Murai } 506af57ed9fSAtsushi Murai break; 507d8e55738SJordan K. Hubbard 508d8e55738SJordan K. Hubbard /* 509d8e55738SJordan K. Hubbard * MS extensions for MS's PPP 510d8e55738SJordan K. Hubbard */ 511d8e55738SJordan K. Hubbard 512927145beSBrian Somers #ifndef NOMSEXT 513d8e55738SJordan K. Hubbard case TY_PRIMARY_DNS: /* MS PPP DNS negotiation hack */ 514d8e55738SJordan K. Hubbard case TY_SECONDARY_DNS: 515d8e55738SJordan K. Hubbard if (!Enabled(ConfMSExt)) { 516cb611434SBrian Somers LogPrintf(LogIPCP, "MS NS req - rejected - msext disabled\n"); 517d8e55738SJordan K. Hubbard IpcpInfo.my_reject |= (1 << type); 51875240ed1SBrian Somers memcpy(rejp, cp, length); 519d8e55738SJordan K. Hubbard rejp += length; 520d8e55738SJordan K. Hubbard break; 521d8e55738SJordan K. Hubbard } 5229780ef31SBrian Somers switch (mode_type) { 523d8e55738SJordan K. Hubbard case MODE_REQ: 524d8e55738SJordan K. Hubbard lp = (u_long *) (cp + 2); 525d8e55738SJordan K. Hubbard dnsstuff.s_addr = *lp; 526d8e55738SJordan K. Hubbard ms_info_req.s_addr = ns_entries[((type - TY_PRIMARY_DNS) ? 1 : 0)].s_addr; 527944f7098SBrian Somers if (dnsstuff.s_addr != ms_info_req.s_addr) { 528944f7098SBrian Somers 529d8e55738SJordan K. Hubbard /* 530944f7098SBrian Somers * So the client has got the DNS stuff wrong (first request) so 531afc7fa2cSBrian Somers * we'll tell 'em how it is 532d8e55738SJordan K. Hubbard */ 53375240ed1SBrian Somers memcpy(nakp, cp, 2); /* copy first two (type/length) */ 534cb611434SBrian Somers LogPrintf(LogIPCP, "MS NS req %d:%s->%s - nak\n", 535d8e55738SJordan K. Hubbard type, 536d8e55738SJordan K. Hubbard inet_ntoa(dnsstuff), 537d8e55738SJordan K. Hubbard inet_ntoa(ms_info_req)); 53875240ed1SBrian Somers memcpy(nakp+2, &ms_info_req, length); 539d8e55738SJordan K. Hubbard nakp += length; 540d8e55738SJordan K. Hubbard break; 541d8e55738SJordan K. Hubbard } 542944f7098SBrian Somers 543d8e55738SJordan K. Hubbard /* 544944f7098SBrian Somers * Otherwise they have it right (this time) so we send a ack packet 545944f7098SBrian Somers * back confirming it... end of story 546d8e55738SJordan K. Hubbard */ 547cb611434SBrian Somers LogPrintf(LogIPCP, "MS NS req %d:%s ok - ack\n", 548d8e55738SJordan K. Hubbard type, 549d8e55738SJordan K. Hubbard inet_ntoa(ms_info_req)); 55075240ed1SBrian Somers memcpy(ackp, cp, length); 551d8e55738SJordan K. Hubbard ackp += length; 552d8e55738SJordan K. Hubbard break; 553d8e55738SJordan K. Hubbard case MODE_NAK: /* what does this mean?? */ 554cb611434SBrian Somers LogPrintf(LogIPCP, "MS NS req %d - NAK??\n", type); 555d8e55738SJordan K. Hubbard break; 556d8e55738SJordan K. Hubbard case MODE_REJ: /* confused?? me to :) */ 557cb611434SBrian Somers LogPrintf(LogIPCP, "MS NS req %d - REJ??\n", type); 558d8e55738SJordan K. Hubbard break; 559d8e55738SJordan K. Hubbard } 560d8e55738SJordan K. Hubbard break; 561d8e55738SJordan K. Hubbard 562d8e55738SJordan K. Hubbard case TY_PRIMARY_NBNS: /* MS PPP NetBIOS nameserver hack */ 563d8e55738SJordan K. Hubbard case TY_SECONDARY_NBNS: 564d8e55738SJordan K. Hubbard if (!Enabled(ConfMSExt)) { 565cb611434SBrian Somers LogPrintf(LogIPCP, "MS NBNS req - rejected - msext disabled\n"); 566d8e55738SJordan K. Hubbard IpcpInfo.my_reject |= (1 << type); 56775240ed1SBrian Somers memcpy(rejp, cp, length); 568d8e55738SJordan K. Hubbard rejp += length; 569d8e55738SJordan K. Hubbard break; 570d8e55738SJordan K. Hubbard } 5719780ef31SBrian Somers switch (mode_type) { 572d8e55738SJordan K. Hubbard case MODE_REQ: 573d8e55738SJordan K. Hubbard lp = (u_long *) (cp + 2); 574d8e55738SJordan K. Hubbard dnsstuff.s_addr = *lp; 575d8e55738SJordan K. Hubbard ms_info_req.s_addr = nbns_entries[((type - TY_PRIMARY_NBNS) ? 1 : 0)].s_addr; 576944f7098SBrian Somers if (dnsstuff.s_addr != ms_info_req.s_addr) { 57775240ed1SBrian Somers memcpy(nakp, cp, 2); 57875240ed1SBrian Somers memcpy(nakp+2, &ms_info_req.s_addr, length); 579cb611434SBrian Somers LogPrintf(LogIPCP, "MS NBNS req %d:%s->%s - nak\n", 580d8e55738SJordan K. Hubbard type, 581d8e55738SJordan K. Hubbard inet_ntoa(dnsstuff), 582d8e55738SJordan K. Hubbard inet_ntoa(ms_info_req)); 583d8e55738SJordan K. Hubbard nakp += length; 584d8e55738SJordan K. Hubbard break; 585d8e55738SJordan K. Hubbard } 586cb611434SBrian Somers LogPrintf(LogIPCP, "MS NBNS req %d:%s ok - ack\n", 587d8e55738SJordan K. Hubbard type, 588d8e55738SJordan K. Hubbard inet_ntoa(ms_info_req)); 58975240ed1SBrian Somers memcpy(ackp, cp, length); 590d8e55738SJordan K. Hubbard ackp += length; 591d8e55738SJordan K. Hubbard break; 592d8e55738SJordan K. Hubbard case MODE_NAK: 593cb611434SBrian Somers LogPrintf(LogIPCP, "MS NBNS req %d - NAK??\n", type); 594d8e55738SJordan K. Hubbard break; 595d8e55738SJordan K. Hubbard case MODE_REJ: 596cb611434SBrian Somers LogPrintf(LogIPCP, "MS NBNS req %d - REJ??\n", type); 597d8e55738SJordan K. Hubbard break; 598d8e55738SJordan K. Hubbard } 599d8e55738SJordan K. Hubbard break; 600d8e55738SJordan K. Hubbard 601927145beSBrian Somers #endif 602d8e55738SJordan K. Hubbard 603af57ed9fSAtsushi Murai default: 604af57ed9fSAtsushi Murai IpcpInfo.my_reject |= (1 << type); 60575240ed1SBrian Somers memcpy(rejp, cp, length); 606af57ed9fSAtsushi Murai rejp += length; 607af57ed9fSAtsushi Murai break; 608af57ed9fSAtsushi Murai } 609af57ed9fSAtsushi Murai plen -= length; 610af57ed9fSAtsushi Murai cp += length; 611af57ed9fSAtsushi Murai } 612af57ed9fSAtsushi Murai } 613af57ed9fSAtsushi Murai 614af57ed9fSAtsushi Murai void 615af57ed9fSAtsushi Murai IpcpInput(struct mbuf * bp) 616af57ed9fSAtsushi Murai { 617af57ed9fSAtsushi Murai FsmInput(&IpcpFsm, bp); 618af57ed9fSAtsushi Murai } 619