ipcp.c revision 21488
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 * 2021488Simp * $Id: ipcp.c,v 1.10 1996/12/12 14:39:44 jkh 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 1216059Samuraivoid 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); 1406059Samurai} 1416059Samurai 1426059Samuraivoid 1436059SamuraiIpcpDefAddress() 1446059Samurai{ 1456059Samurai struct hostent *hp; 1466059Samurai char name[200]; 1476059Samurai 1486059Samurai bzero(&DefMyAddress, sizeof(DefMyAddress)); 1496059Samurai bzero(&DefHisAddress, sizeof(DefHisAddress)); 1509440Samurai bzero(&DefTriggerAddress, sizeof(DefTriggerAddress)); 1516059Samurai if (gethostname(name, sizeof(name)) == 0) { 1526059Samurai hp = gethostbyname(name); 1536059Samurai if (hp && hp->h_addrtype == AF_INET) { 1546059Samurai bcopy(hp->h_addr, (char *)&DefMyAddress.ipaddr.s_addr, hp->h_length); 1556059Samurai } 1566059Samurai } 1576059Samurai} 1586059Samurai 1596059Samuraivoid 1606059SamuraiIpcpInit() 1616059Samurai{ 1626059Samurai struct ipcpstate *icp = &IpcpInfo; 1636059Samurai 1646059Samurai FsmInit(&IpcpFsm); 1656059Samurai bzero(icp, sizeof(struct ipcpstate)); 1666059Samurai if ((mode & MODE_DEDICATED) && !dstsystem) { 1676059Samurai icp->want_ipaddr.s_addr = icp->his_ipaddr.s_addr = 0; 1686059Samurai } else { 1696059Samurai icp->want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr; 1706059Samurai icp->his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr; 1716059Samurai } 1729440Samurai 1739440Samurai /* 1749440Samurai * Some implementation of PPP are: 1759440Samurai * Starting a negotiaion by require sending *special* value as my address, 1769440Samurai * even though standard of PPP is defined full negotiation based. 1779440Samurai * (e.g. "0.0.0.0" or Not "0.0.0.0") 1789440Samurai */ 1799440Samurai if ( icp->want_ipaddr.s_addr == 0 ) { 1809440Samurai icp->want_ipaddr.s_addr = DefTriggerAddress.ipaddr.s_addr; 1819440Samurai } 1829440Samurai 1836059Samurai if (Enabled(ConfVjcomp)) 1846059Samurai icp->want_compproto = (PROTO_VJCOMP << 16) | ((MAX_STATES - 1) << 8); 1856059Samurai else 1866059Samurai icp->want_compproto = 0; 1876059Samurai icp->heis1172 = 0; 1886059Samurai IpcpFsm.maxconfig = 10; 1896059Samurai} 1906059Samurai 1916059Samuraistatic void 1926059SamuraiIpcpInitRestartCounter(fp) 1936059Samuraistruct fsm *fp; 1946059Samurai{ 1956735Samurai fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 1966059Samurai fp->restart = 5; 1976059Samurai} 1986059Samurai 1996059Samuraistatic void 2006059SamuraiIpcpSendConfigReq(fp) 2016059Samuraistruct fsm *fp; 2026059Samurai{ 2036059Samurai u_char *cp; 2046059Samurai struct ipcpstate *icp = &IpcpInfo; 2056059Samurai 2066059Samurai cp = ReqBuff; 20715738Sphk LogPrintf(LOG_LCP_BIT, "%s: SendConfigReq\n", fp->name); 2086735Samurai if (!DEV_IS_SYNC || !REJECTED(icp, TY_IPADDR)) 2096735Samurai PutConfValue(&cp, cftypes, TY_IPADDR, 6, ntohl(icp->want_ipaddr.s_addr)); 2106059Samurai if (icp->want_compproto && !REJECTED(icp, TY_COMPPROTO)) { 2116059Samurai if (icp->heis1172) 2126059Samurai PutConfValue(&cp, cftypes, TY_COMPPROTO, 4, icp->want_compproto >> 16); 2136059Samurai else 2146059Samurai PutConfValue(&cp, cftypes, TY_COMPPROTO, 6, icp->want_compproto); 2156059Samurai } 2166059Samurai FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 2176059Samurai} 2186059Samurai 2196059Samuraistatic void 2206059SamuraiIpcpSendTerminateReq(fp) 2216059Samuraistruct fsm *fp; 2226059Samurai{ 2236059Samurai /* XXX: No code yet */ 2246059Samurai} 2256059Samurai 2266059Samuraistatic void 2276059SamuraiIpcpSendTerminateAck(fp) 2286059Samuraistruct fsm *fp; 2296059Samurai{ 23015738Sphk LogPrintf(LOG_LCP_BIT, " %s: SendTerminateAck\n", fp->name); 2316059Samurai FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 2326059Samurai} 2336059Samurai 2346059Samuraistatic void 2356059SamuraiIpcpLayerStart(fp) 2366059Samuraistruct fsm *fp; 2376059Samurai{ 23815738Sphk LogPrintf(LOG_LCP_BIT, "%s: LayerStart.\n", fp->name); 2396059Samurai} 2406059Samurai 2416059Samuraistatic void 2426059SamuraiIpcpLayerFinish(fp) 2436059Samuraistruct fsm *fp; 2446059Samurai{ 24515738Sphk LogPrintf(LOG_LCP_BIT, "%s: LayerFinish.\n", fp->name); 2466059Samurai LcpClose(); 2476059Samurai NewPhase(PHASE_TERMINATE); 2486059Samurai} 2496059Samurai 2506059Samuraistatic void 2516059SamuraiIpcpLayerDown(fp) 2526059Samuraistruct fsm *fp; 2536059Samurai{ 25415738Sphk LogPrintf(LOG_LCP_BIT, "%s: LayerDown.\n", fp->name); 2556059Samurai StopTimer(&IpcpReportTimer); 2566059Samurai} 2576059Samurai 2586059Samurai/* 2596059Samurai * Called when IPCP has reached to OPEN state 2606059Samurai */ 2616059Samuraistatic void 2626059SamuraiIpcpLayerUp(fp) 2636059Samuraistruct fsm *fp; 2646059Samurai{ 2656059Samurai char tbuff[100]; 2666059Samurai 2676059Samurai#ifdef VERBOSE 2686059Samurai fprintf(stderr, "%s: LayerUp(%d).\r\n", fp->name, fp->state); 2696059Samurai#endif 2706059Samurai Prompt(1); 27115738Sphk LogPrintf(LOG_LCP_BIT, "%s: LayerUp.\n", fp->name); 27221488Simp snprintf(tbuff, sizeof(tbuff), "myaddr = %s ", 27321488Simp inet_ntoa(IpcpInfo.want_ipaddr)); 27415738Sphk LogPrintf(LOG_LCP_BIT|LOG_LINK_BIT, " %s hisaddr = %s\n", tbuff, inet_ntoa(IpcpInfo.his_ipaddr)); 2756059Samurai OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr, ifnetmask); 2766059Samurai OsLinkup(); 2776059Samurai IpcpStartReport(); 2786059Samurai StartIdleTimer(); 27920365Sjkh if (mode & MODE_ALIAS) 28020365Sjkh SetAliasAddress(IpcpInfo.want_ipaddr); 2816059Samurai} 2826059Samurai 2836059Samuraivoid 2846059SamuraiIpcpUp() 2856059Samurai{ 2866059Samurai FsmUp(&IpcpFsm); 28715738Sphk LogPrintf(LOG_LCP_BIT, "IPCP Up event!!\n"); 2886059Samurai} 2896059Samurai 2906059Samuraivoid 2916059SamuraiIpcpOpen() 2926059Samurai{ 2936059Samurai FsmOpen(&IpcpFsm); 2946059Samurai} 2956059Samurai 2966059Samuraistatic int 2976059SamuraiAcceptableAddr(prange, ipaddr) 2986059Samuraistruct in_range *prange; 2996059Samuraistruct in_addr ipaddr; 3006059Samurai{ 3016059Samurai#ifdef DEBUG 3026059Samurai logprintf("requested = %x ", htonl(ipaddr.s_addr)); 3036059Samurai logprintf("range = %x", htonl(prange->ipaddr.s_addr)); 3046059Samurai logprintf("/%x\n", htonl(prange->mask.s_addr)); 3056059Samurai logprintf("%x, %x\n", htonl(prange->ipaddr.s_addr & prange->mask.s_addr), 3066059Samurai htonl(ipaddr.s_addr & prange->mask.s_addr)); 3076059Samurai#endif 3086059Samurai return((prange->ipaddr.s_addr & prange->mask.s_addr) == 3096059Samurai (ipaddr.s_addr & prange->mask.s_addr)); 3106059Samurai} 3116059Samurai 3126059Samuraistatic void 3136735SamuraiIpcpDecodeConfig(cp, plen, mode) 3146735Samuraiu_char *cp; 3156735Samuraiint plen; 3166059Samuraiint mode; 3176059Samurai{ 3186735Samurai int type, length; 3196059Samurai u_long *lp, compproto; 3206059Samurai struct compreq *pcomp; 32118752Sjkh struct in_addr ipaddr, dstipaddr, dnsstuff, ms_info_req; 3226059Samurai char tbuff[100]; 32321488Simp char tbuff2[100]; 3246059Samurai 3256059Samurai ackp = AckBuff; 3266059Samurai nakp = NakBuff; 3276059Samurai rejp = RejBuff; 3286059Samurai 3296059Samurai while (plen >= sizeof(struct fsmconfig)) { 3306059Samurai if (plen < 0) 3316059Samurai break; 3326059Samurai type = *cp; 3336059Samurai length = cp[1]; 3346059Samurai if (type <= TY_IPADDR) 33521488Simp snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); 3366059Samurai else 33721488Simp snprintf(tbuff, sizeof(tbuff), " "); 3386059Samurai 3396059Samurai switch (type) { 3406059Samurai case TY_IPADDR: /* RFC1332 */ 3416059Samurai lp = (u_long *)(cp + 2); 3426059Samurai ipaddr.s_addr = *lp; 34315738Sphk LogPrintf(LOG_LCP_BIT, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 3446059Samurai 3456059Samurai switch (mode) { 3466059Samurai case MODE_REQ: 3476059Samurai if (!AcceptableAddr(&DefHisAddress, ipaddr)) { 3486059Samurai /* 3496059Samurai * If destination address is not acceptable, insist to use 3506059Samurai * what we want to use. 3516059Samurai */ 3526059Samurai bcopy(cp, nakp, 2); 3536059Samurai bcopy(&IpcpInfo.his_ipaddr.s_addr, nakp+2, length); 3546059Samurai nakp += length; 3556059Samurai break; 3568857Srgrimes 3576059Samurai } 3586059Samurai IpcpInfo.his_ipaddr = ipaddr; 3596059Samurai bcopy(cp, ackp, length); 3606059Samurai ackp += length; 3616059Samurai break; 3626059Samurai case MODE_NAK: 3636059Samurai if (AcceptableAddr(&DefMyAddress, ipaddr)) { 3646059Samurai /* 3656059Samurai * Use address suggested by peer. 3666059Samurai */ 36721488Simp snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s ", tbuff, inet_ntoa(IpcpInfo.want_ipaddr)); 36821488Simp LogPrintf(LOG_LCP_BIT, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 3696059Samurai IpcpInfo.want_ipaddr = ipaddr; 3706059Samurai } 3716059Samurai break; 3726059Samurai case MODE_REJ: 3736059Samurai IpcpInfo.his_reject |= (1 << type); 3746059Samurai break; 3756059Samurai } 3766059Samurai break; 3776059Samurai case TY_COMPPROTO: 3786059Samurai lp = (u_long *)(cp + 2); 3796059Samurai compproto = htonl(*lp); 38015738Sphk LogPrintf(LOG_LCP_BIT, "%s %08x\n", tbuff, compproto); 3816059Samurai 3826059Samurai switch (mode) { 3836059Samurai case MODE_REQ: 3846059Samurai if (!Acceptable(ConfVjcomp)) { 3856059Samurai bcopy(cp, rejp, length); 3866059Samurai rejp += length; 3876059Samurai } else { 3886059Samurai pcomp = (struct compreq *)(cp + 2); 3896059Samurai switch (length) { 3906059Samurai case 4: /* RFC1172 */ 3916059Samurai if (ntohs(pcomp->proto) == PROTO_VJCOMP) { 3926059Samurai logprintf("** Peer is speaking RFC1172 compression protocol **\n"); 3936059Samurai IpcpInfo.heis1172 = 1; 3946059Samurai IpcpInfo.his_compproto = compproto; 3956059Samurai bcopy(cp, ackp, length); 3966059Samurai ackp += length; 3976059Samurai } else { 3986059Samurai bcopy(cp, nakp, 2); 3996059Samurai pcomp->proto = htons(PROTO_VJCOMP); 4006059Samurai bcopy(&pcomp, nakp + 2, 2); 4016059Samurai nakp += length; 4026059Samurai } 4036059Samurai break; 4046059Samurai case 6: /* RFC1332 */ 4056059Samurai if (ntohs(pcomp->proto) == PROTO_VJCOMP 4066059Samurai && pcomp->slots < MAX_STATES && pcomp->slots > 2) { 4076059Samurai IpcpInfo.his_compproto = compproto; 4086059Samurai IpcpInfo.heis1172 = 0; 4096059Samurai bcopy(cp, ackp, length); 4106059Samurai ackp += length; 4116059Samurai } else { 4126059Samurai bcopy(cp, nakp, 2); 4136059Samurai pcomp->proto = htons(PROTO_VJCOMP); 4146059Samurai pcomp->slots = MAX_STATES - 1; 4156059Samurai pcomp->compcid = 0; 4166059Samurai bcopy(&pcomp, nakp + 2, sizeof(pcomp)); 4176059Samurai nakp += length; 4186059Samurai } 4196059Samurai break; 4206059Samurai default: 4216059Samurai bcopy(cp, rejp, length); 4226059Samurai rejp += length; 4236059Samurai break; 4246059Samurai } 4256059Samurai } 4266059Samurai break; 4276059Samurai case MODE_NAK: 42815738Sphk LogPrintf(LOG_LCP_BIT, "%s changing compproto: %08x --> %08x\n", 4296059Samurai tbuff, IpcpInfo.want_compproto, compproto); 4306059Samurai IpcpInfo.want_compproto = compproto; 4316059Samurai break; 4326059Samurai case MODE_REJ: 4336059Samurai IpcpInfo.his_reject |= (1 << type); 4346059Samurai break; 4356059Samurai } 4366059Samurai break; 4376059Samurai case TY_IPADDRS: /* RFC1172 */ 4386059Samurai lp = (u_long *)(cp + 2); 4396059Samurai ipaddr.s_addr = *lp; 4406059Samurai lp = (u_long *)(cp + 6); 4416059Samurai dstipaddr.s_addr = *lp; 44215738Sphk LogPrintf(LOG_LCP_BIT, "%s %s, ", tbuff, inet_ntoa(ipaddr)); 44315738Sphk LogPrintf(LOG_LCP_BIT, "%s\n", inet_ntoa(dstipaddr)); 4446059Samurai 4456059Samurai switch (mode) { 4466059Samurai case MODE_REQ: 4476059Samurai IpcpInfo.his_ipaddr = ipaddr; 4486059Samurai IpcpInfo.want_ipaddr = dstipaddr; 4496059Samurai bcopy(cp, ackp, length); 4506059Samurai ackp += length; 4516059Samurai break; 4526059Samurai case MODE_NAK: 45315738Sphk LogPrintf(LOG_LCP_BIT, "%s changing address: %s ", 4546059Samurai tbuff, inet_ntoa(IpcpInfo.want_ipaddr)); 45515738Sphk LogPrintf(LOG_LCP_BIT, "--> %s\n", inet_ntoa(ipaddr)); 4566059Samurai IpcpInfo.want_ipaddr = ipaddr; 4576059Samurai IpcpInfo.his_ipaddr = dstipaddr; 4586059Samurai break; 4596059Samurai case MODE_REJ: 4606059Samurai IpcpInfo.his_reject |= (1 << type); 4616059Samurai break; 4626059Samurai } 4636059Samurai break; 46418752Sjkh 46518752Sjkh /* 46618752Sjkh * MS extensions for MS's PPP 46718752Sjkh */ 46818752Sjkh 46918752Sjkh#ifdef MSEXT 47018752Sjkh case TY_PRIMARY_DNS: /* MS PPP DNS negotiation hack */ 47118752Sjkh case TY_SECONDARY_DNS: 47218752Sjkh if( !Enabled( ConfMSExt ) ) { 47318752Sjkh LogPrintf( LOG_LCP, "MS NS req - rejected - msext disabled\n" ); 47418752Sjkh IpcpInfo.my_reject |= ( 1 << type ); 47518752Sjkh bcopy(cp, rejp, length); 47618752Sjkh rejp += length; 47718752Sjkh break; 47818752Sjkh } 47918752Sjkh switch( mode ){ 48018752Sjkh case MODE_REQ: 48118752Sjkh lp = (u_long *)(cp + 2); 48218752Sjkh dnsstuff.s_addr = *lp; 48318752Sjkh ms_info_req.s_addr = ns_entries[((type - TY_PRIMARY_DNS)?1:0)].s_addr; 48418752Sjkh if( dnsstuff.s_addr != ms_info_req.s_addr ) 48518752Sjkh { 48618752Sjkh /* 48718752Sjkh So the client has got the DNS stuff wrong (first request) 48818752Sjkh so well tell 'em how it is 48918752Sjkh */ 49018752Sjkh bcopy( cp, nakp, 2 ); /* copy first two (type/length) */ 49118752Sjkh LogPrintf( LOG_LCP, "MS NS req %d:%s->%s - nak\n", 49218752Sjkh type, 49318752Sjkh inet_ntoa( dnsstuff ), 49418752Sjkh inet_ntoa( ms_info_req )); 49518752Sjkh bcopy( &ms_info_req, nakp+2, length ); 49618752Sjkh nakp += length; 49718752Sjkh break; 49818752Sjkh } 49918752Sjkh /* 50018752Sjkh Otherwise they have it right (this time) so we send 50118752Sjkh a ack packet back confirming it... end of story 50218752Sjkh */ 50318752Sjkh LogPrintf( LOG_LCP, "MS NS req %d:%s ok - ack\n", 50418752Sjkh type, 50518752Sjkh inet_ntoa( ms_info_req )); 50618752Sjkh bcopy( cp, ackp, length ); 50718752Sjkh ackp += length; 50818752Sjkh break; 50918752Sjkh case MODE_NAK: /* what does this mean?? */ 51018752Sjkh LogPrintf(LOG_LCP, "MS NS req %d - NAK??\n", type ); 51118752Sjkh break; 51218752Sjkh case MODE_REJ: /* confused?? me to :) */ 51318752Sjkh LogPrintf(LOG_LCP, "MS NS req %d - REJ??\n", type ); 51418752Sjkh break; 51518752Sjkh } 51618752Sjkh break; 51718752Sjkh 51818752Sjkh case TY_PRIMARY_NBNS: /* MS PPP NetBIOS nameserver hack */ 51918752Sjkh case TY_SECONDARY_NBNS: 52018752Sjkh if( !Enabled( ConfMSExt ) ) { 52118752Sjkh LogPrintf( LOG_LCP, "MS NBNS req - rejected - msext disabled\n" ); 52218752Sjkh IpcpInfo.my_reject |= ( 1 << type ); 52318752Sjkh bcopy( cp, rejp, length ); 52418752Sjkh rejp += length; 52518752Sjkh break; 52618752Sjkh } 52718752Sjkh switch( mode ){ 52818752Sjkh case MODE_REQ: 52918752Sjkh lp = (u_long *)(cp + 2); 53018752Sjkh dnsstuff.s_addr = *lp; 53118752Sjkh ms_info_req.s_addr = nbns_entries[((type - TY_PRIMARY_NBNS)?1:0)].s_addr; 53218752Sjkh if( dnsstuff.s_addr != ms_info_req.s_addr ) 53318752Sjkh { 53418752Sjkh bcopy( cp, nakp, 2 ); 53518752Sjkh bcopy( &ms_info_req.s_addr , nakp+2, length ); 53618752Sjkh LogPrintf( LOG_LCP, "MS NBNS req %d:%s->%s - nak\n", 53718752Sjkh type, 53818752Sjkh inet_ntoa( dnsstuff ), 53918752Sjkh inet_ntoa( ms_info_req )); 54018752Sjkh nakp += length; 54118752Sjkh break; 54218752Sjkh } 54318752Sjkh LogPrintf( LOG_LCP, "MS NBNS req %d:%s ok - ack\n", 54418752Sjkh type, 54518752Sjkh inet_ntoa( ms_info_req )); 54618752Sjkh bcopy( cp, ackp, length ); 54718752Sjkh ackp += length; 54818752Sjkh break; 54918752Sjkh case MODE_NAK: 55018752Sjkh LogPrintf( LOG_LCP, "MS NBNS req %d - NAK??\n", type ); 55118752Sjkh break; 55218752Sjkh case MODE_REJ: 55318752Sjkh LogPrintf( LOG_LCP, "MS NBNS req %d - REJ??\n", type ); 55418752Sjkh break; 55518752Sjkh } 55618752Sjkh break; 55718752Sjkh 55818752Sjkh#endif /* MSEXT */ 55918752Sjkh 5606059Samurai default: 5616059Samurai IpcpInfo.my_reject |= (1 << type); 5626059Samurai bcopy(cp, rejp, length); 5636059Samurai rejp += length; 5646059Samurai break; 5656059Samurai } 5666059Samurai plen -= length; 5676059Samurai cp += length; 5686059Samurai } 5696059Samurai} 5706059Samurai 5716059Samuraivoid 5726059SamuraiIpcpInput(struct mbuf *bp) 5736059Samurai{ 5746059Samurai FsmInput(&IpcpFsm, bp); 5756059Samurai} 576