ipcp.c revision 25630
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 * 2025630Sbrian * $Id: ipcp.c,v 1.13 1997/02/22 16:10:20 peter 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" 376059Samurai#include "vars.h" 3820365Sjkh#include "alias.h" 396059Samurai 406059Samuraiextern void PutConfValue(); 416059Samuraiextern void Prompt(); 426059Samuraiextern struct in_addr ifnetmask; 436059Samurai 446059Samuraistruct ipcpstate IpcpInfo; 459440Samuraistruct in_range DefMyAddress, DefHisAddress, DefTriggerAddress; 466059Samurai 4718752Sjkh#ifdef MSEXT 4818752Sjkhstruct in_addr ns_entries[2], nbns_entries[2]; 4918752Sjkh#endif /* MSEXT */ 5018752Sjkh 516735Samuraistatic void IpcpSendConfigReq __P((struct fsm *)); 526735Samuraistatic void IpcpSendTerminateAck __P((struct fsm *)); 536735Samuraistatic void IpcpSendTerminateReq __P((struct fsm *)); 546735Samuraistatic void IpcpDecodeConfig __P((u_char *, int, int)); 556735Samuraistatic void IpcpLayerStart __P((struct fsm *)); 566735Samuraistatic void IpcpLayerFinish __P((struct fsm *)); 576735Samuraistatic void IpcpLayerUp __P((struct fsm *)); 586735Samuraistatic void IpcpLayerDown __P((struct fsm *)); 596735Samuraistatic void IpcpInitRestartCounter __P((struct fsm *)); 606059Samurai 617001Samuraistruct pppTimer IpcpReportTimer; 626059Samurai 636059Samuraistatic int lastInOctets, lastOutOctets; 646059Samurai 656059Samurai#define REJECTED(p, x) (p->his_reject & (1<<x)) 666059Samurai 676059Samuraistruct fsm IpcpFsm = { 686059Samurai "IPCP", 696059Samurai PROTO_IPCP, 706059Samurai IPCP_MAXCODE, 716059Samurai OPEN_ACTIVE, 726059Samurai ST_INITIAL, 736059Samurai 0, 0, 0, 746059Samurai 756059Samurai 0, 766059Samurai { 0, 0, 0, NULL, NULL, NULL }, 776059Samurai 786059Samurai IpcpLayerUp, 796059Samurai IpcpLayerDown, 806059Samurai IpcpLayerStart, 816059Samurai IpcpLayerFinish, 826059Samurai IpcpInitRestartCounter, 836059Samurai IpcpSendConfigReq, 846059Samurai IpcpSendTerminateReq, 856059Samurai IpcpSendTerminateAck, 866059Samurai IpcpDecodeConfig, 876059Samurai}; 886059Samurai 896059Samuraistatic char *cftypes[] = { 906059Samurai "???", "IPADDRS", "COMPPROTO", "IPADDR", 916059Samurai}; 926059Samurai 936059Samurai/* 946059Samurai * Function called every second. Updates connection period and idle period, 956059Samurai * also update LQR information. 966059Samurai */ 976059Samuraistatic void 986059SamuraiIpcpReportFunc() 996059Samurai{ 1006059Samurai ipConnectSecs++; 1016059Samurai if (lastInOctets == ipInOctets && lastOutOctets == ipOutOctets) 1026059Samurai ipIdleSecs++; 1036059Samurai lastInOctets = ipInOctets; 1046059Samurai lastOutOctets = ipOutOctets; 1056059Samurai StopTimer(&IpcpReportTimer); 1066059Samurai IpcpReportTimer.state = TIMER_STOPPED; 1076059Samurai StartTimer(&IpcpReportTimer); 1086059Samurai} 1096059Samurai 1106059Samuraistatic void 1116059SamuraiIpcpStartReport() 1126059Samurai{ 1136059Samurai ipIdleSecs = ipConnectSecs = 0; 1146059Samurai StopTimer(&IpcpReportTimer); 1156059Samurai IpcpReportTimer.state = TIMER_STOPPED; 1166059Samurai IpcpReportTimer.load = SECTICKS; 1176059Samurai IpcpReportTimer.func = IpcpReportFunc; 1186059Samurai StartTimer(&IpcpReportTimer); 1196059Samurai} 1206059Samurai 12125630Sbrianint 1226059SamuraiReportIpcpStatus() 1236059Samurai{ 1246059Samurai struct ipcpstate *icp = &IpcpInfo; 1256059Samurai struct fsm *fp = &IpcpFsm; 1266059Samurai 1276059Samurai printf("%s [%s]\n", fp->name, StateNames[fp->state]); 12813389Sphk printf(" his side: %s, %lx\n", 1296059Samurai inet_ntoa(icp->his_ipaddr), icp->his_compproto); 13013389Sphk printf(" my side: %s, %lx\n", 1316059Samurai inet_ntoa(icp->want_ipaddr), icp->want_compproto); 1326059Samurai printf("connected: %d secs, idle: %d secs\n\n", ipConnectSecs, ipIdleSecs); 1339440Samurai printf("Defaults:\n"); 1349440Samurai printf(" My Address: %s/%d\n", 1356059Samurai inet_ntoa(DefMyAddress.ipaddr), DefMyAddress.width); 1369440Samurai printf(" His Address: %s/%d\n", 1376059Samurai inet_ntoa(DefHisAddress.ipaddr), DefHisAddress.width); 1389440Samurai printf(" Negotiation: %s/%d\n", 1399440Samurai inet_ntoa(DefTriggerAddress.ipaddr), DefTriggerAddress.width); 14025630Sbrian return 0; 1416059Samurai} 1426059Samurai 1436059Samuraivoid 1446059SamuraiIpcpDefAddress() 1456059Samurai{ 1466059Samurai struct hostent *hp; 1476059Samurai char name[200]; 1486059Samurai 1496059Samurai bzero(&DefMyAddress, sizeof(DefMyAddress)); 1506059Samurai bzero(&DefHisAddress, sizeof(DefHisAddress)); 1519440Samurai bzero(&DefTriggerAddress, sizeof(DefTriggerAddress)); 1526059Samurai if (gethostname(name, sizeof(name)) == 0) { 1536059Samurai hp = gethostbyname(name); 1546059Samurai if (hp && hp->h_addrtype == AF_INET) { 1556059Samurai bcopy(hp->h_addr, (char *)&DefMyAddress.ipaddr.s_addr, hp->h_length); 1566059Samurai } 1576059Samurai } 1586059Samurai} 1596059Samurai 1606059Samuraivoid 1616059SamuraiIpcpInit() 1626059Samurai{ 1636059Samurai struct ipcpstate *icp = &IpcpInfo; 1646059Samurai 1656059Samurai FsmInit(&IpcpFsm); 1666059Samurai bzero(icp, sizeof(struct ipcpstate)); 1676059Samurai if ((mode & MODE_DEDICATED) && !dstsystem) { 1686059Samurai icp->want_ipaddr.s_addr = icp->his_ipaddr.s_addr = 0; 1696059Samurai } else { 1706059Samurai icp->want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr; 1716059Samurai icp->his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr; 1726059Samurai } 1739440Samurai 1749440Samurai /* 1759440Samurai * Some implementation of PPP are: 1769440Samurai * Starting a negotiaion by require sending *special* value as my address, 1779440Samurai * even though standard of PPP is defined full negotiation based. 1789440Samurai * (e.g. "0.0.0.0" or Not "0.0.0.0") 1799440Samurai */ 1809440Samurai if ( icp->want_ipaddr.s_addr == 0 ) { 1819440Samurai icp->want_ipaddr.s_addr = DefTriggerAddress.ipaddr.s_addr; 1829440Samurai } 1839440Samurai 1846059Samurai if (Enabled(ConfVjcomp)) 1856059Samurai icp->want_compproto = (PROTO_VJCOMP << 16) | ((MAX_STATES - 1) << 8); 1866059Samurai else 1876059Samurai icp->want_compproto = 0; 1886059Samurai icp->heis1172 = 0; 1896059Samurai IpcpFsm.maxconfig = 10; 1906059Samurai} 1916059Samurai 1926059Samuraistatic void 1936059SamuraiIpcpInitRestartCounter(fp) 1946059Samuraistruct fsm *fp; 1956059Samurai{ 1966735Samurai fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 1976059Samurai fp->restart = 5; 1986059Samurai} 1996059Samurai 2006059Samuraistatic void 2016059SamuraiIpcpSendConfigReq(fp) 2026059Samuraistruct fsm *fp; 2036059Samurai{ 2046059Samurai u_char *cp; 2056059Samurai struct ipcpstate *icp = &IpcpInfo; 2066059Samurai 2076059Samurai cp = ReqBuff; 20815738Sphk LogPrintf(LOG_LCP_BIT, "%s: SendConfigReq\n", fp->name); 2096735Samurai if (!DEV_IS_SYNC || !REJECTED(icp, TY_IPADDR)) 2106735Samurai PutConfValue(&cp, cftypes, TY_IPADDR, 6, ntohl(icp->want_ipaddr.s_addr)); 2116059Samurai if (icp->want_compproto && !REJECTED(icp, TY_COMPPROTO)) { 2126059Samurai if (icp->heis1172) 2136059Samurai PutConfValue(&cp, cftypes, TY_COMPPROTO, 4, icp->want_compproto >> 16); 2146059Samurai else 2156059Samurai PutConfValue(&cp, cftypes, TY_COMPPROTO, 6, icp->want_compproto); 2166059Samurai } 2176059Samurai FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 2186059Samurai} 2196059Samurai 2206059Samuraistatic void 2216059SamuraiIpcpSendTerminateReq(fp) 2226059Samuraistruct fsm *fp; 2236059Samurai{ 2246059Samurai /* XXX: No code yet */ 2256059Samurai} 2266059Samurai 2276059Samuraistatic void 2286059SamuraiIpcpSendTerminateAck(fp) 2296059Samuraistruct fsm *fp; 2306059Samurai{ 23115738Sphk LogPrintf(LOG_LCP_BIT, " %s: SendTerminateAck\n", fp->name); 2326059Samurai FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 2336059Samurai} 2346059Samurai 2356059Samuraistatic void 2366059SamuraiIpcpLayerStart(fp) 2376059Samuraistruct fsm *fp; 2386059Samurai{ 23915738Sphk LogPrintf(LOG_LCP_BIT, "%s: LayerStart.\n", fp->name); 2406059Samurai} 2416059Samurai 2426059Samuraistatic void 2436059SamuraiIpcpLayerFinish(fp) 2446059Samuraistruct fsm *fp; 2456059Samurai{ 24615738Sphk LogPrintf(LOG_LCP_BIT, "%s: LayerFinish.\n", fp->name); 2476059Samurai LcpClose(); 2486059Samurai NewPhase(PHASE_TERMINATE); 2496059Samurai} 2506059Samurai 2516059Samuraistatic void 2526059SamuraiIpcpLayerDown(fp) 2536059Samuraistruct fsm *fp; 2546059Samurai{ 25515738Sphk LogPrintf(LOG_LCP_BIT, "%s: LayerDown.\n", fp->name); 2566059Samurai StopTimer(&IpcpReportTimer); 2576059Samurai} 2586059Samurai 2596059Samurai/* 2606059Samurai * Called when IPCP has reached to OPEN state 2616059Samurai */ 2626059Samuraistatic void 2636059SamuraiIpcpLayerUp(fp) 2646059Samuraistruct fsm *fp; 2656059Samurai{ 2666059Samurai char tbuff[100]; 2676059Samurai 2686059Samurai#ifdef VERBOSE 2696059Samurai fprintf(stderr, "%s: LayerUp(%d).\r\n", fp->name, fp->state); 2706059Samurai#endif 27125630Sbrian Prompt(); 27215738Sphk LogPrintf(LOG_LCP_BIT, "%s: LayerUp.\n", fp->name); 27321488Simp snprintf(tbuff, sizeof(tbuff), "myaddr = %s ", 27421488Simp inet_ntoa(IpcpInfo.want_ipaddr)); 27515738Sphk LogPrintf(LOG_LCP_BIT|LOG_LINK_BIT, " %s hisaddr = %s\n", tbuff, inet_ntoa(IpcpInfo.his_ipaddr)); 27625630Sbrian if (OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr, ifnetmask) < 0) { 27725630Sbrian printf("unable to set ip address\n"); 27825630Sbrian return; 27925630Sbrian } 2806059Samurai OsLinkup(); 2816059Samurai IpcpStartReport(); 2826059Samurai StartIdleTimer(); 28320365Sjkh if (mode & MODE_ALIAS) 28420365Sjkh SetAliasAddress(IpcpInfo.want_ipaddr); 2856059Samurai} 2866059Samurai 2876059Samuraivoid 2886059SamuraiIpcpUp() 2896059Samurai{ 2906059Samurai FsmUp(&IpcpFsm); 29115738Sphk LogPrintf(LOG_LCP_BIT, "IPCP Up event!!\n"); 2926059Samurai} 2936059Samurai 2946059Samuraivoid 2956059SamuraiIpcpOpen() 2966059Samurai{ 2976059Samurai FsmOpen(&IpcpFsm); 2986059Samurai} 2996059Samurai 3006059Samuraistatic int 3016059SamuraiAcceptableAddr(prange, ipaddr) 3026059Samuraistruct in_range *prange; 3036059Samuraistruct in_addr ipaddr; 3046059Samurai{ 3056059Samurai#ifdef DEBUG 3066059Samurai logprintf("requested = %x ", htonl(ipaddr.s_addr)); 3076059Samurai logprintf("range = %x", htonl(prange->ipaddr.s_addr)); 3086059Samurai logprintf("/%x\n", htonl(prange->mask.s_addr)); 3096059Samurai logprintf("%x, %x\n", htonl(prange->ipaddr.s_addr & prange->mask.s_addr), 3106059Samurai htonl(ipaddr.s_addr & prange->mask.s_addr)); 3116059Samurai#endif 3126059Samurai return((prange->ipaddr.s_addr & prange->mask.s_addr) == 3136059Samurai (ipaddr.s_addr & prange->mask.s_addr)); 3146059Samurai} 3156059Samurai 3166059Samuraistatic void 3176735SamuraiIpcpDecodeConfig(cp, plen, mode) 3186735Samuraiu_char *cp; 3196735Samuraiint plen; 3206059Samuraiint mode; 3216059Samurai{ 3226735Samurai int type, length; 3236059Samurai u_long *lp, compproto; 3246059Samurai struct compreq *pcomp; 32518752Sjkh struct in_addr ipaddr, dstipaddr, dnsstuff, ms_info_req; 3266059Samurai char tbuff[100]; 32721488Simp char tbuff2[100]; 3286059Samurai 3296059Samurai ackp = AckBuff; 3306059Samurai nakp = NakBuff; 3316059Samurai rejp = RejBuff; 3326059Samurai 3336059Samurai while (plen >= sizeof(struct fsmconfig)) { 3346059Samurai if (plen < 0) 3356059Samurai break; 3366059Samurai type = *cp; 3376059Samurai length = cp[1]; 3386059Samurai if (type <= TY_IPADDR) 33921488Simp snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); 3406059Samurai else 34121488Simp snprintf(tbuff, sizeof(tbuff), " "); 3426059Samurai 3436059Samurai switch (type) { 3446059Samurai case TY_IPADDR: /* RFC1332 */ 3456059Samurai lp = (u_long *)(cp + 2); 3466059Samurai ipaddr.s_addr = *lp; 34715738Sphk LogPrintf(LOG_LCP_BIT, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 3486059Samurai 3496059Samurai switch (mode) { 3506059Samurai case MODE_REQ: 3516059Samurai if (!AcceptableAddr(&DefHisAddress, ipaddr)) { 3526059Samurai /* 3536059Samurai * If destination address is not acceptable, insist to use 3546059Samurai * what we want to use. 3556059Samurai */ 3566059Samurai bcopy(cp, nakp, 2); 3576059Samurai bcopy(&IpcpInfo.his_ipaddr.s_addr, nakp+2, length); 3586059Samurai nakp += length; 3596059Samurai break; 3608857Srgrimes 3616059Samurai } 3626059Samurai IpcpInfo.his_ipaddr = ipaddr; 3636059Samurai bcopy(cp, ackp, length); 3646059Samurai ackp += length; 3656059Samurai break; 3666059Samurai case MODE_NAK: 3676059Samurai if (AcceptableAddr(&DefMyAddress, ipaddr)) { 3686059Samurai /* 3696059Samurai * Use address suggested by peer. 3706059Samurai */ 37121488Simp snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s ", tbuff, inet_ntoa(IpcpInfo.want_ipaddr)); 37221488Simp LogPrintf(LOG_LCP_BIT, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 3736059Samurai IpcpInfo.want_ipaddr = ipaddr; 3746059Samurai } 3756059Samurai break; 3766059Samurai case MODE_REJ: 3776059Samurai IpcpInfo.his_reject |= (1 << type); 3786059Samurai break; 3796059Samurai } 3806059Samurai break; 3816059Samurai case TY_COMPPROTO: 3826059Samurai lp = (u_long *)(cp + 2); 3836059Samurai compproto = htonl(*lp); 38415738Sphk LogPrintf(LOG_LCP_BIT, "%s %08x\n", tbuff, compproto); 3856059Samurai 3866059Samurai switch (mode) { 3876059Samurai case MODE_REQ: 3886059Samurai if (!Acceptable(ConfVjcomp)) { 3896059Samurai bcopy(cp, rejp, length); 3906059Samurai rejp += length; 3916059Samurai } else { 3926059Samurai pcomp = (struct compreq *)(cp + 2); 3936059Samurai switch (length) { 3946059Samurai case 4: /* RFC1172 */ 3956059Samurai if (ntohs(pcomp->proto) == PROTO_VJCOMP) { 3966059Samurai logprintf("** Peer is speaking RFC1172 compression protocol **\n"); 3976059Samurai IpcpInfo.heis1172 = 1; 3986059Samurai IpcpInfo.his_compproto = compproto; 3996059Samurai bcopy(cp, ackp, length); 4006059Samurai ackp += length; 4016059Samurai } else { 4026059Samurai bcopy(cp, nakp, 2); 4036059Samurai pcomp->proto = htons(PROTO_VJCOMP); 4046059Samurai bcopy(&pcomp, nakp + 2, 2); 4056059Samurai nakp += length; 4066059Samurai } 4076059Samurai break; 4086059Samurai case 6: /* RFC1332 */ 4096059Samurai if (ntohs(pcomp->proto) == PROTO_VJCOMP 4106059Samurai && pcomp->slots < MAX_STATES && pcomp->slots > 2) { 4116059Samurai IpcpInfo.his_compproto = compproto; 4126059Samurai IpcpInfo.heis1172 = 0; 4136059Samurai bcopy(cp, ackp, length); 4146059Samurai ackp += length; 4156059Samurai } else { 4166059Samurai bcopy(cp, nakp, 2); 4176059Samurai pcomp->proto = htons(PROTO_VJCOMP); 4186059Samurai pcomp->slots = MAX_STATES - 1; 4196059Samurai pcomp->compcid = 0; 4206059Samurai bcopy(&pcomp, nakp + 2, sizeof(pcomp)); 4216059Samurai nakp += length; 4226059Samurai } 4236059Samurai break; 4246059Samurai default: 4256059Samurai bcopy(cp, rejp, length); 4266059Samurai rejp += length; 4276059Samurai break; 4286059Samurai } 4296059Samurai } 4306059Samurai break; 4316059Samurai case MODE_NAK: 43215738Sphk LogPrintf(LOG_LCP_BIT, "%s changing compproto: %08x --> %08x\n", 4336059Samurai tbuff, IpcpInfo.want_compproto, compproto); 4346059Samurai IpcpInfo.want_compproto = compproto; 4356059Samurai break; 4366059Samurai case MODE_REJ: 4376059Samurai IpcpInfo.his_reject |= (1 << type); 4386059Samurai break; 4396059Samurai } 4406059Samurai break; 4416059Samurai case TY_IPADDRS: /* RFC1172 */ 4426059Samurai lp = (u_long *)(cp + 2); 4436059Samurai ipaddr.s_addr = *lp; 4446059Samurai lp = (u_long *)(cp + 6); 4456059Samurai dstipaddr.s_addr = *lp; 44615738Sphk LogPrintf(LOG_LCP_BIT, "%s %s, ", tbuff, inet_ntoa(ipaddr)); 44715738Sphk LogPrintf(LOG_LCP_BIT, "%s\n", inet_ntoa(dstipaddr)); 4486059Samurai 4496059Samurai switch (mode) { 4506059Samurai case MODE_REQ: 4516059Samurai IpcpInfo.his_ipaddr = ipaddr; 4526059Samurai IpcpInfo.want_ipaddr = dstipaddr; 4536059Samurai bcopy(cp, ackp, length); 4546059Samurai ackp += length; 4556059Samurai break; 4566059Samurai case MODE_NAK: 45715738Sphk LogPrintf(LOG_LCP_BIT, "%s changing address: %s ", 4586059Samurai tbuff, inet_ntoa(IpcpInfo.want_ipaddr)); 45915738Sphk LogPrintf(LOG_LCP_BIT, "--> %s\n", inet_ntoa(ipaddr)); 4606059Samurai IpcpInfo.want_ipaddr = ipaddr; 4616059Samurai IpcpInfo.his_ipaddr = dstipaddr; 4626059Samurai break; 4636059Samurai case MODE_REJ: 4646059Samurai IpcpInfo.his_reject |= (1 << type); 4656059Samurai break; 4666059Samurai } 4676059Samurai break; 46818752Sjkh 46918752Sjkh /* 47018752Sjkh * MS extensions for MS's PPP 47118752Sjkh */ 47218752Sjkh 47318752Sjkh#ifdef MSEXT 47418752Sjkh case TY_PRIMARY_DNS: /* MS PPP DNS negotiation hack */ 47518752Sjkh case TY_SECONDARY_DNS: 47618752Sjkh if( !Enabled( ConfMSExt ) ) { 47718752Sjkh LogPrintf( LOG_LCP, "MS NS req - rejected - msext disabled\n" ); 47818752Sjkh IpcpInfo.my_reject |= ( 1 << type ); 47918752Sjkh bcopy(cp, rejp, length); 48018752Sjkh rejp += length; 48118752Sjkh break; 48218752Sjkh } 48318752Sjkh switch( mode ){ 48418752Sjkh case MODE_REQ: 48518752Sjkh lp = (u_long *)(cp + 2); 48618752Sjkh dnsstuff.s_addr = *lp; 48718752Sjkh ms_info_req.s_addr = ns_entries[((type - TY_PRIMARY_DNS)?1:0)].s_addr; 48818752Sjkh if( dnsstuff.s_addr != ms_info_req.s_addr ) 48918752Sjkh { 49018752Sjkh /* 49118752Sjkh So the client has got the DNS stuff wrong (first request) 49218752Sjkh so well tell 'em how it is 49318752Sjkh */ 49418752Sjkh bcopy( cp, nakp, 2 ); /* copy first two (type/length) */ 49518752Sjkh LogPrintf( LOG_LCP, "MS NS req %d:%s->%s - nak\n", 49618752Sjkh type, 49718752Sjkh inet_ntoa( dnsstuff ), 49818752Sjkh inet_ntoa( ms_info_req )); 49918752Sjkh bcopy( &ms_info_req, nakp+2, length ); 50018752Sjkh nakp += length; 50118752Sjkh break; 50218752Sjkh } 50318752Sjkh /* 50418752Sjkh Otherwise they have it right (this time) so we send 50518752Sjkh a ack packet back confirming it... end of story 50618752Sjkh */ 50718752Sjkh LogPrintf( LOG_LCP, "MS NS req %d:%s ok - ack\n", 50818752Sjkh type, 50918752Sjkh inet_ntoa( ms_info_req )); 51018752Sjkh bcopy( cp, ackp, length ); 51118752Sjkh ackp += length; 51218752Sjkh break; 51318752Sjkh case MODE_NAK: /* what does this mean?? */ 51418752Sjkh LogPrintf(LOG_LCP, "MS NS req %d - NAK??\n", type ); 51518752Sjkh break; 51618752Sjkh case MODE_REJ: /* confused?? me to :) */ 51718752Sjkh LogPrintf(LOG_LCP, "MS NS req %d - REJ??\n", type ); 51818752Sjkh break; 51918752Sjkh } 52018752Sjkh break; 52118752Sjkh 52218752Sjkh case TY_PRIMARY_NBNS: /* MS PPP NetBIOS nameserver hack */ 52318752Sjkh case TY_SECONDARY_NBNS: 52418752Sjkh if( !Enabled( ConfMSExt ) ) { 52518752Sjkh LogPrintf( LOG_LCP, "MS NBNS req - rejected - msext disabled\n" ); 52618752Sjkh IpcpInfo.my_reject |= ( 1 << type ); 52718752Sjkh bcopy( cp, rejp, length ); 52818752Sjkh rejp += length; 52918752Sjkh break; 53018752Sjkh } 53118752Sjkh switch( mode ){ 53218752Sjkh case MODE_REQ: 53318752Sjkh lp = (u_long *)(cp + 2); 53418752Sjkh dnsstuff.s_addr = *lp; 53518752Sjkh ms_info_req.s_addr = nbns_entries[((type - TY_PRIMARY_NBNS)?1:0)].s_addr; 53618752Sjkh if( dnsstuff.s_addr != ms_info_req.s_addr ) 53718752Sjkh { 53818752Sjkh bcopy( cp, nakp, 2 ); 53918752Sjkh bcopy( &ms_info_req.s_addr , nakp+2, length ); 54018752Sjkh LogPrintf( LOG_LCP, "MS NBNS req %d:%s->%s - nak\n", 54118752Sjkh type, 54218752Sjkh inet_ntoa( dnsstuff ), 54318752Sjkh inet_ntoa( ms_info_req )); 54418752Sjkh nakp += length; 54518752Sjkh break; 54618752Sjkh } 54718752Sjkh LogPrintf( LOG_LCP, "MS NBNS req %d:%s ok - ack\n", 54818752Sjkh type, 54918752Sjkh inet_ntoa( ms_info_req )); 55018752Sjkh bcopy( cp, ackp, length ); 55118752Sjkh ackp += length; 55218752Sjkh break; 55318752Sjkh case MODE_NAK: 55418752Sjkh LogPrintf( LOG_LCP, "MS NBNS req %d - NAK??\n", type ); 55518752Sjkh break; 55618752Sjkh case MODE_REJ: 55718752Sjkh LogPrintf( LOG_LCP, "MS NBNS req %d - REJ??\n", type ); 55818752Sjkh break; 55918752Sjkh } 56018752Sjkh break; 56118752Sjkh 56218752Sjkh#endif /* MSEXT */ 56318752Sjkh 5646059Samurai default: 5656059Samurai IpcpInfo.my_reject |= (1 << type); 5666059Samurai bcopy(cp, rejp, length); 5676059Samurai rejp += length; 5686059Samurai break; 5696059Samurai } 5706059Samurai plen -= length; 5716059Samurai cp += length; 5726059Samurai } 5736059Samurai} 5746059Samurai 5756059Samuraivoid 5766059SamuraiIpcpInput(struct mbuf *bp) 5776059Samurai{ 5786059Samurai FsmInput(&IpcpFsm, bp); 5796059Samurai} 580