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 * 20af57ed9fSAtsushi Murai * $Id:$ 21af57ed9fSAtsushi Murai * 22af57ed9fSAtsushi Murai * TODO: 23af57ed9fSAtsushi Murai * o More RFC1772 backwoard compatibility 24af57ed9fSAtsushi Murai */ 25af57ed9fSAtsushi Murai #include "fsm.h" 26af57ed9fSAtsushi Murai #include "lcpproto.h" 27af57ed9fSAtsushi Murai #include "lcp.h" 28af57ed9fSAtsushi Murai #include "ipcp.h" 29af57ed9fSAtsushi Murai #include <netdb.h> 30af57ed9fSAtsushi Murai #include <netinet/in_systm.h> 31af57ed9fSAtsushi Murai #include <netinet/ip.h> 32af57ed9fSAtsushi Murai #include <arpa/inet.h> 33af57ed9fSAtsushi Murai #include <sys/socket.h> 34af57ed9fSAtsushi Murai #include "slcompress.h" 35af57ed9fSAtsushi Murai #include "os.h" 36af57ed9fSAtsushi Murai #include "phase.h" 37af57ed9fSAtsushi Murai #include "vars.h" 38af57ed9fSAtsushi Murai 39af57ed9fSAtsushi Murai extern void PutConfValue(); 40af57ed9fSAtsushi Murai extern void Prompt(); 41af57ed9fSAtsushi Murai extern struct in_addr ifnetmask; 42af57ed9fSAtsushi Murai 43af57ed9fSAtsushi Murai struct ipcpstate IpcpInfo; 44af57ed9fSAtsushi Murai struct in_range DefMyAddress, DefHisAddress; 45af57ed9fSAtsushi Murai 46af57ed9fSAtsushi Murai static void IpcpSendConfigReq(struct fsm *); 47af57ed9fSAtsushi Murai static void IpcpSendTerminateAck(struct fsm *); 48af57ed9fSAtsushi Murai static void IpcpSendTerminateReq(struct fsm *); 49af57ed9fSAtsushi Murai static void IpcpDecodeConfig(); 50af57ed9fSAtsushi Murai static void IpcpLayerStart(struct fsm *); 51af57ed9fSAtsushi Murai static void IpcpLayerFinish(struct fsm *); 52af57ed9fSAtsushi Murai static void IpcpLayerUp(struct fsm *); 53af57ed9fSAtsushi Murai static void IpcpLayerDown(struct fsm *); 54af57ed9fSAtsushi Murai static void IpcpInitRestartCounter(struct fsm *); 55af57ed9fSAtsushi Murai 56af57ed9fSAtsushi Murai static struct pppTimer IpcpReportTimer; 57af57ed9fSAtsushi Murai 58af57ed9fSAtsushi Murai static int lastInOctets, lastOutOctets; 59af57ed9fSAtsushi Murai 60af57ed9fSAtsushi Murai #define REJECTED(p, x) (p->his_reject & (1<<x)) 61af57ed9fSAtsushi Murai 62af57ed9fSAtsushi Murai struct fsm IpcpFsm = { 63af57ed9fSAtsushi Murai "IPCP", 64af57ed9fSAtsushi Murai PROTO_IPCP, 65af57ed9fSAtsushi Murai IPCP_MAXCODE, 66af57ed9fSAtsushi Murai OPEN_ACTIVE, 67af57ed9fSAtsushi Murai ST_INITIAL, 68af57ed9fSAtsushi Murai 0, 0, 0, 69af57ed9fSAtsushi Murai 70af57ed9fSAtsushi Murai 0, 71af57ed9fSAtsushi Murai { 0, 0, 0, NULL, NULL, NULL }, 72af57ed9fSAtsushi Murai 73af57ed9fSAtsushi Murai IpcpLayerUp, 74af57ed9fSAtsushi Murai IpcpLayerDown, 75af57ed9fSAtsushi Murai IpcpLayerStart, 76af57ed9fSAtsushi Murai IpcpLayerFinish, 77af57ed9fSAtsushi Murai IpcpInitRestartCounter, 78af57ed9fSAtsushi Murai IpcpSendConfigReq, 79af57ed9fSAtsushi Murai IpcpSendTerminateReq, 80af57ed9fSAtsushi Murai IpcpSendTerminateAck, 81af57ed9fSAtsushi Murai IpcpDecodeConfig, 82af57ed9fSAtsushi Murai }; 83af57ed9fSAtsushi Murai 84af57ed9fSAtsushi Murai static char *cftypes[] = { 85af57ed9fSAtsushi Murai "???", "IPADDRS", "COMPPROTO", "IPADDR", 86af57ed9fSAtsushi Murai }; 87af57ed9fSAtsushi Murai 88af57ed9fSAtsushi Murai /* 89af57ed9fSAtsushi Murai * Function called every second. Updates connection period and idle period, 90af57ed9fSAtsushi Murai * also update LQR information. 91af57ed9fSAtsushi Murai */ 92af57ed9fSAtsushi Murai static void 93af57ed9fSAtsushi Murai IpcpReportFunc() 94af57ed9fSAtsushi Murai { 95af57ed9fSAtsushi Murai ipConnectSecs++; 96af57ed9fSAtsushi Murai if (lastInOctets == ipInOctets && lastOutOctets == ipOutOctets) 97af57ed9fSAtsushi Murai ipIdleSecs++; 98af57ed9fSAtsushi Murai lastInOctets = ipInOctets; 99af57ed9fSAtsushi Murai lastOutOctets = ipOutOctets; 100af57ed9fSAtsushi Murai StopTimer(&IpcpReportTimer); 101af57ed9fSAtsushi Murai IpcpReportTimer.state = TIMER_STOPPED; 102af57ed9fSAtsushi Murai StartTimer(&IpcpReportTimer); 103af57ed9fSAtsushi Murai } 104af57ed9fSAtsushi Murai 105af57ed9fSAtsushi Murai static void 106af57ed9fSAtsushi Murai IpcpStartReport() 107af57ed9fSAtsushi Murai { 108af57ed9fSAtsushi Murai ipIdleSecs = ipConnectSecs = 0; 109af57ed9fSAtsushi Murai StopTimer(&IpcpReportTimer); 110af57ed9fSAtsushi Murai IpcpReportTimer.state = TIMER_STOPPED; 111af57ed9fSAtsushi Murai IpcpReportTimer.load = SECTICKS; 112af57ed9fSAtsushi Murai IpcpReportTimer.func = IpcpReportFunc; 113af57ed9fSAtsushi Murai StartTimer(&IpcpReportTimer); 114af57ed9fSAtsushi Murai } 115af57ed9fSAtsushi Murai 116af57ed9fSAtsushi Murai void 117af57ed9fSAtsushi Murai ReportIpcpStatus() 118af57ed9fSAtsushi Murai { 119af57ed9fSAtsushi Murai struct ipcpstate *icp = &IpcpInfo; 120af57ed9fSAtsushi Murai struct fsm *fp = &IpcpFsm; 121af57ed9fSAtsushi Murai 122af57ed9fSAtsushi Murai printf("%s [%s]\n", fp->name, StateNames[fp->state]); 123af57ed9fSAtsushi Murai printf(" his side: %s, %x\n", 124af57ed9fSAtsushi Murai inet_ntoa(icp->his_ipaddr), icp->his_compproto); 125af57ed9fSAtsushi Murai printf(" my side: %s, %x\n", 126af57ed9fSAtsushi Murai inet_ntoa(icp->want_ipaddr), icp->want_compproto); 127af57ed9fSAtsushi Murai printf("connected: %d secs, idle: %d secs\n\n", ipConnectSecs, ipIdleSecs); 128af57ed9fSAtsushi Murai printf("Defaults: My Address: %s/%d ", 129af57ed9fSAtsushi Murai inet_ntoa(DefMyAddress.ipaddr), DefMyAddress.width); 130af57ed9fSAtsushi Murai printf("His Address: %s/%d\n", 131af57ed9fSAtsushi Murai inet_ntoa(DefHisAddress.ipaddr), DefHisAddress.width); 132af57ed9fSAtsushi Murai } 133af57ed9fSAtsushi Murai 134af57ed9fSAtsushi Murai void 135af57ed9fSAtsushi Murai IpcpDefAddress() 136af57ed9fSAtsushi Murai { 137af57ed9fSAtsushi Murai struct hostent *hp; 138af57ed9fSAtsushi Murai char name[200]; 139af57ed9fSAtsushi Murai 140af57ed9fSAtsushi Murai bzero(&DefMyAddress, sizeof(DefMyAddress)); 141af57ed9fSAtsushi Murai bzero(&DefHisAddress, sizeof(DefHisAddress)); 142af57ed9fSAtsushi Murai if (gethostname(name, sizeof(name)) == 0) { 143af57ed9fSAtsushi Murai hp = gethostbyname(name); 144af57ed9fSAtsushi Murai if (hp && hp->h_addrtype == AF_INET) { 145af57ed9fSAtsushi Murai bcopy(hp->h_addr, (char *)&DefMyAddress.ipaddr.s_addr, hp->h_length); 146af57ed9fSAtsushi Murai } 147af57ed9fSAtsushi Murai } 148af57ed9fSAtsushi Murai } 149af57ed9fSAtsushi Murai 150af57ed9fSAtsushi Murai void 151af57ed9fSAtsushi Murai IpcpInit() 152af57ed9fSAtsushi Murai { 153af57ed9fSAtsushi Murai struct ipcpstate *icp = &IpcpInfo; 154af57ed9fSAtsushi Murai 155af57ed9fSAtsushi Murai FsmInit(&IpcpFsm); 156af57ed9fSAtsushi Murai bzero(icp, sizeof(struct ipcpstate)); 157af57ed9fSAtsushi Murai if ((mode & MODE_DEDICATED) && !dstsystem) { 158af57ed9fSAtsushi Murai icp->want_ipaddr.s_addr = icp->his_ipaddr.s_addr = 0; 159af57ed9fSAtsushi Murai } else { 160af57ed9fSAtsushi Murai icp->want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr; 161af57ed9fSAtsushi Murai icp->his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr; 162af57ed9fSAtsushi Murai } 163af57ed9fSAtsushi Murai if (icp->want_ipaddr.s_addr == 0) 164af57ed9fSAtsushi Murai icp->want_ipaddr.s_addr = htonl(0xc0000001); 165af57ed9fSAtsushi Murai if (Enabled(ConfVjcomp)) 166af57ed9fSAtsushi Murai icp->want_compproto = (PROTO_VJCOMP << 16) | ((MAX_STATES - 1) << 8); 167af57ed9fSAtsushi Murai else 168af57ed9fSAtsushi Murai icp->want_compproto = 0; 169af57ed9fSAtsushi Murai icp->heis1172 = 0; 170af57ed9fSAtsushi Murai IpcpFsm.maxconfig = 10; 171af57ed9fSAtsushi Murai } 172af57ed9fSAtsushi Murai 173af57ed9fSAtsushi Murai static void 174af57ed9fSAtsushi Murai IpcpInitRestartCounter(fp) 175af57ed9fSAtsushi Murai struct fsm *fp; 176af57ed9fSAtsushi Murai { 177af57ed9fSAtsushi Murai fp->FsmTimer.load = 3 * SECTICKS; 178af57ed9fSAtsushi Murai fp->restart = 5; 179af57ed9fSAtsushi Murai } 180af57ed9fSAtsushi Murai 181af57ed9fSAtsushi Murai static void 182af57ed9fSAtsushi Murai IpcpSendConfigReq(fp) 183af57ed9fSAtsushi Murai struct fsm *fp; 184af57ed9fSAtsushi Murai { 185af57ed9fSAtsushi Murai u_char *cp; 186af57ed9fSAtsushi Murai struct ipcpstate *icp = &IpcpInfo; 187af57ed9fSAtsushi Murai 188af57ed9fSAtsushi Murai cp = ReqBuff; 189af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s: SendConfigReq\n", fp->name); 190af57ed9fSAtsushi Murai PutConfValue(&cp, cftypes, TY_IPADDR, 6, ntohl(icp->want_ipaddr.s_addr)); 191af57ed9fSAtsushi Murai if (icp->want_compproto && !REJECTED(icp, TY_COMPPROTO)) { 192af57ed9fSAtsushi Murai if (icp->heis1172) 193af57ed9fSAtsushi Murai PutConfValue(&cp, cftypes, TY_COMPPROTO, 4, icp->want_compproto >> 16); 194af57ed9fSAtsushi Murai else 195af57ed9fSAtsushi Murai PutConfValue(&cp, cftypes, TY_COMPPROTO, 6, icp->want_compproto); 196af57ed9fSAtsushi Murai } 197af57ed9fSAtsushi Murai FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 198af57ed9fSAtsushi Murai } 199af57ed9fSAtsushi Murai 200af57ed9fSAtsushi Murai static void 201af57ed9fSAtsushi Murai IpcpSendTerminateReq(fp) 202af57ed9fSAtsushi Murai struct fsm *fp; 203af57ed9fSAtsushi Murai { 204af57ed9fSAtsushi Murai /* XXX: No code yet */ 205af57ed9fSAtsushi Murai } 206af57ed9fSAtsushi Murai 207af57ed9fSAtsushi Murai static void 208af57ed9fSAtsushi Murai IpcpSendTerminateAck(fp) 209af57ed9fSAtsushi Murai struct fsm *fp; 210af57ed9fSAtsushi Murai { 211af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, " %s: SendTerminateAck\n", fp->name); 212af57ed9fSAtsushi Murai FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 213af57ed9fSAtsushi Murai } 214af57ed9fSAtsushi Murai 215af57ed9fSAtsushi Murai static void 216af57ed9fSAtsushi Murai IpcpLayerStart(fp) 217af57ed9fSAtsushi Murai struct fsm *fp; 218af57ed9fSAtsushi Murai { 219af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s: LayerStart.\n", fp->name); 220af57ed9fSAtsushi Murai } 221af57ed9fSAtsushi Murai 222af57ed9fSAtsushi Murai static void 223af57ed9fSAtsushi Murai IpcpLayerFinish(fp) 224af57ed9fSAtsushi Murai struct fsm *fp; 225af57ed9fSAtsushi Murai { 226af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s: LayerFinish.\n", fp->name); 227af57ed9fSAtsushi Murai LcpClose(); 228af57ed9fSAtsushi Murai NewPhase(PHASE_TERMINATE); 229af57ed9fSAtsushi Murai } 230af57ed9fSAtsushi Murai 231af57ed9fSAtsushi Murai static void 232af57ed9fSAtsushi Murai IpcpLayerDown(fp) 233af57ed9fSAtsushi Murai struct fsm *fp; 234af57ed9fSAtsushi Murai { 235af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s: LayerDown.\n", fp->name); 236af57ed9fSAtsushi Murai StopTimer(&IpcpReportTimer); 237af57ed9fSAtsushi Murai } 238af57ed9fSAtsushi Murai 239af57ed9fSAtsushi Murai /* 240af57ed9fSAtsushi Murai * Called when IPCP has reached to OPEN state 241af57ed9fSAtsushi Murai */ 242af57ed9fSAtsushi Murai static void 243af57ed9fSAtsushi Murai IpcpLayerUp(fp) 244af57ed9fSAtsushi Murai struct fsm *fp; 245af57ed9fSAtsushi Murai { 246af57ed9fSAtsushi Murai char tbuff[100]; 247af57ed9fSAtsushi Murai 248af57ed9fSAtsushi Murai #ifdef VERBOSE 249af57ed9fSAtsushi Murai fprintf(stderr, "%s: LayerUp(%d).\r\n", fp->name, fp->state); 250af57ed9fSAtsushi Murai #endif 251af57ed9fSAtsushi Murai Prompt(1); 252af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s: LayerUp.\n", fp->name); 253af57ed9fSAtsushi Murai sprintf(tbuff, "myaddr = %s ", inet_ntoa(IpcpInfo.want_ipaddr)); 254af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, " %s hisaddr = %s\n", tbuff, inet_ntoa(IpcpInfo.his_ipaddr)); 255af57ed9fSAtsushi Murai OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr, ifnetmask); 256af57ed9fSAtsushi Murai OsLinkup(); 257af57ed9fSAtsushi Murai IpcpStartReport(); 258af57ed9fSAtsushi Murai StartIdleTimer(); 259af57ed9fSAtsushi Murai } 260af57ed9fSAtsushi Murai 261af57ed9fSAtsushi Murai void 262af57ed9fSAtsushi Murai IpcpUp() 263af57ed9fSAtsushi Murai { 264af57ed9fSAtsushi Murai FsmUp(&IpcpFsm); 265af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "IPCP Up event!!\n"); 266af57ed9fSAtsushi Murai } 267af57ed9fSAtsushi Murai 268af57ed9fSAtsushi Murai void 269af57ed9fSAtsushi Murai IpcpOpen() 270af57ed9fSAtsushi Murai { 271af57ed9fSAtsushi Murai FsmOpen(&IpcpFsm); 272af57ed9fSAtsushi Murai } 273af57ed9fSAtsushi Murai 274af57ed9fSAtsushi Murai static int 275af57ed9fSAtsushi Murai AcceptableAddr(prange, ipaddr) 276af57ed9fSAtsushi Murai struct in_range *prange; 277af57ed9fSAtsushi Murai struct in_addr ipaddr; 278af57ed9fSAtsushi Murai { 279af57ed9fSAtsushi Murai #ifdef DEBUG 280af57ed9fSAtsushi Murai logprintf("requested = %x ", htonl(ipaddr.s_addr)); 281af57ed9fSAtsushi Murai logprintf("range = %x", htonl(prange->ipaddr.s_addr)); 282af57ed9fSAtsushi Murai logprintf("/%x\n", htonl(prange->mask.s_addr)); 283af57ed9fSAtsushi Murai logprintf("%x, %x\n", htonl(prange->ipaddr.s_addr & prange->mask.s_addr), 284af57ed9fSAtsushi Murai htonl(ipaddr.s_addr & prange->mask.s_addr)); 285af57ed9fSAtsushi Murai #endif 286af57ed9fSAtsushi Murai return((prange->ipaddr.s_addr & prange->mask.s_addr) == 287af57ed9fSAtsushi Murai (ipaddr.s_addr & prange->mask.s_addr)); 288af57ed9fSAtsushi Murai } 289af57ed9fSAtsushi Murai 290af57ed9fSAtsushi Murai static void 291af57ed9fSAtsushi Murai IpcpDecodeConfig(bp, mode) 292af57ed9fSAtsushi Murai struct mbuf *bp; 293af57ed9fSAtsushi Murai int mode; 294af57ed9fSAtsushi Murai { 295af57ed9fSAtsushi Murai u_char *cp; 296af57ed9fSAtsushi Murai int plen, type, length; 297af57ed9fSAtsushi Murai u_long *lp, compproto; 298af57ed9fSAtsushi Murai struct compreq *pcomp; 299af57ed9fSAtsushi Murai struct in_addr ipaddr, dstipaddr; 300af57ed9fSAtsushi Murai char tbuff[100]; 301af57ed9fSAtsushi Murai 302af57ed9fSAtsushi Murai plen = plength(bp); 303af57ed9fSAtsushi Murai 304af57ed9fSAtsushi Murai cp = MBUF_CTOP(bp); 305af57ed9fSAtsushi Murai ackp = AckBuff; 306af57ed9fSAtsushi Murai nakp = NakBuff; 307af57ed9fSAtsushi Murai rejp = RejBuff; 308af57ed9fSAtsushi Murai 309af57ed9fSAtsushi Murai while (plen >= sizeof(struct fsmconfig)) { 310af57ed9fSAtsushi Murai if (plen < 0) 311af57ed9fSAtsushi Murai break; 312af57ed9fSAtsushi Murai type = *cp; 313af57ed9fSAtsushi Murai length = cp[1]; 314af57ed9fSAtsushi Murai if (type <= TY_IPADDR) 315af57ed9fSAtsushi Murai sprintf(tbuff, " %s[%d] ", cftypes[type], length); 316af57ed9fSAtsushi Murai else 317af57ed9fSAtsushi Murai sprintf(tbuff, " "); 318af57ed9fSAtsushi Murai 319af57ed9fSAtsushi Murai switch (type) { 320af57ed9fSAtsushi Murai case TY_IPADDR: /* RFC1332 */ 321af57ed9fSAtsushi Murai lp = (u_long *)(cp + 2); 322af57ed9fSAtsushi Murai ipaddr.s_addr = *lp; 323af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 324af57ed9fSAtsushi Murai 325af57ed9fSAtsushi Murai switch (mode) { 326af57ed9fSAtsushi Murai case MODE_REQ: 327af57ed9fSAtsushi Murai if (!AcceptableAddr(&DefHisAddress, ipaddr)) { 328af57ed9fSAtsushi Murai /* 329af57ed9fSAtsushi Murai * If destination address is not acceptable, insist to use 330af57ed9fSAtsushi Murai * what we want to use. 331af57ed9fSAtsushi Murai */ 332af57ed9fSAtsushi Murai bcopy(cp, nakp, 2); 333af57ed9fSAtsushi Murai bcopy(&IpcpInfo.his_ipaddr.s_addr, nakp+2, length); 334af57ed9fSAtsushi Murai nakp += length; 335af57ed9fSAtsushi Murai break; 336af57ed9fSAtsushi Murai 337af57ed9fSAtsushi Murai } 338af57ed9fSAtsushi Murai IpcpInfo.his_ipaddr = ipaddr; 339af57ed9fSAtsushi Murai bcopy(cp, ackp, length); 340af57ed9fSAtsushi Murai ackp += length; 341af57ed9fSAtsushi Murai break; 342af57ed9fSAtsushi Murai case MODE_NAK: 343af57ed9fSAtsushi Murai if (AcceptableAddr(&DefMyAddress, ipaddr)) { 344af57ed9fSAtsushi Murai /* 345af57ed9fSAtsushi Murai * Use address suggested by peer. 346af57ed9fSAtsushi Murai */ 347af57ed9fSAtsushi Murai sprintf(tbuff+50, "%s changing address: %s ", tbuff, inet_ntoa(IpcpInfo.want_ipaddr)); 348af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s --> %s\n", tbuff+50, inet_ntoa(ipaddr)); 349af57ed9fSAtsushi Murai IpcpInfo.want_ipaddr = ipaddr; 350af57ed9fSAtsushi Murai } 351af57ed9fSAtsushi Murai break; 352af57ed9fSAtsushi Murai case MODE_REJ: 353af57ed9fSAtsushi Murai IpcpInfo.his_reject |= (1 << type); 354af57ed9fSAtsushi Murai break; 355af57ed9fSAtsushi Murai } 356af57ed9fSAtsushi Murai break; 357af57ed9fSAtsushi Murai case TY_COMPPROTO: 358af57ed9fSAtsushi Murai lp = (u_long *)(cp + 2); 359af57ed9fSAtsushi Murai compproto = htonl(*lp); 360af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s %08x\n", tbuff, compproto); 361af57ed9fSAtsushi Murai 362af57ed9fSAtsushi Murai switch (mode) { 363af57ed9fSAtsushi Murai case MODE_REQ: 364af57ed9fSAtsushi Murai if (!Acceptable(ConfVjcomp)) { 365af57ed9fSAtsushi Murai bcopy(cp, rejp, length); 366af57ed9fSAtsushi Murai rejp += length; 367af57ed9fSAtsushi Murai } else { 368af57ed9fSAtsushi Murai pcomp = (struct compreq *)(cp + 2); 369af57ed9fSAtsushi Murai switch (length) { 370af57ed9fSAtsushi Murai case 4: /* RFC1172 */ 371af57ed9fSAtsushi Murai if (ntohs(pcomp->proto) == PROTO_VJCOMP) { 372af57ed9fSAtsushi Murai logprintf("** Peer is speaking RFC1172 compression protocol **\n"); 373af57ed9fSAtsushi Murai IpcpInfo.heis1172 = 1; 374af57ed9fSAtsushi Murai IpcpInfo.his_compproto = compproto; 375af57ed9fSAtsushi Murai bcopy(cp, ackp, length); 376af57ed9fSAtsushi Murai ackp += length; 377af57ed9fSAtsushi Murai } else { 378af57ed9fSAtsushi Murai bcopy(cp, nakp, 2); 379af57ed9fSAtsushi Murai pcomp->proto = htons(PROTO_VJCOMP); 380af57ed9fSAtsushi Murai bcopy(&pcomp, nakp + 2, 2); 381af57ed9fSAtsushi Murai nakp += length; 382af57ed9fSAtsushi Murai } 383af57ed9fSAtsushi Murai break; 384af57ed9fSAtsushi Murai case 6: /* RFC1332 */ 385af57ed9fSAtsushi Murai if (ntohs(pcomp->proto) == PROTO_VJCOMP 386af57ed9fSAtsushi Murai && pcomp->slots < MAX_STATES && pcomp->slots > 2) { 387af57ed9fSAtsushi Murai IpcpInfo.his_compproto = compproto; 388af57ed9fSAtsushi Murai IpcpInfo.heis1172 = 0; 389af57ed9fSAtsushi Murai bcopy(cp, ackp, length); 390af57ed9fSAtsushi Murai ackp += length; 391af57ed9fSAtsushi Murai } else { 392af57ed9fSAtsushi Murai bcopy(cp, nakp, 2); 393af57ed9fSAtsushi Murai pcomp->proto = htons(PROTO_VJCOMP); 394af57ed9fSAtsushi Murai pcomp->slots = MAX_STATES - 1; 395af57ed9fSAtsushi Murai pcomp->compcid = 0; 396af57ed9fSAtsushi Murai bcopy(&pcomp, nakp + 2, sizeof(pcomp)); 397af57ed9fSAtsushi Murai nakp += length; 398af57ed9fSAtsushi Murai } 399af57ed9fSAtsushi Murai break; 400af57ed9fSAtsushi Murai default: 401af57ed9fSAtsushi Murai bcopy(cp, rejp, length); 402af57ed9fSAtsushi Murai rejp += length; 403af57ed9fSAtsushi Murai break; 404af57ed9fSAtsushi Murai } 405af57ed9fSAtsushi Murai } 406af57ed9fSAtsushi Murai break; 407af57ed9fSAtsushi Murai case MODE_NAK: 408af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s changing compproto: %08x --> %08x\n", 409af57ed9fSAtsushi Murai tbuff, IpcpInfo.want_compproto, compproto); 410af57ed9fSAtsushi Murai IpcpInfo.want_compproto = compproto; 411af57ed9fSAtsushi Murai break; 412af57ed9fSAtsushi Murai case MODE_REJ: 413af57ed9fSAtsushi Murai IpcpInfo.his_reject |= (1 << type); 414af57ed9fSAtsushi Murai break; 415af57ed9fSAtsushi Murai } 416af57ed9fSAtsushi Murai break; 417af57ed9fSAtsushi Murai case TY_IPADDRS: /* RFC1172 */ 418af57ed9fSAtsushi Murai lp = (u_long *)(cp + 2); 419af57ed9fSAtsushi Murai ipaddr.s_addr = *lp; 420af57ed9fSAtsushi Murai lp = (u_long *)(cp + 6); 421af57ed9fSAtsushi Murai dstipaddr.s_addr = *lp; 422af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s %s, ", tbuff, inet_ntoa(ipaddr)); 423af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s\n", inet_ntoa(dstipaddr)); 424af57ed9fSAtsushi Murai 425af57ed9fSAtsushi Murai switch (mode) { 426af57ed9fSAtsushi Murai case MODE_REQ: 427af57ed9fSAtsushi Murai IpcpInfo.his_ipaddr = ipaddr; 428af57ed9fSAtsushi Murai IpcpInfo.want_ipaddr = dstipaddr; 429af57ed9fSAtsushi Murai bcopy(cp, ackp, length); 430af57ed9fSAtsushi Murai ackp += length; 431af57ed9fSAtsushi Murai break; 432af57ed9fSAtsushi Murai case MODE_NAK: 433af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "%s changing address: %s ", 434af57ed9fSAtsushi Murai tbuff, inet_ntoa(IpcpInfo.want_ipaddr)); 435af57ed9fSAtsushi Murai LogPrintf(LOG_LCP, "--> %s\n", inet_ntoa(ipaddr)); 436af57ed9fSAtsushi Murai IpcpInfo.want_ipaddr = ipaddr; 437af57ed9fSAtsushi Murai IpcpInfo.his_ipaddr = dstipaddr; 438af57ed9fSAtsushi Murai break; 439af57ed9fSAtsushi Murai case MODE_REJ: 440af57ed9fSAtsushi Murai IpcpInfo.his_reject |= (1 << type); 441af57ed9fSAtsushi Murai break; 442af57ed9fSAtsushi Murai } 443af57ed9fSAtsushi Murai break; 444af57ed9fSAtsushi Murai default: 445af57ed9fSAtsushi Murai IpcpInfo.my_reject |= (1 << type); 446af57ed9fSAtsushi Murai bcopy(cp, rejp, length); 447af57ed9fSAtsushi Murai rejp += length; 448af57ed9fSAtsushi Murai break; 449af57ed9fSAtsushi Murai } 450af57ed9fSAtsushi Murai plen -= length; 451af57ed9fSAtsushi Murai cp += length; 452af57ed9fSAtsushi Murai } 453af57ed9fSAtsushi Murai } 454af57ed9fSAtsushi Murai 455af57ed9fSAtsushi Murai void 456af57ed9fSAtsushi Murai IpcpInput(struct mbuf *bp) 457af57ed9fSAtsushi Murai { 458af57ed9fSAtsushi Murai FsmInput(&IpcpFsm, bp); 459af57ed9fSAtsushi Murai } 460