ipcp.c revision 28461
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 * 2028461Sbrian * $Id: ipcp.c,v 1.24 1997/08/19 01:10:20 brian Exp $ 218857Srgrimes * 226059Samurai * TODO: 236059Samurai * o More RFC1772 backwoard compatibility 246059Samurai */ 256059Samurai#include "fsm.h" 266059Samurai#include "lcpproto.h" 276059Samurai#include "lcp.h" 286059Samurai#include "ipcp.h" 296059Samurai#include <netdb.h> 306059Samurai#include <netinet/in_systm.h> 316059Samurai#include <netinet/ip.h> 326059Samurai#include <arpa/inet.h> 336059Samurai#include <sys/socket.h> 346059Samurai#include "slcompress.h" 356059Samurai#include "os.h" 366059Samurai#include "phase.h" 3726142Sbrian#include "loadalias.h" 386059Samurai#include "vars.h" 396059Samurai 406059Samuraiextern void PutConfValue(); 416059Samuraiextern void Prompt(); 426059Samuraiextern struct in_addr ifnetmask; 436059Samurai 446059Samuraistruct ipcpstate IpcpInfo; 4528394Sbrianstruct in_range DefMyAddress, DefHisAddress; 4628394Sbrianstruct in_addr TriggerAddress; 4728394Sbrianint HaveTriggerAddress; 486059Samurai 4926516Sbrian#ifndef NOMSEXT 5018752Sjkhstruct in_addr ns_entries[2], nbns_entries[2]; 5126516Sbrian#endif 5218752Sjkh 5326516Sbrianstatic void IpcpSendConfigReq(struct fsm *); 5426516Sbrianstatic void IpcpSendTerminateAck(struct fsm *); 5526516Sbrianstatic void IpcpSendTerminateReq(struct fsm *); 5626516Sbrianstatic void IpcpDecodeConfig(u_char *, int, int); 5726516Sbrianstatic void IpcpLayerStart(struct fsm *); 5826516Sbrianstatic void IpcpLayerFinish(struct fsm *); 5926516Sbrianstatic void IpcpLayerUp(struct fsm *); 6026516Sbrianstatic void IpcpLayerDown(struct fsm *); 6126516Sbrianstatic void IpcpInitRestartCounter(struct fsm *); 626059Samurai 637001Samuraistruct pppTimer IpcpReportTimer; 646059Samurai 656059Samuraistatic int lastInOctets, lastOutOctets; 666059Samurai 676059Samurai#define REJECTED(p, x) (p->his_reject & (1<<x)) 686059Samurai 696059Samuraistruct fsm IpcpFsm = { 706059Samurai "IPCP", 716059Samurai PROTO_IPCP, 726059Samurai IPCP_MAXCODE, 736059Samurai OPEN_ACTIVE, 746059Samurai ST_INITIAL, 756059Samurai 0, 0, 0, 766059Samurai 776059Samurai 0, 786059Samurai { 0, 0, 0, NULL, NULL, NULL }, 7928461Sbrian { 0, 0, 0, NULL, NULL, NULL }, 8028461Sbrian LogIPCP, 816059Samurai 826059Samurai IpcpLayerUp, 836059Samurai IpcpLayerDown, 846059Samurai IpcpLayerStart, 856059Samurai IpcpLayerFinish, 866059Samurai IpcpInitRestartCounter, 876059Samurai IpcpSendConfigReq, 886059Samurai IpcpSendTerminateReq, 896059Samurai IpcpSendTerminateAck, 906059Samurai IpcpDecodeConfig, 916059Samurai}; 926059Samurai 936059Samuraistatic char *cftypes[] = { 946059Samurai "???", "IPADDRS", "COMPPROTO", "IPADDR", 956059Samurai}; 966059Samurai 976059Samurai/* 986059Samurai * Function called every second. Updates connection period and idle period, 996059Samurai * also update LQR information. 1006059Samurai */ 1016059Samuraistatic void 1026059SamuraiIpcpReportFunc() 1036059Samurai{ 1046059Samurai ipConnectSecs++; 1056059Samurai if (lastInOctets == ipInOctets && lastOutOctets == ipOutOctets) 1066059Samurai ipIdleSecs++; 1076059Samurai lastInOctets = ipInOctets; 1086059Samurai lastOutOctets = ipOutOctets; 1096059Samurai StopTimer(&IpcpReportTimer); 1106059Samurai IpcpReportTimer.state = TIMER_STOPPED; 1116059Samurai StartTimer(&IpcpReportTimer); 1126059Samurai} 1136059Samurai 1146059Samuraistatic void 1156059SamuraiIpcpStartReport() 1166059Samurai{ 1176059Samurai ipIdleSecs = ipConnectSecs = 0; 1186059Samurai StopTimer(&IpcpReportTimer); 1196059Samurai IpcpReportTimer.state = TIMER_STOPPED; 1206059Samurai IpcpReportTimer.load = SECTICKS; 1216059Samurai IpcpReportTimer.func = IpcpReportFunc; 1226059Samurai StartTimer(&IpcpReportTimer); 1236059Samurai} 1246059Samurai 12525630Sbrianint 1266059SamuraiReportIpcpStatus() 1276059Samurai{ 1286059Samurai struct ipcpstate *icp = &IpcpInfo; 1296059Samurai struct fsm *fp = &IpcpFsm; 1306059Samurai 13126516Sbrian if (!VarTerm) 13226516Sbrian return 1; 13326516Sbrian fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]); 13426516Sbrian fprintf(VarTerm, " his side: %s, %lx\n", 1356059Samurai inet_ntoa(icp->his_ipaddr), icp->his_compproto); 13626516Sbrian fprintf(VarTerm, " my side: %s, %lx\n", 1376059Samurai inet_ntoa(icp->want_ipaddr), icp->want_compproto); 13826516Sbrian fprintf(VarTerm, "connected: %d secs, idle: %d secs\n\n", ipConnectSecs, ipIdleSecs); 13926516Sbrian fprintf(VarTerm, "Defaults:\n"); 14026516Sbrian fprintf(VarTerm, " My Address: %s/%d\n", 1416059Samurai inet_ntoa(DefMyAddress.ipaddr), DefMyAddress.width); 14226516Sbrian fprintf(VarTerm, " His Address: %s/%d\n", 1436059Samurai inet_ntoa(DefHisAddress.ipaddr), DefHisAddress.width); 14428394Sbrian if (HaveTriggerAddress) 14528394Sbrian fprintf(VarTerm, " Negotiation(trigger): %s\n", inet_ntoa(TriggerAddress)); 14628394Sbrian else 14728394Sbrian fprintf(VarTerm, " Negotiation(trigger): MYADDR\n"); 14826516Sbrian 14926516Sbrian return 0; 1506059Samurai} 1516059Samurai 1526059Samuraivoid 1536059SamuraiIpcpDefAddress() 1546059Samurai{ 1556059Samurai struct hostent *hp; 1566059Samurai char name[200]; 1576059Samurai 1586059Samurai bzero(&DefMyAddress, sizeof(DefMyAddress)); 1596059Samurai bzero(&DefHisAddress, sizeof(DefHisAddress)); 16028394Sbrian TriggerAddress.s_addr = 0; 16128394Sbrian HaveTriggerAddress = 0; 1626059Samurai if (gethostname(name, sizeof(name)) == 0) { 1636059Samurai hp = gethostbyname(name); 1646059Samurai if (hp && hp->h_addrtype == AF_INET) { 1656059Samurai bcopy(hp->h_addr, (char *)&DefMyAddress.ipaddr.s_addr, hp->h_length); 1666059Samurai } 1676059Samurai } 1686059Samurai} 1696059Samurai 1706059Samuraivoid 1716059SamuraiIpcpInit() 1726059Samurai{ 1736059Samurai struct ipcpstate *icp = &IpcpInfo; 1746059Samurai 1756059Samurai FsmInit(&IpcpFsm); 1766059Samurai bzero(icp, sizeof(struct ipcpstate)); 1776059Samurai if ((mode & MODE_DEDICATED) && !dstsystem) { 1786059Samurai icp->want_ipaddr.s_addr = icp->his_ipaddr.s_addr = 0; 1796059Samurai } else { 1806059Samurai icp->want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr; 1816059Samurai icp->his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr; 1826059Samurai } 1839440Samurai 1849440Samurai /* 1859440Samurai * Some implementation of PPP are: 1869440Samurai * Starting a negotiaion by require sending *special* value as my address, 1879440Samurai * even though standard of PPP is defined full negotiation based. 1889440Samurai * (e.g. "0.0.0.0" or Not "0.0.0.0") 1899440Samurai */ 19028394Sbrian if (HaveTriggerAddress) { 19128394Sbrian icp->want_ipaddr.s_addr = TriggerAddress.s_addr; 19228461Sbrian LogPrintf(LogIPCP, "Using trigger address %s\n", inet_ntoa(TriggerAddress)); 1939440Samurai } 1949440Samurai 1956059Samurai if (Enabled(ConfVjcomp)) 1966059Samurai icp->want_compproto = (PROTO_VJCOMP << 16) | ((MAX_STATES - 1) << 8); 1976059Samurai else 1986059Samurai icp->want_compproto = 0; 1996059Samurai icp->heis1172 = 0; 2006059Samurai IpcpFsm.maxconfig = 10; 2016059Samurai} 2026059Samurai 2036059Samuraistatic void 2046059SamuraiIpcpInitRestartCounter(fp) 2056059Samuraistruct fsm *fp; 2066059Samurai{ 2076735Samurai fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 2086059Samurai fp->restart = 5; 2096059Samurai} 2106059Samurai 2116059Samuraistatic void 2126059SamuraiIpcpSendConfigReq(fp) 2136059Samuraistruct fsm *fp; 2146059Samurai{ 2156059Samurai u_char *cp; 2166059Samurai struct ipcpstate *icp = &IpcpInfo; 2176059Samurai 2186059Samurai cp = ReqBuff; 21928461Sbrian LogPrintf(LogIPCP, "IpcpSendConfigReq\n"); 2206735Samurai if (!DEV_IS_SYNC || !REJECTED(icp, TY_IPADDR)) 2216735Samurai PutConfValue(&cp, cftypes, TY_IPADDR, 6, ntohl(icp->want_ipaddr.s_addr)); 2226059Samurai if (icp->want_compproto && !REJECTED(icp, TY_COMPPROTO)) { 2236059Samurai if (icp->heis1172) 2246059Samurai PutConfValue(&cp, cftypes, TY_COMPPROTO, 4, icp->want_compproto >> 16); 2256059Samurai else 2266059Samurai PutConfValue(&cp, cftypes, TY_COMPPROTO, 6, icp->want_compproto); 2276059Samurai } 2286059Samurai FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 2296059Samurai} 2306059Samurai 2316059Samuraistatic void 2326059SamuraiIpcpSendTerminateReq(fp) 2336059Samuraistruct fsm *fp; 2346059Samurai{ 2356059Samurai /* XXX: No code yet */ 2366059Samurai} 2376059Samurai 2386059Samuraistatic void 2396059SamuraiIpcpSendTerminateAck(fp) 2406059Samuraistruct fsm *fp; 2416059Samurai{ 24228461Sbrian LogPrintf(LogIPCP, "IpcpSendTerminateAck\n"); 2436059Samurai FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 2446059Samurai} 2456059Samurai 2466059Samuraistatic void 2476059SamuraiIpcpLayerStart(fp) 2486059Samuraistruct fsm *fp; 2496059Samurai{ 25028461Sbrian LogPrintf(LogIPCP, "IpcpLayerStart.\n"); 2516059Samurai} 2526059Samurai 2536059Samuraistatic void 2546059SamuraiIpcpLayerFinish(fp) 2556059Samuraistruct fsm *fp; 2566059Samurai{ 25728461Sbrian LogPrintf(LogIPCP, "IpcpLayerFinish.\n"); 25826098Sbrian reconnect(RECON_FALSE); 2596059Samurai LcpClose(); 2606059Samurai NewPhase(PHASE_TERMINATE); 2616059Samurai} 2626059Samurai 2636059Samuraistatic void 2646059SamuraiIpcpLayerDown(fp) 2656059Samuraistruct fsm *fp; 2666059Samurai{ 26728461Sbrian LogPrintf(LogIPCP, "IpcpLayerDown.\n"); 2686059Samurai StopTimer(&IpcpReportTimer); 2696059Samurai} 2706059Samurai 2716059Samurai/* 2726059Samurai * Called when IPCP has reached to OPEN state 2736059Samurai */ 2746059Samuraistatic void 2756059SamuraiIpcpLayerUp(fp) 2766059Samuraistruct fsm *fp; 2776059Samurai{ 2786059Samurai char tbuff[100]; 2796059Samurai 28025630Sbrian Prompt(); 28128461Sbrian LogPrintf(LogIPCP, "IpcpLayerUp(%d).\n", fp->state); 28221488Simp snprintf(tbuff, sizeof(tbuff), "myaddr = %s ", 28321488Simp inet_ntoa(IpcpInfo.want_ipaddr)); 28428461Sbrian LogPrintf(LogIsKept(LogIPCP) ? LogIPCP : LogLINK, " %s hisaddr = %s\n", 28526516Sbrian tbuff, inet_ntoa(IpcpInfo.his_ipaddr)); 28625630Sbrian if (OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr, ifnetmask) < 0) { 28726516Sbrian if (VarTerm) 28826516Sbrian LogPrintf(LogERROR, "IpcpLayerUp: unable to set ip address\n"); 28926516Sbrian return; 29025630Sbrian } 29127763Sbrian if (mode & MODE_ALIAS) 29227763Sbrian VarSetPacketAliasAddress(IpcpInfo.want_ipaddr); 2936059Samurai OsLinkup(); 2946059Samurai IpcpStartReport(); 2956059Samurai StartIdleTimer(); 2966059Samurai} 2976059Samurai 2986059Samuraivoid 2996059SamuraiIpcpUp() 3006059Samurai{ 3016059Samurai FsmUp(&IpcpFsm); 30228461Sbrian LogPrintf(LogIPCP, "IPCP Up event!!\n"); 3036059Samurai} 3046059Samurai 3056059Samuraivoid 3066059SamuraiIpcpOpen() 3076059Samurai{ 3086059Samurai FsmOpen(&IpcpFsm); 3096059Samurai} 3106059Samurai 3116059Samuraistatic int 3126059SamuraiAcceptableAddr(prange, ipaddr) 3136059Samuraistruct in_range *prange; 3146059Samuraistruct in_addr ipaddr; 3156059Samurai{ 31626516Sbrian LogPrintf(LogDEBUG, "requested = %x ", htonl(ipaddr.s_addr)); 31726516Sbrian LogPrintf(LogDEBUG, "range = %x", htonl(prange->ipaddr.s_addr)); 31826516Sbrian LogPrintf(LogDEBUG, "/%x\n", htonl(prange->mask.s_addr)); 31926516Sbrian LogPrintf(LogDEBUG, "%x, %x\n", htonl(prange->ipaddr.s_addr & prange-> 32026516Sbrian mask.s_addr), htonl(ipaddr.s_addr & prange->mask.s_addr)); 32125661Sbrian return (prange->ipaddr.s_addr & prange->mask.s_addr) == 32225661Sbrian (ipaddr.s_addr & prange->mask.s_addr) && ipaddr.s_addr; 3236059Samurai} 3246059Samurai 3256059Samuraistatic void 3266735SamuraiIpcpDecodeConfig(cp, plen, mode) 3276735Samuraiu_char *cp; 3286735Samuraiint plen; 3296059Samuraiint mode; 3306059Samurai{ 3316735Samurai int type, length; 3326059Samurai u_long *lp, compproto; 3336059Samurai struct compreq *pcomp; 33418752Sjkh struct in_addr ipaddr, dstipaddr, dnsstuff, ms_info_req; 3356059Samurai char tbuff[100]; 33621488Simp char tbuff2[100]; 3376059Samurai 3386059Samurai ackp = AckBuff; 3396059Samurai nakp = NakBuff; 3406059Samurai rejp = RejBuff; 3416059Samurai 3426059Samurai while (plen >= sizeof(struct fsmconfig)) { 3436059Samurai if (plen < 0) 3446059Samurai break; 3456059Samurai type = *cp; 3466059Samurai length = cp[1]; 3476059Samurai if (type <= TY_IPADDR) 34821488Simp snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); 3496059Samurai else 35021488Simp snprintf(tbuff, sizeof(tbuff), " "); 3516059Samurai 3526059Samurai switch (type) { 3536059Samurai case TY_IPADDR: /* RFC1332 */ 3546059Samurai lp = (u_long *)(cp + 2); 3556059Samurai ipaddr.s_addr = *lp; 35628461Sbrian LogPrintf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 3576059Samurai 3586059Samurai switch (mode) { 3596059Samurai case MODE_REQ: 3606059Samurai if (!AcceptableAddr(&DefHisAddress, ipaddr)) { 3616059Samurai /* 3626059Samurai * If destination address is not acceptable, insist to use 3636059Samurai * what we want to use. 3646059Samurai */ 3656059Samurai bcopy(cp, nakp, 2); 3666059Samurai bcopy(&IpcpInfo.his_ipaddr.s_addr, nakp+2, length); 3676059Samurai nakp += length; 3686059Samurai break; 3698857Srgrimes 3706059Samurai } 3716059Samurai IpcpInfo.his_ipaddr = ipaddr; 3726059Samurai bcopy(cp, ackp, length); 3736059Samurai ackp += length; 3746059Samurai break; 3756059Samurai case MODE_NAK: 3766059Samurai if (AcceptableAddr(&DefMyAddress, ipaddr)) { 3776059Samurai /* 3786059Samurai * Use address suggested by peer. 3796059Samurai */ 38021488Simp snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s ", tbuff, inet_ntoa(IpcpInfo.want_ipaddr)); 38128461Sbrian LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 3826059Samurai IpcpInfo.want_ipaddr = ipaddr; 3836059Samurai } 3846059Samurai break; 3856059Samurai case MODE_REJ: 3866059Samurai IpcpInfo.his_reject |= (1 << type); 3876059Samurai break; 3886059Samurai } 3896059Samurai break; 3906059Samurai case TY_COMPPROTO: 3916059Samurai lp = (u_long *)(cp + 2); 3926059Samurai compproto = htonl(*lp); 39328461Sbrian LogPrintf(LogIPCP, "%s %08x\n", tbuff, compproto); 3946059Samurai 3956059Samurai switch (mode) { 3966059Samurai case MODE_REQ: 3976059Samurai if (!Acceptable(ConfVjcomp)) { 3986059Samurai bcopy(cp, rejp, length); 3996059Samurai rejp += length; 4006059Samurai } else { 4016059Samurai pcomp = (struct compreq *)(cp + 2); 4026059Samurai switch (length) { 4036059Samurai case 4: /* RFC1172 */ 4046059Samurai if (ntohs(pcomp->proto) == PROTO_VJCOMP) { 40526940Sbrian LogPrintf(LogWARN, "Peer is speaking RFC1172 compression protocol !\n"); 4066059Samurai IpcpInfo.heis1172 = 1; 4076059Samurai IpcpInfo.his_compproto = compproto; 4086059Samurai bcopy(cp, ackp, length); 4096059Samurai ackp += length; 4106059Samurai } else { 4116059Samurai bcopy(cp, nakp, 2); 4126059Samurai pcomp->proto = htons(PROTO_VJCOMP); 4136059Samurai bcopy(&pcomp, nakp + 2, 2); 4146059Samurai nakp += length; 4156059Samurai } 4166059Samurai break; 4176059Samurai case 6: /* RFC1332 */ 4186059Samurai if (ntohs(pcomp->proto) == PROTO_VJCOMP 4196059Samurai && pcomp->slots < MAX_STATES && pcomp->slots > 2) { 4206059Samurai IpcpInfo.his_compproto = compproto; 4216059Samurai IpcpInfo.heis1172 = 0; 4226059Samurai bcopy(cp, ackp, length); 4236059Samurai ackp += length; 4246059Samurai } else { 4256059Samurai bcopy(cp, nakp, 2); 4266059Samurai pcomp->proto = htons(PROTO_VJCOMP); 4276059Samurai pcomp->slots = MAX_STATES - 1; 4286059Samurai pcomp->compcid = 0; 4296059Samurai bcopy(&pcomp, nakp + 2, sizeof(pcomp)); 4306059Samurai nakp += length; 4316059Samurai } 4326059Samurai break; 4336059Samurai default: 4346059Samurai bcopy(cp, rejp, length); 4356059Samurai rejp += length; 4366059Samurai break; 4376059Samurai } 4386059Samurai } 4396059Samurai break; 4406059Samurai case MODE_NAK: 44128461Sbrian LogPrintf(LogIPCP, "%s changing compproto: %08x --> %08x\n", 4426059Samurai tbuff, IpcpInfo.want_compproto, compproto); 4436059Samurai IpcpInfo.want_compproto = compproto; 4446059Samurai break; 4456059Samurai case MODE_REJ: 4466059Samurai IpcpInfo.his_reject |= (1 << type); 4476059Samurai break; 4486059Samurai } 4496059Samurai break; 4506059Samurai case TY_IPADDRS: /* RFC1172 */ 4516059Samurai lp = (u_long *)(cp + 2); 4526059Samurai ipaddr.s_addr = *lp; 4536059Samurai lp = (u_long *)(cp + 6); 4546059Samurai dstipaddr.s_addr = *lp; 45528461Sbrian LogPrintf(LogIPCP, "%s %s, ", tbuff, inet_ntoa(ipaddr)); 45628461Sbrian LogPrintf(LogIPCP, "%s\n", inet_ntoa(dstipaddr)); 4576059Samurai 4586059Samurai switch (mode) { 4596059Samurai case MODE_REQ: 4606059Samurai IpcpInfo.his_ipaddr = ipaddr; 4616059Samurai IpcpInfo.want_ipaddr = dstipaddr; 4626059Samurai bcopy(cp, ackp, length); 4636059Samurai ackp += length; 4646059Samurai break; 4656059Samurai case MODE_NAK: 46628461Sbrian LogPrintf(LogIPCP, "%s changing address: %s ", 4676059Samurai tbuff, inet_ntoa(IpcpInfo.want_ipaddr)); 46828461Sbrian LogPrintf(LogIPCP, "--> %s\n", inet_ntoa(ipaddr)); 4696059Samurai IpcpInfo.want_ipaddr = ipaddr; 4706059Samurai IpcpInfo.his_ipaddr = dstipaddr; 4716059Samurai break; 4726059Samurai case MODE_REJ: 4736059Samurai IpcpInfo.his_reject |= (1 << type); 4746059Samurai break; 4756059Samurai } 4766059Samurai break; 47718752Sjkh 47818752Sjkh /* 47918752Sjkh * MS extensions for MS's PPP 48018752Sjkh */ 48118752Sjkh 48226516Sbrian#ifndef NOMSEXT 48318752Sjkh case TY_PRIMARY_DNS: /* MS PPP DNS negotiation hack */ 48418752Sjkh case TY_SECONDARY_DNS: 48518752Sjkh if( !Enabled( ConfMSExt ) ) { 48628461Sbrian LogPrintf(LogIPCP, "MS NS req - rejected - msext disabled\n"); 48718752Sjkh IpcpInfo.my_reject |= ( 1 << type ); 48818752Sjkh bcopy(cp, rejp, length); 48918752Sjkh rejp += length; 49018752Sjkh break; 49118752Sjkh } 49218752Sjkh switch( mode ){ 49318752Sjkh case MODE_REQ: 49418752Sjkh lp = (u_long *)(cp + 2); 49518752Sjkh dnsstuff.s_addr = *lp; 49618752Sjkh ms_info_req.s_addr = ns_entries[((type - TY_PRIMARY_DNS)?1:0)].s_addr; 49718752Sjkh if( dnsstuff.s_addr != ms_info_req.s_addr ) 49818752Sjkh { 49918752Sjkh /* 50018752Sjkh So the client has got the DNS stuff wrong (first request) 50118752Sjkh so well tell 'em how it is 50218752Sjkh */ 50318752Sjkh bcopy( cp, nakp, 2 ); /* copy first two (type/length) */ 50428461Sbrian LogPrintf( LogIPCP, "MS NS req %d:%s->%s - nak\n", 50518752Sjkh type, 50618752Sjkh inet_ntoa( dnsstuff ), 50718752Sjkh inet_ntoa( ms_info_req )); 50818752Sjkh bcopy( &ms_info_req, nakp+2, length ); 50918752Sjkh nakp += length; 51018752Sjkh break; 51118752Sjkh } 51218752Sjkh /* 51318752Sjkh Otherwise they have it right (this time) so we send 51418752Sjkh a ack packet back confirming it... end of story 51518752Sjkh */ 51628461Sbrian LogPrintf( LogIPCP, "MS NS req %d:%s ok - ack\n", 51718752Sjkh type, 51818752Sjkh inet_ntoa( ms_info_req )); 51918752Sjkh bcopy( cp, ackp, length ); 52018752Sjkh ackp += length; 52118752Sjkh break; 52218752Sjkh case MODE_NAK: /* what does this mean?? */ 52328461Sbrian LogPrintf(LogIPCP, "MS NS req %d - NAK??\n", type ); 52418752Sjkh break; 52518752Sjkh case MODE_REJ: /* confused?? me to :) */ 52628461Sbrian LogPrintf(LogIPCP, "MS NS req %d - REJ??\n", type ); 52718752Sjkh break; 52818752Sjkh } 52918752Sjkh break; 53018752Sjkh 53118752Sjkh case TY_PRIMARY_NBNS: /* MS PPP NetBIOS nameserver hack */ 53218752Sjkh case TY_SECONDARY_NBNS: 53318752Sjkh if( !Enabled( ConfMSExt ) ) { 53428461Sbrian LogPrintf( LogIPCP, "MS NBNS req - rejected - msext disabled\n" ); 53518752Sjkh IpcpInfo.my_reject |= ( 1 << type ); 53618752Sjkh bcopy( cp, rejp, length ); 53718752Sjkh rejp += length; 53818752Sjkh break; 53918752Sjkh } 54018752Sjkh switch( mode ){ 54118752Sjkh case MODE_REQ: 54218752Sjkh lp = (u_long *)(cp + 2); 54318752Sjkh dnsstuff.s_addr = *lp; 54418752Sjkh ms_info_req.s_addr = nbns_entries[((type - TY_PRIMARY_NBNS)?1:0)].s_addr; 54518752Sjkh if( dnsstuff.s_addr != ms_info_req.s_addr ) 54618752Sjkh { 54718752Sjkh bcopy( cp, nakp, 2 ); 54818752Sjkh bcopy( &ms_info_req.s_addr , nakp+2, length ); 54928461Sbrian LogPrintf(LogIPCP, "MS NBNS req %d:%s->%s - nak\n", 55018752Sjkh type, 55118752Sjkh inet_ntoa( dnsstuff ), 55218752Sjkh inet_ntoa( ms_info_req )); 55318752Sjkh nakp += length; 55418752Sjkh break; 55518752Sjkh } 55628461Sbrian LogPrintf(LogIPCP, "MS NBNS req %d:%s ok - ack\n", 55718752Sjkh type, 55818752Sjkh inet_ntoa( ms_info_req )); 55918752Sjkh bcopy( cp, ackp, length ); 56018752Sjkh ackp += length; 56118752Sjkh break; 56218752Sjkh case MODE_NAK: 56328461Sbrian LogPrintf(LogIPCP, "MS NBNS req %d - NAK??\n", type ); 56418752Sjkh break; 56518752Sjkh case MODE_REJ: 56628461Sbrian LogPrintf(LogIPCP, "MS NBNS req %d - REJ??\n", type ); 56718752Sjkh break; 56818752Sjkh } 56918752Sjkh break; 57018752Sjkh 57126516Sbrian#endif 57218752Sjkh 5736059Samurai default: 5746059Samurai IpcpInfo.my_reject |= (1 << type); 5756059Samurai bcopy(cp, rejp, length); 5766059Samurai rejp += length; 5776059Samurai break; 5786059Samurai } 5796059Samurai plen -= length; 5806059Samurai cp += length; 5816059Samurai } 5826059Samurai} 5836059Samurai 5846059Samuraivoid 5856059SamuraiIpcpInput(struct mbuf *bp) 5866059Samurai{ 5876059Samurai FsmInput(&IpcpFsm, bp); 5886059Samurai} 589