ipcp.c revision 31034
16059Samurai/* 26059Samurai * PPP IP Control Protocol (IPCP) Module 36059Samurai * 46059Samurai * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 56059Samurai * 66059Samurai * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 76059Samurai * 86059Samurai * Redistribution and use in source and binary forms are permitted 96059Samurai * provided that the above copyright notice and this paragraph are 106059Samurai * duplicated in all such forms and that any documentation, 116059Samurai * advertising materials, and other materials related to such 126059Samurai * distribution and use acknowledge that the software was developed 136059Samurai * by the Internet Initiative Japan, Inc. The name of the 146059Samurai * IIJ may not be used to endorse or promote products derived 156059Samurai * from this software without specific prior written permission. 166059Samurai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 176059Samurai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 186059Samurai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 196059Samurai * 2031034Sbrian * $Id: ipcp.c,v 1.33 1997/10/29 01:19:40 brian Exp $ 218857Srgrimes * 226059Samurai * TODO: 236059Samurai * o More RFC1772 backwoard compatibility 246059Samurai */ 2530715Sbrian#include <sys/param.h> 266059Samurai#include <netinet/in_systm.h> 2729048Sbrian#include <netinet/in.h> 286059Samurai#include <netinet/ip.h> 296059Samurai#include <arpa/inet.h> 306059Samurai#include <sys/socket.h> 3130715Sbrian#include <netdb.h> 3230715Sbrian 3329048Sbrian#include <limits.h> 3430715Sbrian#include <stdio.h> 3530715Sbrian#include <string.h> 3630715Sbrian#include <unistd.h> 3730715Sbrian 3830715Sbrian#include "mbuf.h" 3930715Sbrian#include "log.h" 4030715Sbrian#include "defs.h" 4130715Sbrian#include "timer.h" 4229048Sbrian#include "fsm.h" 4329048Sbrian#include "lcpproto.h" 4429048Sbrian#include "lcp.h" 4529048Sbrian#include "ipcp.h" 466059Samurai#include "slcompress.h" 476059Samurai#include "os.h" 486059Samurai#include "phase.h" 4926142Sbrian#include "loadalias.h" 5030715Sbrian#include "command.h" 516059Samurai#include "vars.h" 5230715Sbrian#include "vjcomp.h" 5330733Sbrian#include "ip.h" 546059Samurai 5530715Sbrian#ifndef NOMSEXT 5630715Sbrianstruct in_addr ns_entries[2]; 5730715Sbrianstruct in_addr nbns_entries[2]; 5830715Sbrian#endif 596059Samurai 606059Samuraistruct ipcpstate IpcpInfo; 6130715Sbrianstruct in_range DefMyAddress; 6230715Sbrianstruct in_range DefHisAddress; 6330715Sbrianstruct in_addr TriggerAddress; 6428394Sbrianint HaveTriggerAddress; 6530715Sbrianstruct pppTimer IpcpReportTimer; 666059Samurai 6726516Sbrianstatic void IpcpSendConfigReq(struct fsm *); 6826516Sbrianstatic void IpcpSendTerminateAck(struct fsm *); 6926516Sbrianstatic void IpcpSendTerminateReq(struct fsm *); 7026516Sbrianstatic void IpcpDecodeConfig(u_char *, int, int); 7126516Sbrianstatic void IpcpLayerStart(struct fsm *); 7226516Sbrianstatic void IpcpLayerFinish(struct fsm *); 7326516Sbrianstatic void IpcpLayerUp(struct fsm *); 7426516Sbrianstatic void IpcpLayerDown(struct fsm *); 7526516Sbrianstatic void IpcpInitRestartCounter(struct fsm *); 7630715Sbrianstatic int IpcpOctetsIn(void); 7730715Sbrianstatic int IpcpOctetsOut(void); 786059Samurai 796059Samuraistatic int lastInOctets, lastOutOctets; 8029048Sbrianstatic int StartingIpIn, StartingIpOut; 816059Samurai 826059Samurai#define REJECTED(p, x) (p->his_reject & (1<<x)) 836059Samurai 846059Samuraistruct fsm IpcpFsm = { 856059Samurai "IPCP", 866059Samurai PROTO_IPCP, 876059Samurai IPCP_MAXCODE, 886059Samurai OPEN_ACTIVE, 896059Samurai ST_INITIAL, 906059Samurai 0, 0, 0, 916059Samurai 926059Samurai 0, 9328679Sbrian {0, 0, 0, NULL, NULL, NULL}, 9428679Sbrian {0, 0, 0, NULL, NULL, NULL}, 9528461Sbrian LogIPCP, 966059Samurai 976059Samurai IpcpLayerUp, 986059Samurai IpcpLayerDown, 996059Samurai IpcpLayerStart, 1006059Samurai IpcpLayerFinish, 1016059Samurai IpcpInitRestartCounter, 1026059Samurai IpcpSendConfigReq, 1036059Samurai IpcpSendTerminateReq, 1046059Samurai IpcpSendTerminateAck, 1056059Samurai IpcpDecodeConfig, 1066059Samurai}; 1076059Samurai 1086059Samuraistatic char *cftypes[] = { 1096059Samurai "???", "IPADDRS", "COMPPROTO", "IPADDR", 1106059Samurai}; 1116059Samurai 1126059Samurai/* 1136059Samurai * Function called every second. Updates connection period and idle period, 1146059Samurai * also update LQR information. 1156059Samurai */ 1166059Samuraistatic void 1176059SamuraiIpcpReportFunc() 1186059Samurai{ 1196059Samurai ipConnectSecs++; 1206059Samurai if (lastInOctets == ipInOctets && lastOutOctets == ipOutOctets) 1216059Samurai ipIdleSecs++; 1226059Samurai lastInOctets = ipInOctets; 1236059Samurai lastOutOctets = ipOutOctets; 1246059Samurai StopTimer(&IpcpReportTimer); 1256059Samurai IpcpReportTimer.state = TIMER_STOPPED; 1266059Samurai StartTimer(&IpcpReportTimer); 1276059Samurai} 1286059Samurai 1296059Samuraistatic void 1306059SamuraiIpcpStartReport() 1316059Samurai{ 1326059Samurai ipIdleSecs = ipConnectSecs = 0; 1336059Samurai StopTimer(&IpcpReportTimer); 1346059Samurai IpcpReportTimer.state = TIMER_STOPPED; 1356059Samurai IpcpReportTimer.load = SECTICKS; 1366059Samurai IpcpReportTimer.func = IpcpReportFunc; 1376059Samurai StartTimer(&IpcpReportTimer); 1386059Samurai} 1396059Samurai 14025630Sbrianint 1416059SamuraiReportIpcpStatus() 1426059Samurai{ 1436059Samurai struct ipcpstate *icp = &IpcpInfo; 1446059Samurai struct fsm *fp = &IpcpFsm; 1456059Samurai 14626516Sbrian if (!VarTerm) 14726516Sbrian return 1; 14826516Sbrian fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]); 14926516Sbrian fprintf(VarTerm, " his side: %s, %lx\n", 15028679Sbrian inet_ntoa(icp->his_ipaddr), icp->his_compproto); 15126516Sbrian fprintf(VarTerm, " my side: %s, %lx\n", 15228679Sbrian inet_ntoa(icp->want_ipaddr), icp->want_compproto); 15329048Sbrian fprintf(VarTerm, "Connected: %d secs, idle: %d secs\n\n", 15429048Sbrian ipConnectSecs, ipIdleSecs); 15529048Sbrian fprintf(VarTerm, " %d octets in, %d octets out\n", 15629048Sbrian IpcpOctetsIn(), IpcpOctetsOut()); 15729048Sbrian 15826516Sbrian fprintf(VarTerm, "Defaults:\n"); 15926516Sbrian fprintf(VarTerm, " My Address: %s/%d\n", 16028679Sbrian inet_ntoa(DefMyAddress.ipaddr), DefMyAddress.width); 16126516Sbrian fprintf(VarTerm, " His Address: %s/%d\n", 16228679Sbrian inet_ntoa(DefHisAddress.ipaddr), DefHisAddress.width); 16328394Sbrian if (HaveTriggerAddress) 16428679Sbrian fprintf(VarTerm, " Negotiation(trigger): %s\n", inet_ntoa(TriggerAddress)); 16528394Sbrian else 16628679Sbrian fprintf(VarTerm, " Negotiation(trigger): MYADDR\n"); 16726516Sbrian 16826516Sbrian return 0; 1696059Samurai} 1706059Samurai 1716059Samuraivoid 1726059SamuraiIpcpDefAddress() 1736059Samurai{ 1746059Samurai struct hostent *hp; 1756059Samurai char name[200]; 1766059Samurai 17730715Sbrian memset(&DefMyAddress, '\0', sizeof(DefMyAddress)); 17830715Sbrian memset(&DefHisAddress, '\0', sizeof(DefHisAddress)); 17928394Sbrian TriggerAddress.s_addr = 0; 18028394Sbrian HaveTriggerAddress = 0; 1816059Samurai if (gethostname(name, sizeof(name)) == 0) { 18228679Sbrian hp = gethostbyname(name); 18328679Sbrian if (hp && hp->h_addrtype == AF_INET) { 18430715Sbrian memcpy(&DefMyAddress.ipaddr.s_addr, hp->h_addr, hp->h_length); 18528679Sbrian } 1866059Samurai } 1876059Samurai} 1886059Samurai 1896059Samuraivoid 1906059SamuraiIpcpInit() 1916059Samurai{ 1926059Samurai struct ipcpstate *icp = &IpcpInfo; 1936059Samurai 1946059Samurai FsmInit(&IpcpFsm); 19530715Sbrian memset(icp, '\0', sizeof(struct ipcpstate)); 1966059Samurai if ((mode & MODE_DEDICATED) && !dstsystem) { 1976059Samurai icp->want_ipaddr.s_addr = icp->his_ipaddr.s_addr = 0; 1986059Samurai } else { 1996059Samurai icp->want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr; 2006059Samurai icp->his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr; 2016059Samurai } 2029440Samurai 2039440Samurai /* 20429048Sbrian * Some implementations of PPP require that we send a 20529048Sbrian * *special* value as our address, even though the rfc specifies 20629048Sbrian * full negotiation (e.g. "0.0.0.0" or Not "0.0.0.0"). 2079440Samurai */ 20828394Sbrian if (HaveTriggerAddress) { 20928394Sbrian icp->want_ipaddr.s_addr = TriggerAddress.s_addr; 21028461Sbrian LogPrintf(LogIPCP, "Using trigger address %s\n", inet_ntoa(TriggerAddress)); 2119440Samurai } 2126059Samurai if (Enabled(ConfVjcomp)) 21330500Sbrian icp->want_compproto = (PROTO_VJCOMP << 16) | ((MAX_STATES - 1) << 8) | 1; 2146059Samurai else 2156059Samurai icp->want_compproto = 0; 2166059Samurai icp->heis1172 = 0; 2176059Samurai IpcpFsm.maxconfig = 10; 21829048Sbrian StartingIpIn = ipInOctets; 21929048Sbrian StartingIpOut = ipOutOctets; 2206059Samurai} 2216059Samurai 2226059Samuraistatic void 22328679SbrianIpcpInitRestartCounter(struct fsm * fp) 2246059Samurai{ 2256735Samurai fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 2266059Samurai fp->restart = 5; 2276059Samurai} 2286059Samurai 2296059Samuraistatic void 23028679SbrianIpcpSendConfigReq(struct fsm * fp) 2316059Samurai{ 2326059Samurai u_char *cp; 2336059Samurai struct ipcpstate *icp = &IpcpInfo; 2346059Samurai 2356059Samurai cp = ReqBuff; 23628461Sbrian LogPrintf(LogIPCP, "IpcpSendConfigReq\n"); 2376735Samurai if (!DEV_IS_SYNC || !REJECTED(icp, TY_IPADDR)) 2386735Samurai PutConfValue(&cp, cftypes, TY_IPADDR, 6, ntohl(icp->want_ipaddr.s_addr)); 2396059Samurai if (icp->want_compproto && !REJECTED(icp, TY_COMPPROTO)) { 2406059Samurai if (icp->heis1172) 2416059Samurai PutConfValue(&cp, cftypes, TY_COMPPROTO, 4, icp->want_compproto >> 16); 2426059Samurai else 2436059Samurai PutConfValue(&cp, cftypes, TY_COMPPROTO, 6, icp->want_compproto); 2446059Samurai } 2456059Samurai FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 2466059Samurai} 2476059Samurai 2486059Samuraistatic void 24928679SbrianIpcpSendTerminateReq(struct fsm * fp) 2506059Samurai{ 2516059Samurai /* XXX: No code yet */ 2526059Samurai} 2536059Samurai 2546059Samuraistatic void 25528679SbrianIpcpSendTerminateAck(struct fsm * fp) 2566059Samurai{ 25728461Sbrian LogPrintf(LogIPCP, "IpcpSendTerminateAck\n"); 2586059Samurai FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 2596059Samurai} 2606059Samurai 2616059Samuraistatic void 26228679SbrianIpcpLayerStart(struct fsm * fp) 2636059Samurai{ 26428461Sbrian LogPrintf(LogIPCP, "IpcpLayerStart.\n"); 2656059Samurai} 2666059Samurai 2676059Samuraistatic void 26828679SbrianIpcpLayerFinish(struct fsm * fp) 2696059Samurai{ 27028461Sbrian LogPrintf(LogIPCP, "IpcpLayerFinish.\n"); 27126098Sbrian reconnect(RECON_FALSE); 2726059Samurai LcpClose(); 2736059Samurai NewPhase(PHASE_TERMINATE); 2746059Samurai} 2756059Samurai 27630715Sbrianstatic int 27729048SbrianIpcpOctetsIn() 27829048Sbrian{ 27929048Sbrian return ipInOctets < StartingIpIn ? 28029048Sbrian INT_MAX - StartingIpIn + ipInOctets - INT_MIN + 1 : 28129048Sbrian ipInOctets - StartingIpIn; 28229048Sbrian} 28329048Sbrian 28430715Sbrianstatic int 28529048SbrianIpcpOctetsOut() 28629048Sbrian{ 28729048Sbrian return ipOutOctets < StartingIpOut ? 28829048Sbrian INT_MAX - StartingIpOut + ipOutOctets - INT_MIN + 1 : 28929048Sbrian ipOutOctets - StartingIpOut; 29029048Sbrian} 29129048Sbrian 2926059Samuraistatic void 29328679SbrianIpcpLayerDown(struct fsm * fp) 2946059Samurai{ 29528461Sbrian LogPrintf(LogIPCP, "IpcpLayerDown.\n"); 29629048Sbrian LogPrintf(LogIPCP, "%d octets in, %d octets out\n", 29729048Sbrian IpcpOctetsIn(), IpcpOctetsOut()); 2986059Samurai StopTimer(&IpcpReportTimer); 29930825Sbrian Prompt(); 3006059Samurai} 3016059Samurai 3026059Samurai/* 3036059Samurai * Called when IPCP has reached to OPEN state 3046059Samurai */ 3056059Samuraistatic void 30628679SbrianIpcpLayerUp(struct fsm * fp) 3076059Samurai{ 3086059Samurai char tbuff[100]; 3096059Samurai 31025630Sbrian Prompt(); 31128461Sbrian LogPrintf(LogIPCP, "IpcpLayerUp(%d).\n", fp->state); 31228679Sbrian snprintf(tbuff, sizeof(tbuff), "myaddr = %s ", 31328679Sbrian inet_ntoa(IpcpInfo.want_ipaddr)); 31430187Sbrian 31530187Sbrian if (IpcpInfo.his_compproto >> 16 == PROTO_VJCOMP) 31630187Sbrian VjInit((IpcpInfo.his_compproto >> 8) & 255); 31730187Sbrian 31828461Sbrian LogPrintf(LogIsKept(LogIPCP) ? LogIPCP : LogLINK, " %s hisaddr = %s\n", 31928679Sbrian tbuff, inet_ntoa(IpcpInfo.his_ipaddr)); 32025630Sbrian if (OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr, ifnetmask) < 0) { 32126516Sbrian if (VarTerm) 32226516Sbrian LogPrintf(LogERROR, "IpcpLayerUp: unable to set ip address\n"); 32326516Sbrian return; 32425630Sbrian } 32527763Sbrian if (mode & MODE_ALIAS) 32628679Sbrian VarPacketAliasSetAddress(IpcpInfo.want_ipaddr); 3276059Samurai OsLinkup(); 32829048Sbrian StartingIpIn = ipInOctets; 32929048Sbrian StartingIpOut = ipOutOctets; 3306059Samurai IpcpStartReport(); 3316059Samurai StartIdleTimer(); 3326059Samurai} 3336059Samurai 3346059Samuraivoid 3356059SamuraiIpcpUp() 3366059Samurai{ 3376059Samurai FsmUp(&IpcpFsm); 33828461Sbrian LogPrintf(LogIPCP, "IPCP Up event!!\n"); 3396059Samurai} 3406059Samurai 3416059Samuraivoid 3426059SamuraiIpcpOpen() 3436059Samurai{ 3446059Samurai FsmOpen(&IpcpFsm); 3456059Samurai} 3466059Samurai 3476059Samuraistatic int 34828679SbrianAcceptableAddr(struct in_range * prange, struct in_addr ipaddr) 3496059Samurai{ 35028974Sbrian LogPrintf(LogDEBUG, "requested = %x\n", htonl(ipaddr.s_addr)); 35128974Sbrian LogPrintf(LogDEBUG, "range = %x\n", htonl(prange->ipaddr.s_addr)); 35226516Sbrian LogPrintf(LogDEBUG, "/%x\n", htonl(prange->mask.s_addr)); 35326516Sbrian LogPrintf(LogDEBUG, "%x, %x\n", htonl(prange->ipaddr.s_addr & prange-> 35428679Sbrian mask.s_addr), htonl(ipaddr.s_addr & prange->mask.s_addr)); 35525661Sbrian return (prange->ipaddr.s_addr & prange->mask.s_addr) == 35628679Sbrian (ipaddr.s_addr & prange->mask.s_addr) && ipaddr.s_addr; 3576059Samurai} 3586059Samurai 3596059Samuraistatic void 36031034SbrianIpcpDecodeConfig(u_char * cp, int plen, int mode_type) 3616059Samurai{ 3626735Samurai int type, length; 3636059Samurai u_long *lp, compproto; 3646059Samurai struct compreq *pcomp; 36518752Sjkh struct in_addr ipaddr, dstipaddr, dnsstuff, ms_info_req; 3666059Samurai char tbuff[100]; 36721488Simp char tbuff2[100]; 3686059Samurai 3696059Samurai ackp = AckBuff; 3706059Samurai nakp = NakBuff; 3716059Samurai rejp = RejBuff; 3726059Samurai 3736059Samurai while (plen >= sizeof(struct fsmconfig)) { 3746059Samurai type = *cp; 3756059Samurai length = cp[1]; 3766059Samurai if (type <= TY_IPADDR) 37721488Simp snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); 3786059Samurai else 37921488Simp snprintf(tbuff, sizeof(tbuff), " "); 3806059Samurai 3816059Samurai switch (type) { 3826059Samurai case TY_IPADDR: /* RFC1332 */ 38328679Sbrian lp = (u_long *) (cp + 2); 3846059Samurai ipaddr.s_addr = *lp; 38528461Sbrian LogPrintf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 3866059Samurai 38731034Sbrian switch (mode_type) { 3886059Samurai case MODE_REQ: 3896059Samurai if (!AcceptableAddr(&DefHisAddress, ipaddr)) { 39028679Sbrian /* 39128679Sbrian * If destination address is not acceptable, insist to use what we 39228679Sbrian * want to use. 39328679Sbrian */ 39430715Sbrian memcpy(nakp, cp, 2); 39530715Sbrian memcpy(nakp+2, &IpcpInfo.his_ipaddr.s_addr, length); 39628679Sbrian nakp += length; 39728679Sbrian break; 3986059Samurai } 3996059Samurai IpcpInfo.his_ipaddr = ipaddr; 40030715Sbrian memcpy(ackp, cp, length); 4016059Samurai ackp += length; 4026059Samurai break; 4036059Samurai case MODE_NAK: 4046059Samurai if (AcceptableAddr(&DefMyAddress, ipaddr)) { 40528679Sbrian 40628679Sbrian /* 40728679Sbrian * Use address suggested by peer. 40828679Sbrian */ 40928974Sbrian snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s ", tbuff, 41028974Sbrian inet_ntoa(IpcpInfo.want_ipaddr)); 41128461Sbrian LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 4126059Samurai IpcpInfo.want_ipaddr = ipaddr; 4136059Samurai } 4146059Samurai break; 4156059Samurai case MODE_REJ: 4166059Samurai IpcpInfo.his_reject |= (1 << type); 4176059Samurai break; 4186059Samurai } 4196059Samurai break; 4206059Samurai case TY_COMPPROTO: 42128679Sbrian lp = (u_long *) (cp + 2); 4226059Samurai compproto = htonl(*lp); 42328461Sbrian LogPrintf(LogIPCP, "%s %08x\n", tbuff, compproto); 4246059Samurai 42531034Sbrian switch (mode_type) { 4266059Samurai case MODE_REQ: 4276059Samurai if (!Acceptable(ConfVjcomp)) { 42830715Sbrian memcpy(rejp, cp, length); 4296059Samurai rejp += length; 4306059Samurai } else { 43128679Sbrian pcomp = (struct compreq *) (cp + 2); 4326059Samurai switch (length) { 43328679Sbrian case 4: /* RFC1172 */ 4346059Samurai if (ntohs(pcomp->proto) == PROTO_VJCOMP) { 43526940Sbrian LogPrintf(LogWARN, "Peer is speaking RFC1172 compression protocol !\n"); 4366059Samurai IpcpInfo.heis1172 = 1; 4376059Samurai IpcpInfo.his_compproto = compproto; 43830715Sbrian memcpy(ackp, cp, length); 4396059Samurai ackp += length; 4406059Samurai } else { 44130715Sbrian memcpy(nakp, cp, 2); 4426059Samurai pcomp->proto = htons(PROTO_VJCOMP); 44330715Sbrian memcpy(nakp+2, &pcomp, 2); 4446059Samurai nakp += length; 4456059Samurai } 4466059Samurai break; 44728679Sbrian case 6: /* RFC1332 */ 4486059Samurai if (ntohs(pcomp->proto) == PROTO_VJCOMP 44928679Sbrian && pcomp->slots < MAX_STATES && pcomp->slots > 2) { 4506059Samurai IpcpInfo.his_compproto = compproto; 4516059Samurai IpcpInfo.heis1172 = 0; 45230715Sbrian memcpy(ackp, cp, length); 4536059Samurai ackp += length; 4546059Samurai } else { 45530715Sbrian memcpy(nakp, cp, 2); 4566059Samurai pcomp->proto = htons(PROTO_VJCOMP); 4576059Samurai pcomp->slots = MAX_STATES - 1; 4586059Samurai pcomp->compcid = 0; 45930715Sbrian memcpy(nakp+2, &pcomp, sizeof(pcomp)); 4606059Samurai nakp += length; 4616059Samurai } 4626059Samurai break; 4636059Samurai default: 46430715Sbrian memcpy(rejp, cp, length); 4656059Samurai rejp += length; 4666059Samurai break; 4676059Samurai } 4686059Samurai } 4696059Samurai break; 4706059Samurai case MODE_NAK: 47128461Sbrian LogPrintf(LogIPCP, "%s changing compproto: %08x --> %08x\n", 47228679Sbrian tbuff, IpcpInfo.want_compproto, compproto); 4736059Samurai IpcpInfo.want_compproto = compproto; 4746059Samurai break; 4756059Samurai case MODE_REJ: 4766059Samurai IpcpInfo.his_reject |= (1 << type); 4776059Samurai break; 4786059Samurai } 4796059Samurai break; 48028679Sbrian case TY_IPADDRS: /* RFC1172 */ 48128679Sbrian lp = (u_long *) (cp + 2); 4826059Samurai ipaddr.s_addr = *lp; 48328679Sbrian lp = (u_long *) (cp + 6); 4846059Samurai dstipaddr.s_addr = *lp; 48528974Sbrian snprintf(tbuff2, sizeof(tbuff2), "%s %s,", tbuff, inet_ntoa(ipaddr)); 48628974Sbrian LogPrintf(LogIPCP, "%s %s\n", tbuff2, inet_ntoa(dstipaddr)); 4876059Samurai 48831034Sbrian switch (mode_type) { 4896059Samurai case MODE_REQ: 4906059Samurai IpcpInfo.his_ipaddr = ipaddr; 4916059Samurai IpcpInfo.want_ipaddr = dstipaddr; 49230715Sbrian memcpy(ackp, cp, length); 4936059Samurai ackp += length; 4946059Samurai break; 4956059Samurai case MODE_NAK: 49628974Sbrian snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s", tbuff, 49728974Sbrian inet_ntoa(IpcpInfo.want_ipaddr)); 49828974Sbrian LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 4996059Samurai IpcpInfo.want_ipaddr = ipaddr; 5006059Samurai IpcpInfo.his_ipaddr = dstipaddr; 5016059Samurai break; 5026059Samurai case MODE_REJ: 5036059Samurai IpcpInfo.his_reject |= (1 << type); 5046059Samurai break; 5056059Samurai } 5066059Samurai break; 50718752Sjkh 50828679Sbrian /* 50928679Sbrian * MS extensions for MS's PPP 51028679Sbrian */ 51118752Sjkh 51226516Sbrian#ifndef NOMSEXT 51328679Sbrian case TY_PRIMARY_DNS: /* MS PPP DNS negotiation hack */ 51418752Sjkh case TY_SECONDARY_DNS: 51528679Sbrian if (!Enabled(ConfMSExt)) { 51628461Sbrian LogPrintf(LogIPCP, "MS NS req - rejected - msext disabled\n"); 51728679Sbrian IpcpInfo.my_reject |= (1 << type); 51830715Sbrian memcpy(rejp, cp, length); 51918752Sjkh rejp += length; 52018752Sjkh break; 52118752Sjkh } 52231034Sbrian switch (mode_type) { 52318752Sjkh case MODE_REQ: 52428679Sbrian lp = (u_long *) (cp + 2); 52518752Sjkh dnsstuff.s_addr = *lp; 52628679Sbrian ms_info_req.s_addr = ns_entries[((type - TY_PRIMARY_DNS) ? 1 : 0)].s_addr; 52728679Sbrian if (dnsstuff.s_addr != ms_info_req.s_addr) { 52828679Sbrian 52918752Sjkh /* 53028679Sbrian * So the client has got the DNS stuff wrong (first request) so 53128974Sbrian * we'll tell 'em how it is 53228679Sbrian */ 53330715Sbrian memcpy(nakp, cp, 2); /* copy first two (type/length) */ 53428679Sbrian LogPrintf(LogIPCP, "MS NS req %d:%s->%s - nak\n", 53528679Sbrian type, 53628679Sbrian inet_ntoa(dnsstuff), 53728679Sbrian inet_ntoa(ms_info_req)); 53830715Sbrian memcpy(nakp+2, &ms_info_req, length); 53918752Sjkh nakp += length; 54018752Sjkh break; 54118752Sjkh } 54228679Sbrian 54328679Sbrian /* 54428679Sbrian * Otherwise they have it right (this time) so we send a ack packet 54528679Sbrian * back confirming it... end of story 54628679Sbrian */ 54728679Sbrian LogPrintf(LogIPCP, "MS NS req %d:%s ok - ack\n", 54828679Sbrian type, 54928679Sbrian inet_ntoa(ms_info_req)); 55030715Sbrian memcpy(ackp, cp, length); 55118752Sjkh ackp += length; 55218752Sjkh break; 55328679Sbrian case MODE_NAK: /* what does this mean?? */ 55428679Sbrian LogPrintf(LogIPCP, "MS NS req %d - NAK??\n", type); 55518752Sjkh break; 55628679Sbrian case MODE_REJ: /* confused?? me to :) */ 55728679Sbrian LogPrintf(LogIPCP, "MS NS req %d - REJ??\n", type); 55818752Sjkh break; 55918752Sjkh } 56018752Sjkh break; 56118752Sjkh 56228679Sbrian case TY_PRIMARY_NBNS: /* MS PPP NetBIOS nameserver hack */ 56318752Sjkh case TY_SECONDARY_NBNS: 56428679Sbrian if (!Enabled(ConfMSExt)) { 56528679Sbrian LogPrintf(LogIPCP, "MS NBNS req - rejected - msext disabled\n"); 56628679Sbrian IpcpInfo.my_reject |= (1 << type); 56730715Sbrian memcpy(rejp, cp, length); 56828679Sbrian rejp += length; 56928679Sbrian break; 57028679Sbrian } 57131034Sbrian switch (mode_type) { 57218752Sjkh case MODE_REQ: 57328679Sbrian lp = (u_long *) (cp + 2); 57418752Sjkh dnsstuff.s_addr = *lp; 57528679Sbrian ms_info_req.s_addr = nbns_entries[((type - TY_PRIMARY_NBNS) ? 1 : 0)].s_addr; 57628679Sbrian if (dnsstuff.s_addr != ms_info_req.s_addr) { 57730715Sbrian memcpy(nakp, cp, 2); 57830715Sbrian memcpy(nakp+2, &ms_info_req.s_addr, length); 57928461Sbrian LogPrintf(LogIPCP, "MS NBNS req %d:%s->%s - nak\n", 58028679Sbrian type, 58128679Sbrian inet_ntoa(dnsstuff), 58228679Sbrian inet_ntoa(ms_info_req)); 58318752Sjkh nakp += length; 58418752Sjkh break; 58518752Sjkh } 58628461Sbrian LogPrintf(LogIPCP, "MS NBNS req %d:%s ok - ack\n", 58728679Sbrian type, 58828679Sbrian inet_ntoa(ms_info_req)); 58930715Sbrian memcpy(ackp, cp, length); 59018752Sjkh ackp += length; 59118752Sjkh break; 59218752Sjkh case MODE_NAK: 59328679Sbrian LogPrintf(LogIPCP, "MS NBNS req %d - NAK??\n", type); 59418752Sjkh break; 59518752Sjkh case MODE_REJ: 59628679Sbrian LogPrintf(LogIPCP, "MS NBNS req %d - REJ??\n", type); 59718752Sjkh break; 59818752Sjkh } 59918752Sjkh break; 60018752Sjkh 60126516Sbrian#endif 60218752Sjkh 6036059Samurai default: 6046059Samurai IpcpInfo.my_reject |= (1 << type); 60530715Sbrian memcpy(rejp, cp, length); 6066059Samurai rejp += length; 6076059Samurai break; 6086059Samurai } 6096059Samurai plen -= length; 6106059Samurai cp += length; 6116059Samurai } 6126059Samurai} 6136059Samurai 6146059Samuraivoid 61528679SbrianIpcpInput(struct mbuf * bp) 6166059Samurai{ 6176059Samurai FsmInput(&IpcpFsm, bp); 6186059Samurai} 619