ipcp.c revision 31690
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 * 2031690Sbrian * $Id: ipcp.c,v 1.41 1997/12/06 22:43:58 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> 3631272Sbrian#include <time.h> 3730715Sbrian#include <unistd.h> 3830715Sbrian 3931343Sbrian#include "command.h" 4030715Sbrian#include "mbuf.h" 4130715Sbrian#include "log.h" 4230715Sbrian#include "defs.h" 4330715Sbrian#include "timer.h" 4429048Sbrian#include "fsm.h" 4529048Sbrian#include "lcpproto.h" 4629048Sbrian#include "lcp.h" 4731690Sbrian#include "iplist.h" 4829048Sbrian#include "ipcp.h" 496059Samurai#include "slcompress.h" 506059Samurai#include "os.h" 516059Samurai#include "phase.h" 5226142Sbrian#include "loadalias.h" 536059Samurai#include "vars.h" 5430715Sbrian#include "vjcomp.h" 5530733Sbrian#include "ip.h" 5631272Sbrian#include "throughput.h" 5731690Sbrian#include "route.h" 586059Samurai 5930715Sbrian#ifndef NOMSEXT 6030715Sbrianstruct in_addr ns_entries[2]; 6130715Sbrianstruct in_addr nbns_entries[2]; 6230715Sbrian#endif 636059Samurai 646059Samuraistruct ipcpstate IpcpInfo; 6530715Sbrianstruct in_range DefMyAddress; 6630715Sbrianstruct in_range DefHisAddress; 6731690Sbrianstruct iplist DefHisChoice; 6830715Sbrianstruct in_addr TriggerAddress; 6928394Sbrianint HaveTriggerAddress; 706059Samurai 7126516Sbrianstatic void IpcpSendConfigReq(struct fsm *); 7226516Sbrianstatic void IpcpSendTerminateAck(struct fsm *); 7326516Sbrianstatic void IpcpSendTerminateReq(struct fsm *); 7426516Sbrianstatic void IpcpDecodeConfig(u_char *, int, int); 7526516Sbrianstatic void IpcpLayerStart(struct fsm *); 7626516Sbrianstatic void IpcpLayerFinish(struct fsm *); 7726516Sbrianstatic void IpcpLayerUp(struct fsm *); 7826516Sbrianstatic void IpcpLayerDown(struct fsm *); 7926516Sbrianstatic void IpcpInitRestartCounter(struct fsm *); 806059Samurai 816059Samuraistruct fsm IpcpFsm = { 826059Samurai "IPCP", 836059Samurai PROTO_IPCP, 846059Samurai IPCP_MAXCODE, 856059Samurai OPEN_ACTIVE, 866059Samurai ST_INITIAL, 876059Samurai 0, 0, 0, 886059Samurai 896059Samurai 0, 9028679Sbrian {0, 0, 0, NULL, NULL, NULL}, 9128679Sbrian {0, 0, 0, NULL, NULL, NULL}, 9228461Sbrian LogIPCP, 936059Samurai 946059Samurai IpcpLayerUp, 956059Samurai IpcpLayerDown, 966059Samurai IpcpLayerStart, 976059Samurai IpcpLayerFinish, 986059Samurai IpcpInitRestartCounter, 996059Samurai IpcpSendConfigReq, 1006059Samurai IpcpSendTerminateReq, 1016059Samurai IpcpSendTerminateAck, 1026059Samurai IpcpDecodeConfig, 1036059Samurai}; 1046059Samurai 10531343Sbrianstatic const char *cftypes[] = { 10631171Sbrian /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ 10731171Sbrian "???", 10831171Sbrian "IPADDRS", /* 1: IP-Addresses */ /* deprecated */ 10931171Sbrian "COMPPROTO", /* 2: IP-Compression-Protocol */ 11031171Sbrian "IPADDR", /* 3: IP-Address */ 1116059Samurai}; 1126059Samurai 11331171Sbrian#define NCFTYPES (sizeof(cftypes)/sizeof(char *)) 11431171Sbrian 11531343Sbrianstatic const char *cftypes128[] = { 11631171Sbrian /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ 11731171Sbrian "???", 11831171Sbrian "PRIDNS", /* 129: Primary DNS Server Address */ 11931171Sbrian "PRINBNS", /* 130: Primary NBNS Server Address */ 12031171Sbrian "SECDNS", /* 131: Secondary DNS Server Address */ 12131171Sbrian "SECNBNS", /* 132: Secondary NBNS Server Address */ 12231171Sbrian}; 12331171Sbrian 12431171Sbrian#define NCFTYPES128 (sizeof(cftypes)/sizeof(char *)) 12531171Sbrian 12631272Sbrianstruct pppThroughput throughput; 12731272Sbrian 12831272Sbrianvoid 12931272SbrianIpcpAddInOctets(int n) 1306059Samurai{ 13131272Sbrian throughput_addin(&throughput, n); 1326059Samurai} 1336059Samurai 13431272Sbrianvoid 13531272SbrianIpcpAddOutOctets(int n) 1366059Samurai{ 13731272Sbrian throughput_addout(&throughput, n); 1386059Samurai} 1396059Samurai 14025630Sbrianint 14131343SbrianReportIpcpStatus(struct cmdargs const *arg) 1426059Samurai{ 1436059Samurai struct fsm *fp = &IpcpFsm; 1446059Samurai 14526516Sbrian if (!VarTerm) 14626516Sbrian return 1; 14726516Sbrian fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]); 14831514Sbrian fprintf(VarTerm, " his side: %s, %s\n", 14931540Sbrian inet_ntoa(IpcpInfo.his_ipaddr), vj2asc(IpcpInfo.his_compproto)); 15031514Sbrian fprintf(VarTerm, " my side: %s, %s\n", 15131540Sbrian inet_ntoa(IpcpInfo.want_ipaddr), vj2asc(IpcpInfo.want_compproto)); 15229048Sbrian 15326516Sbrian fprintf(VarTerm, "Defaults:\n"); 15426516Sbrian fprintf(VarTerm, " My Address: %s/%d\n", 15528679Sbrian inet_ntoa(DefMyAddress.ipaddr), DefMyAddress.width); 15626516Sbrian fprintf(VarTerm, " His Address: %s/%d\n", 15728679Sbrian inet_ntoa(DefHisAddress.ipaddr), DefHisAddress.width); 15828394Sbrian if (HaveTriggerAddress) 15928679Sbrian fprintf(VarTerm, " Negotiation(trigger): %s\n", inet_ntoa(TriggerAddress)); 16028394Sbrian else 16128679Sbrian fprintf(VarTerm, " Negotiation(trigger): MYADDR\n"); 16226516Sbrian 16331272Sbrian fprintf(VarTerm, "\n"); 16431272Sbrian throughput_disp(&throughput, VarTerm); 16531272Sbrian 16626516Sbrian return 0; 1676059Samurai} 1686059Samurai 1696059Samuraivoid 1706059SamuraiIpcpDefAddress() 1716059Samurai{ 1726059Samurai struct hostent *hp; 1736059Samurai char name[200]; 1746059Samurai 17530715Sbrian memset(&DefMyAddress, '\0', sizeof(DefMyAddress)); 17630715Sbrian memset(&DefHisAddress, '\0', sizeof(DefHisAddress)); 17728394Sbrian TriggerAddress.s_addr = 0; 17828394Sbrian HaveTriggerAddress = 0; 1796059Samurai if (gethostname(name, sizeof(name)) == 0) { 18028679Sbrian hp = gethostbyname(name); 18128679Sbrian if (hp && hp->h_addrtype == AF_INET) { 18230715Sbrian memcpy(&DefMyAddress.ipaddr.s_addr, hp->h_addr, hp->h_length); 18328679Sbrian } 1846059Samurai } 1856059Samurai} 1866059Samurai 1876059Samuraivoid 1886059SamuraiIpcpInit() 1896059Samurai{ 19031690Sbrian if (iplist_isvalid(&DefHisChoice)) 19131690Sbrian iplist_setrandpos(&DefHisChoice); 1926059Samurai FsmInit(&IpcpFsm); 19331540Sbrian memset(&IpcpInfo, '\0', sizeof(struct ipcpstate)); 19431121Sbrian if ((mode & MODE_DEDICATED) && !GetLabel()) { 19531540Sbrian IpcpInfo.want_ipaddr.s_addr = IpcpInfo.his_ipaddr.s_addr = 0; 1966059Samurai } else { 19731540Sbrian IpcpInfo.want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr; 19831540Sbrian IpcpInfo.his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr; 1996059Samurai } 2009440Samurai 2019440Samurai /* 20229048Sbrian * Some implementations of PPP require that we send a 20329048Sbrian * *special* value as our address, even though the rfc specifies 20429048Sbrian * full negotiation (e.g. "0.0.0.0" or Not "0.0.0.0"). 2059440Samurai */ 20628394Sbrian if (HaveTriggerAddress) { 20731540Sbrian IpcpInfo.want_ipaddr.s_addr = TriggerAddress.s_addr; 20828461Sbrian LogPrintf(LogIPCP, "Using trigger address %s\n", inet_ntoa(TriggerAddress)); 2099440Samurai } 2106059Samurai if (Enabled(ConfVjcomp)) 21131540Sbrian IpcpInfo.want_compproto = (PROTO_VJCOMP << 16) | ((MAX_STATES - 1) << 8) | 1; 2126059Samurai else 21331540Sbrian IpcpInfo.want_compproto = 0; 21431540Sbrian IpcpInfo.heis1172 = 0; 2156059Samurai IpcpFsm.maxconfig = 10; 21631272Sbrian throughput_init(&throughput); 2176059Samurai} 2186059Samurai 2196059Samuraistatic void 22028679SbrianIpcpInitRestartCounter(struct fsm * fp) 2216059Samurai{ 2226735Samurai fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 2236059Samurai fp->restart = 5; 2246059Samurai} 2256059Samurai 2266059Samuraistatic void 22728679SbrianIpcpSendConfigReq(struct fsm * fp) 2286059Samurai{ 2296059Samurai u_char *cp; 23031514Sbrian struct lcp_opt o; 2316059Samurai 2326059Samurai cp = ReqBuff; 23328461Sbrian LogPrintf(LogIPCP, "IpcpSendConfigReq\n"); 23431540Sbrian if (!DEV_IS_SYNC || !REJECTED(&IpcpInfo, TY_IPADDR)) { 23531514Sbrian o.id = TY_IPADDR; 23631514Sbrian o.len = 6; 23731540Sbrian *(u_long *)o.data = IpcpInfo.want_ipaddr.s_addr; 23831514Sbrian cp += LcpPutConf(LogIPCP, cp, &o, cftypes[o.id], 23931540Sbrian inet_ntoa(IpcpInfo.want_ipaddr)); 24031514Sbrian } 24131514Sbrian 24231540Sbrian if (IpcpInfo.want_compproto && !REJECTED(&IpcpInfo, TY_COMPPROTO)) { 24331514Sbrian const char *args; 24431514Sbrian o.id = TY_COMPPROTO; 24531540Sbrian if (IpcpInfo.heis1172) { 24631514Sbrian o.len = 4; 24731514Sbrian *(u_short *)o.data = htons(PROTO_VJCOMP); 24831514Sbrian args = ""; 24931514Sbrian } else { 25031514Sbrian o.len = 6; 25131540Sbrian *(u_long *)o.data = htonl(IpcpInfo.want_compproto); 25231540Sbrian args = vj2asc(IpcpInfo.want_compproto); 25331514Sbrian } 25431514Sbrian cp += LcpPutConf(LogIPCP, cp, &o, cftypes[o.id], args); 2556059Samurai } 2566059Samurai FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 2576059Samurai} 2586059Samurai 2596059Samuraistatic void 26028679SbrianIpcpSendTerminateReq(struct fsm * fp) 2616059Samurai{ 2626059Samurai /* XXX: No code yet */ 2636059Samurai} 2646059Samurai 2656059Samuraistatic void 26628679SbrianIpcpSendTerminateAck(struct fsm * fp) 2676059Samurai{ 26828461Sbrian LogPrintf(LogIPCP, "IpcpSendTerminateAck\n"); 2696059Samurai FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 2706059Samurai} 2716059Samurai 2726059Samuraistatic void 27328679SbrianIpcpLayerStart(struct fsm * fp) 2746059Samurai{ 27528461Sbrian LogPrintf(LogIPCP, "IpcpLayerStart.\n"); 2766059Samurai} 2776059Samurai 2786059Samuraistatic void 27928679SbrianIpcpLayerFinish(struct fsm * fp) 2806059Samurai{ 28128461Sbrian LogPrintf(LogIPCP, "IpcpLayerFinish.\n"); 28226098Sbrian reconnect(RECON_FALSE); 2836059Samurai LcpClose(); 2846059Samurai NewPhase(PHASE_TERMINATE); 2856059Samurai} 2866059Samurai 2876059Samuraistatic void 28828679SbrianIpcpLayerDown(struct fsm * fp) 2896059Samurai{ 29028461Sbrian LogPrintf(LogIPCP, "IpcpLayerDown.\n"); 29131272Sbrian throughput_stop(&throughput); 29231272Sbrian throughput_log(&throughput, LogIPCP, NULL); 2936059Samurai} 2946059Samurai 2956059Samurai/* 2966059Samurai * Called when IPCP has reached to OPEN state 2976059Samurai */ 2986059Samuraistatic void 29928679SbrianIpcpLayerUp(struct fsm * fp) 3006059Samurai{ 3016059Samurai char tbuff[100]; 3026059Samurai 30325630Sbrian Prompt(); 30428461Sbrian LogPrintf(LogIPCP, "IpcpLayerUp(%d).\n", fp->state); 30528679Sbrian snprintf(tbuff, sizeof(tbuff), "myaddr = %s ", 30628679Sbrian inet_ntoa(IpcpInfo.want_ipaddr)); 30730187Sbrian 30830187Sbrian if (IpcpInfo.his_compproto >> 16 == PROTO_VJCOMP) 30930187Sbrian VjInit((IpcpInfo.his_compproto >> 8) & 255); 31030187Sbrian 31128461Sbrian LogPrintf(LogIsKept(LogIPCP) ? LogIPCP : LogLINK, " %s hisaddr = %s\n", 31228679Sbrian tbuff, inet_ntoa(IpcpInfo.his_ipaddr)); 31331690Sbrian if (OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr) < 0) { 31426516Sbrian if (VarTerm) 31526516Sbrian LogPrintf(LogERROR, "IpcpLayerUp: unable to set ip address\n"); 31626516Sbrian return; 31725630Sbrian } 31831343Sbrian#ifndef NOALIAS 31927763Sbrian if (mode & MODE_ALIAS) 32028679Sbrian VarPacketAliasSetAddress(IpcpInfo.want_ipaddr); 32131343Sbrian#endif 3226059Samurai OsLinkup(); 32331272Sbrian throughput_start(&throughput); 3246059Samurai StartIdleTimer(); 3256059Samurai} 3266059Samurai 3276059Samuraivoid 3286059SamuraiIpcpUp() 3296059Samurai{ 3306059Samurai FsmUp(&IpcpFsm); 33128461Sbrian LogPrintf(LogIPCP, "IPCP Up event!!\n"); 3326059Samurai} 3336059Samurai 3346059Samuraivoid 3356059SamuraiIpcpOpen() 3366059Samurai{ 3376059Samurai FsmOpen(&IpcpFsm); 3386059Samurai} 3396059Samurai 3406059Samuraistatic int 34128679SbrianAcceptableAddr(struct in_range * prange, struct in_addr ipaddr) 3426059Samurai{ 34328974Sbrian LogPrintf(LogDEBUG, "requested = %x\n", htonl(ipaddr.s_addr)); 34428974Sbrian LogPrintf(LogDEBUG, "range = %x\n", htonl(prange->ipaddr.s_addr)); 34526516Sbrian LogPrintf(LogDEBUG, "/%x\n", htonl(prange->mask.s_addr)); 34626516Sbrian LogPrintf(LogDEBUG, "%x, %x\n", htonl(prange->ipaddr.s_addr & prange-> 34728679Sbrian mask.s_addr), htonl(ipaddr.s_addr & prange->mask.s_addr)); 34825661Sbrian return (prange->ipaddr.s_addr & prange->mask.s_addr) == 34928679Sbrian (ipaddr.s_addr & prange->mask.s_addr) && ipaddr.s_addr; 3506059Samurai} 3516059Samurai 3526059Samuraistatic void 35331034SbrianIpcpDecodeConfig(u_char * cp, int plen, int mode_type) 3546059Samurai{ 3556735Samurai int type, length; 3566059Samurai u_long *lp, compproto; 3576059Samurai struct compreq *pcomp; 35818752Sjkh struct in_addr ipaddr, dstipaddr, dnsstuff, ms_info_req; 3596059Samurai char tbuff[100]; 36021488Simp char tbuff2[100]; 3616059Samurai 3626059Samurai ackp = AckBuff; 3636059Samurai nakp = NakBuff; 3646059Samurai rejp = RejBuff; 3656059Samurai 3666059Samurai while (plen >= sizeof(struct fsmconfig)) { 3676059Samurai type = *cp; 3686059Samurai length = cp[1]; 36931171Sbrian if (type < NCFTYPES) 37021488Simp snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); 37131171Sbrian else if (type > 128 && type < 128 + NCFTYPES128) 37231585Sbrian snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes128[type-128], length); 3736059Samurai else 37431690Sbrian snprintf(tbuff, sizeof(tbuff), " <%d>[%d] ", type, length); 3756059Samurai 3766059Samurai switch (type) { 3776059Samurai case TY_IPADDR: /* RFC1332 */ 37828679Sbrian lp = (u_long *) (cp + 2); 3796059Samurai ipaddr.s_addr = *lp; 38028461Sbrian LogPrintf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 3816059Samurai 38231034Sbrian switch (mode_type) { 3836059Samurai case MODE_REQ: 38431690Sbrian if (iplist_isvalid(&DefHisChoice)) { 38531690Sbrian if (iplist_ip2pos(&DefHisChoice, ipaddr) < 0 || 38631690Sbrian OsTrySetIpaddress(DefMyAddress.ipaddr, ipaddr) != 0) { 38731690Sbrian LogPrintf(LogIPCP, "%s: Address invalid or already in use\n", 38831690Sbrian inet_ntoa(ipaddr)); 38931690Sbrian IpcpInfo.his_ipaddr = ChooseHisAddr(DefMyAddress.ipaddr); 39031690Sbrian if (IpcpInfo.his_ipaddr.s_addr == INADDR_ANY) { 39131690Sbrian memcpy(rejp, cp, length); 39231690Sbrian rejp += length; 39331690Sbrian } else { 39431690Sbrian memcpy(nakp, cp, 2); 39531690Sbrian memcpy(nakp+2, &IpcpInfo.his_ipaddr.s_addr, length - 2); 39631690Sbrian nakp += length; 39731690Sbrian } 39831690Sbrian break; 39931690Sbrian } 40031690Sbrian } else if (!AcceptableAddr(&DefHisAddress, ipaddr)) { 40128679Sbrian /* 40228679Sbrian * If destination address is not acceptable, insist to use what we 40328679Sbrian * want to use. 40428679Sbrian */ 40530715Sbrian memcpy(nakp, cp, 2); 40631690Sbrian memcpy(nakp+2, &IpcpInfo.his_ipaddr.s_addr, length - 2); 40728679Sbrian nakp += length; 40828679Sbrian break; 4096059Samurai } 4106059Samurai IpcpInfo.his_ipaddr = ipaddr; 41130715Sbrian memcpy(ackp, cp, length); 4126059Samurai ackp += length; 4136059Samurai break; 4146059Samurai case MODE_NAK: 4156059Samurai if (AcceptableAddr(&DefMyAddress, ipaddr)) { 41631690Sbrian /* Use address suggested by peer */ 41728974Sbrian snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s ", tbuff, 41828974Sbrian inet_ntoa(IpcpInfo.want_ipaddr)); 41928461Sbrian LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 4206059Samurai IpcpInfo.want_ipaddr = ipaddr; 42131690Sbrian } else { 42231690Sbrian LogPrintf(LogIPCP, "%s: Unacceptable address!\n", inet_ntoa(ipaddr)); 42331690Sbrian FsmClose(&IpcpFsm); 4246059Samurai } 4256059Samurai break; 4266059Samurai case MODE_REJ: 4276059Samurai IpcpInfo.his_reject |= (1 << type); 4286059Samurai break; 4296059Samurai } 4306059Samurai break; 4316059Samurai case TY_COMPPROTO: 43228679Sbrian lp = (u_long *) (cp + 2); 4336059Samurai compproto = htonl(*lp); 43431514Sbrian LogPrintf(LogIPCP, "%s %s\n", tbuff, vj2asc(compproto)); 4356059Samurai 43631034Sbrian switch (mode_type) { 4376059Samurai case MODE_REQ: 4386059Samurai if (!Acceptable(ConfVjcomp)) { 43930715Sbrian memcpy(rejp, cp, length); 4406059Samurai rejp += length; 4416059Samurai } else { 44228679Sbrian pcomp = (struct compreq *) (cp + 2); 4436059Samurai switch (length) { 44428679Sbrian case 4: /* RFC1172 */ 4456059Samurai if (ntohs(pcomp->proto) == PROTO_VJCOMP) { 44626940Sbrian LogPrintf(LogWARN, "Peer is speaking RFC1172 compression protocol !\n"); 4476059Samurai IpcpInfo.heis1172 = 1; 4486059Samurai IpcpInfo.his_compproto = compproto; 44930715Sbrian memcpy(ackp, cp, length); 4506059Samurai ackp += length; 4516059Samurai } else { 45230715Sbrian memcpy(nakp, cp, 2); 4536059Samurai pcomp->proto = htons(PROTO_VJCOMP); 45430715Sbrian memcpy(nakp+2, &pcomp, 2); 4556059Samurai nakp += length; 4566059Samurai } 4576059Samurai break; 45828679Sbrian case 6: /* RFC1332 */ 4596059Samurai if (ntohs(pcomp->proto) == PROTO_VJCOMP 46028679Sbrian && pcomp->slots < MAX_STATES && pcomp->slots > 2) { 4616059Samurai IpcpInfo.his_compproto = compproto; 4626059Samurai IpcpInfo.heis1172 = 0; 46330715Sbrian memcpy(ackp, cp, length); 4646059Samurai ackp += length; 4656059Samurai } else { 46630715Sbrian memcpy(nakp, cp, 2); 4676059Samurai pcomp->proto = htons(PROTO_VJCOMP); 4686059Samurai pcomp->slots = MAX_STATES - 1; 4696059Samurai pcomp->compcid = 0; 47030715Sbrian memcpy(nakp+2, &pcomp, sizeof(pcomp)); 4716059Samurai nakp += length; 4726059Samurai } 4736059Samurai break; 4746059Samurai default: 47530715Sbrian memcpy(rejp, cp, length); 4766059Samurai rejp += length; 4776059Samurai break; 4786059Samurai } 4796059Samurai } 4806059Samurai break; 4816059Samurai case MODE_NAK: 48228461Sbrian LogPrintf(LogIPCP, "%s changing compproto: %08x --> %08x\n", 48328679Sbrian tbuff, IpcpInfo.want_compproto, compproto); 4846059Samurai IpcpInfo.want_compproto = compproto; 4856059Samurai break; 4866059Samurai case MODE_REJ: 4876059Samurai IpcpInfo.his_reject |= (1 << type); 4886059Samurai break; 4896059Samurai } 4906059Samurai break; 49128679Sbrian case TY_IPADDRS: /* RFC1172 */ 49228679Sbrian lp = (u_long *) (cp + 2); 4936059Samurai ipaddr.s_addr = *lp; 49428679Sbrian lp = (u_long *) (cp + 6); 4956059Samurai dstipaddr.s_addr = *lp; 49628974Sbrian snprintf(tbuff2, sizeof(tbuff2), "%s %s,", tbuff, inet_ntoa(ipaddr)); 49728974Sbrian LogPrintf(LogIPCP, "%s %s\n", tbuff2, inet_ntoa(dstipaddr)); 4986059Samurai 49931034Sbrian switch (mode_type) { 5006059Samurai case MODE_REQ: 5016059Samurai IpcpInfo.his_ipaddr = ipaddr; 5026059Samurai IpcpInfo.want_ipaddr = dstipaddr; 50330715Sbrian memcpy(ackp, cp, length); 5046059Samurai ackp += length; 5056059Samurai break; 5066059Samurai case MODE_NAK: 50728974Sbrian snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s", tbuff, 50828974Sbrian inet_ntoa(IpcpInfo.want_ipaddr)); 50928974Sbrian LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 5106059Samurai IpcpInfo.want_ipaddr = ipaddr; 5116059Samurai IpcpInfo.his_ipaddr = dstipaddr; 5126059Samurai break; 5136059Samurai case MODE_REJ: 5146059Samurai IpcpInfo.his_reject |= (1 << type); 5156059Samurai break; 5166059Samurai } 5176059Samurai break; 51818752Sjkh 51928679Sbrian /* 52028679Sbrian * MS extensions for MS's PPP 52128679Sbrian */ 52218752Sjkh 52326516Sbrian#ifndef NOMSEXT 52428679Sbrian case TY_PRIMARY_DNS: /* MS PPP DNS negotiation hack */ 52518752Sjkh case TY_SECONDARY_DNS: 52628679Sbrian if (!Enabled(ConfMSExt)) { 52728461Sbrian LogPrintf(LogIPCP, "MS NS req - rejected - msext disabled\n"); 52828679Sbrian IpcpInfo.my_reject |= (1 << type); 52930715Sbrian memcpy(rejp, cp, length); 53018752Sjkh rejp += length; 53118752Sjkh break; 53218752Sjkh } 53331034Sbrian switch (mode_type) { 53418752Sjkh case MODE_REQ: 53528679Sbrian lp = (u_long *) (cp + 2); 53618752Sjkh dnsstuff.s_addr = *lp; 53728679Sbrian ms_info_req.s_addr = ns_entries[((type - TY_PRIMARY_DNS) ? 1 : 0)].s_addr; 53828679Sbrian if (dnsstuff.s_addr != ms_info_req.s_addr) { 53928679Sbrian 54018752Sjkh /* 54128679Sbrian * So the client has got the DNS stuff wrong (first request) so 54228974Sbrian * we'll tell 'em how it is 54328679Sbrian */ 54430715Sbrian memcpy(nakp, cp, 2); /* copy first two (type/length) */ 54528679Sbrian LogPrintf(LogIPCP, "MS NS req %d:%s->%s - nak\n", 54628679Sbrian type, 54728679Sbrian inet_ntoa(dnsstuff), 54828679Sbrian inet_ntoa(ms_info_req)); 54930715Sbrian memcpy(nakp+2, &ms_info_req, length); 55018752Sjkh nakp += length; 55118752Sjkh break; 55218752Sjkh } 55328679Sbrian 55428679Sbrian /* 55528679Sbrian * Otherwise they have it right (this time) so we send a ack packet 55628679Sbrian * back confirming it... end of story 55728679Sbrian */ 55828679Sbrian LogPrintf(LogIPCP, "MS NS req %d:%s ok - ack\n", 55928679Sbrian type, 56028679Sbrian inet_ntoa(ms_info_req)); 56130715Sbrian memcpy(ackp, cp, length); 56218752Sjkh ackp += length; 56318752Sjkh break; 56428679Sbrian case MODE_NAK: /* what does this mean?? */ 56528679Sbrian LogPrintf(LogIPCP, "MS NS req %d - NAK??\n", type); 56618752Sjkh break; 56728679Sbrian case MODE_REJ: /* confused?? me to :) */ 56828679Sbrian LogPrintf(LogIPCP, "MS NS req %d - REJ??\n", type); 56918752Sjkh break; 57018752Sjkh } 57118752Sjkh break; 57218752Sjkh 57328679Sbrian case TY_PRIMARY_NBNS: /* MS PPP NetBIOS nameserver hack */ 57418752Sjkh case TY_SECONDARY_NBNS: 57528679Sbrian if (!Enabled(ConfMSExt)) { 57628679Sbrian LogPrintf(LogIPCP, "MS NBNS req - rejected - msext disabled\n"); 57728679Sbrian IpcpInfo.my_reject |= (1 << type); 57830715Sbrian memcpy(rejp, cp, length); 57928679Sbrian rejp += length; 58028679Sbrian break; 58128679Sbrian } 58231034Sbrian switch (mode_type) { 58318752Sjkh case MODE_REQ: 58428679Sbrian lp = (u_long *) (cp + 2); 58518752Sjkh dnsstuff.s_addr = *lp; 58628679Sbrian ms_info_req.s_addr = nbns_entries[((type - TY_PRIMARY_NBNS) ? 1 : 0)].s_addr; 58728679Sbrian if (dnsstuff.s_addr != ms_info_req.s_addr) { 58830715Sbrian memcpy(nakp, cp, 2); 58930715Sbrian memcpy(nakp+2, &ms_info_req.s_addr, length); 59028461Sbrian LogPrintf(LogIPCP, "MS NBNS req %d:%s->%s - nak\n", 59128679Sbrian type, 59228679Sbrian inet_ntoa(dnsstuff), 59328679Sbrian inet_ntoa(ms_info_req)); 59418752Sjkh nakp += length; 59518752Sjkh break; 59618752Sjkh } 59728461Sbrian LogPrintf(LogIPCP, "MS NBNS req %d:%s ok - ack\n", 59828679Sbrian type, 59928679Sbrian inet_ntoa(ms_info_req)); 60030715Sbrian memcpy(ackp, cp, length); 60118752Sjkh ackp += length; 60218752Sjkh break; 60318752Sjkh case MODE_NAK: 60428679Sbrian LogPrintf(LogIPCP, "MS NBNS req %d - NAK??\n", type); 60518752Sjkh break; 60618752Sjkh case MODE_REJ: 60728679Sbrian LogPrintf(LogIPCP, "MS NBNS req %d - REJ??\n", type); 60818752Sjkh break; 60918752Sjkh } 61018752Sjkh break; 61118752Sjkh 61226516Sbrian#endif 61318752Sjkh 6146059Samurai default: 6156059Samurai IpcpInfo.my_reject |= (1 << type); 61630715Sbrian memcpy(rejp, cp, length); 6176059Samurai rejp += length; 6186059Samurai break; 6196059Samurai } 6206059Samurai plen -= length; 6216059Samurai cp += length; 6226059Samurai } 6236059Samurai} 6246059Samurai 6256059Samuraivoid 62628679SbrianIpcpInput(struct mbuf * bp) 6276059Samurai{ 6286059Samurai FsmInput(&IpcpFsm, bp); 6296059Samurai} 630