1/* 2 * PPP IP Control Protocol (IPCP) Module 3 * 4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5 * 6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the Internet Initiative Japan, Inc. The name of the 14 * IIJ may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 *
| 1/* 2 * PPP IP Control Protocol (IPCP) Module 3 * 4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5 * 6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the Internet Initiative Japan, Inc. The name of the 14 * IIJ may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 *
|
20 * $Id: ipcp.c,v 1.35 1997/11/11 22:58:11 brian Exp $
| 20 * $Id: ipcp.c,v 1.36 1997/11/14 15:39:14 brian Exp $
|
21 * 22 * TODO: 23 * o More RFC1772 backwoard compatibility 24 */ 25#include <sys/param.h> 26#include <netinet/in_systm.h> 27#include <netinet/in.h> 28#include <netinet/ip.h> 29#include <arpa/inet.h> 30#include <sys/socket.h> 31#include <netdb.h> 32 33#include <limits.h> 34#include <stdio.h> 35#include <string.h>
| 21 * 22 * TODO: 23 * o More RFC1772 backwoard compatibility 24 */ 25#include <sys/param.h> 26#include <netinet/in_systm.h> 27#include <netinet/in.h> 28#include <netinet/ip.h> 29#include <arpa/inet.h> 30#include <sys/socket.h> 31#include <netdb.h> 32 33#include <limits.h> 34#include <stdio.h> 35#include <string.h>
|
| 36#include <time.h>
|
36#include <unistd.h> 37 38#include "mbuf.h" 39#include "log.h" 40#include "defs.h" 41#include "timer.h" 42#include "fsm.h" 43#include "lcpproto.h" 44#include "lcp.h" 45#include "ipcp.h" 46#include "slcompress.h" 47#include "os.h" 48#include "phase.h" 49#include "loadalias.h" 50#include "command.h" 51#include "vars.h" 52#include "vjcomp.h" 53#include "ip.h"
| 37#include <unistd.h> 38 39#include "mbuf.h" 40#include "log.h" 41#include "defs.h" 42#include "timer.h" 43#include "fsm.h" 44#include "lcpproto.h" 45#include "lcp.h" 46#include "ipcp.h" 47#include "slcompress.h" 48#include "os.h" 49#include "phase.h" 50#include "loadalias.h" 51#include "command.h" 52#include "vars.h" 53#include "vjcomp.h" 54#include "ip.h"
|
| 55#include "throughput.h"
|
54 55#ifndef NOMSEXT 56struct in_addr ns_entries[2]; 57struct in_addr nbns_entries[2]; 58#endif 59 60struct ipcpstate IpcpInfo; 61struct in_range DefMyAddress; 62struct in_range DefHisAddress; 63struct in_addr TriggerAddress; 64int HaveTriggerAddress;
| 56 57#ifndef NOMSEXT 58struct in_addr ns_entries[2]; 59struct in_addr nbns_entries[2]; 60#endif 61 62struct ipcpstate IpcpInfo; 63struct in_range DefMyAddress; 64struct in_range DefHisAddress; 65struct in_addr TriggerAddress; 66int HaveTriggerAddress;
|
65struct pppTimer IpcpReportTimer;
| |
66 67static void IpcpSendConfigReq(struct fsm *); 68static void IpcpSendTerminateAck(struct fsm *); 69static void IpcpSendTerminateReq(struct fsm *); 70static void IpcpDecodeConfig(u_char *, int, int); 71static void IpcpLayerStart(struct fsm *); 72static void IpcpLayerFinish(struct fsm *); 73static void IpcpLayerUp(struct fsm *); 74static void IpcpLayerDown(struct fsm *); 75static void IpcpInitRestartCounter(struct fsm *);
| 67 68static void IpcpSendConfigReq(struct fsm *); 69static void IpcpSendTerminateAck(struct fsm *); 70static void IpcpSendTerminateReq(struct fsm *); 71static void IpcpDecodeConfig(u_char *, int, int); 72static void IpcpLayerStart(struct fsm *); 73static void IpcpLayerFinish(struct fsm *); 74static void IpcpLayerUp(struct fsm *); 75static void IpcpLayerDown(struct fsm *); 76static void IpcpInitRestartCounter(struct fsm *);
|
76static int IpcpOctetsIn(void); 77static int IpcpOctetsOut(void);
| |
78
| 77
|
79static int lastInOctets, lastOutOctets; 80static int StartingIpIn, StartingIpOut; 81
| |
82#define REJECTED(p, x) (p->his_reject & (1<<x)) 83 84struct fsm IpcpFsm = { 85 "IPCP", 86 PROTO_IPCP, 87 IPCP_MAXCODE, 88 OPEN_ACTIVE, 89 ST_INITIAL, 90 0, 0, 0, 91 92 0, 93 {0, 0, 0, NULL, NULL, NULL}, 94 {0, 0, 0, NULL, NULL, NULL}, 95 LogIPCP, 96 97 IpcpLayerUp, 98 IpcpLayerDown, 99 IpcpLayerStart, 100 IpcpLayerFinish, 101 IpcpInitRestartCounter, 102 IpcpSendConfigReq, 103 IpcpSendTerminateReq, 104 IpcpSendTerminateAck, 105 IpcpDecodeConfig, 106}; 107 108static char *cftypes[] = { 109 /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ 110 "???", 111 "IPADDRS", /* 1: IP-Addresses */ /* deprecated */ 112 "COMPPROTO", /* 2: IP-Compression-Protocol */ 113 "IPADDR", /* 3: IP-Address */ 114}; 115 116#define NCFTYPES (sizeof(cftypes)/sizeof(char *)) 117 118static char *cftypes128[] = { 119 /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ 120 "???", 121 "PRIDNS", /* 129: Primary DNS Server Address */ 122 "PRINBNS", /* 130: Primary NBNS Server Address */ 123 "SECDNS", /* 131: Secondary DNS Server Address */ 124 "SECNBNS", /* 132: Secondary NBNS Server Address */ 125}; 126 127#define NCFTYPES128 (sizeof(cftypes)/sizeof(char *)) 128
| 78#define REJECTED(p, x) (p->his_reject & (1<<x)) 79 80struct fsm IpcpFsm = { 81 "IPCP", 82 PROTO_IPCP, 83 IPCP_MAXCODE, 84 OPEN_ACTIVE, 85 ST_INITIAL, 86 0, 0, 0, 87 88 0, 89 {0, 0, 0, NULL, NULL, NULL}, 90 {0, 0, 0, NULL, NULL, NULL}, 91 LogIPCP, 92 93 IpcpLayerUp, 94 IpcpLayerDown, 95 IpcpLayerStart, 96 IpcpLayerFinish, 97 IpcpInitRestartCounter, 98 IpcpSendConfigReq, 99 IpcpSendTerminateReq, 100 IpcpSendTerminateAck, 101 IpcpDecodeConfig, 102}; 103 104static char *cftypes[] = { 105 /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ 106 "???", 107 "IPADDRS", /* 1: IP-Addresses */ /* deprecated */ 108 "COMPPROTO", /* 2: IP-Compression-Protocol */ 109 "IPADDR", /* 3: IP-Address */ 110}; 111 112#define NCFTYPES (sizeof(cftypes)/sizeof(char *)) 113 114static char *cftypes128[] = { 115 /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */ 116 "???", 117 "PRIDNS", /* 129: Primary DNS Server Address */ 118 "PRINBNS", /* 130: Primary NBNS Server Address */ 119 "SECDNS", /* 131: Secondary DNS Server Address */ 120 "SECNBNS", /* 132: Secondary NBNS Server Address */ 121}; 122 123#define NCFTYPES128 (sizeof(cftypes)/sizeof(char *)) 124
|
129/* 130 * Function called every second. Updates connection period and idle period, 131 * also update LQR information. 132 */ 133static void 134IpcpReportFunc()
| 125struct pppThroughput throughput; 126 127void 128IpcpAddInOctets(int n)
|
135{
| 129{
|
136 ipConnectSecs++; 137 if (lastInOctets == ipInOctets && lastOutOctets == ipOutOctets) 138 ipIdleSecs++; 139 lastInOctets = ipInOctets; 140 lastOutOctets = ipOutOctets; 141 StopTimer(&IpcpReportTimer); 142 IpcpReportTimer.state = TIMER_STOPPED; 143 StartTimer(&IpcpReportTimer);
| 130 throughput_addin(&throughput, n);
|
144} 145
| 131} 132
|
146static void 147IpcpStartReport()
| 133void 134IpcpAddOutOctets(int n)
|
148{
| 135{
|
149 ipIdleSecs = ipConnectSecs = 0; 150 StopTimer(&IpcpReportTimer); 151 IpcpReportTimer.state = TIMER_STOPPED; 152 IpcpReportTimer.load = SECTICKS; 153 IpcpReportTimer.func = IpcpReportFunc; 154 StartTimer(&IpcpReportTimer);
| 136 throughput_addout(&throughput, n);
|
155} 156 157int 158ReportIpcpStatus() 159{ 160 struct ipcpstate *icp = &IpcpInfo; 161 struct fsm *fp = &IpcpFsm; 162 163 if (!VarTerm) 164 return 1; 165 fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]); 166 fprintf(VarTerm, " his side: %s, %lx\n", 167 inet_ntoa(icp->his_ipaddr), icp->his_compproto); 168 fprintf(VarTerm, " my side: %s, %lx\n", 169 inet_ntoa(icp->want_ipaddr), icp->want_compproto);
| 137} 138 139int 140ReportIpcpStatus() 141{ 142 struct ipcpstate *icp = &IpcpInfo; 143 struct fsm *fp = &IpcpFsm; 144 145 if (!VarTerm) 146 return 1; 147 fprintf(VarTerm, "%s [%s]\n", fp->name, StateNames[fp->state]); 148 fprintf(VarTerm, " his side: %s, %lx\n", 149 inet_ntoa(icp->his_ipaddr), icp->his_compproto); 150 fprintf(VarTerm, " my side: %s, %lx\n", 151 inet_ntoa(icp->want_ipaddr), icp->want_compproto);
|
170 fprintf(VarTerm, "Connected: %d secs, idle: %d secs\n\n", 171 ipConnectSecs, ipIdleSecs); 172 fprintf(VarTerm, " %d octets in, %d octets out\n", 173 IpcpOctetsIn(), IpcpOctetsOut());
| |
174 175 fprintf(VarTerm, "Defaults:\n"); 176 fprintf(VarTerm, " My Address: %s/%d\n", 177 inet_ntoa(DefMyAddress.ipaddr), DefMyAddress.width); 178 fprintf(VarTerm, " His Address: %s/%d\n", 179 inet_ntoa(DefHisAddress.ipaddr), DefHisAddress.width); 180 if (HaveTriggerAddress) 181 fprintf(VarTerm, " Negotiation(trigger): %s\n", inet_ntoa(TriggerAddress)); 182 else 183 fprintf(VarTerm, " Negotiation(trigger): MYADDR\n"); 184
| 152 153 fprintf(VarTerm, "Defaults:\n"); 154 fprintf(VarTerm, " My Address: %s/%d\n", 155 inet_ntoa(DefMyAddress.ipaddr), DefMyAddress.width); 156 fprintf(VarTerm, " His Address: %s/%d\n", 157 inet_ntoa(DefHisAddress.ipaddr), DefHisAddress.width); 158 if (HaveTriggerAddress) 159 fprintf(VarTerm, " Negotiation(trigger): %s\n", inet_ntoa(TriggerAddress)); 160 else 161 fprintf(VarTerm, " Negotiation(trigger): MYADDR\n"); 162
|
| 163 fprintf(VarTerm, "\n"); 164 throughput_disp(&throughput, VarTerm); 165
|
185 return 0; 186} 187 188void 189IpcpDefAddress() 190{ 191 struct hostent *hp; 192 char name[200]; 193 194 memset(&DefMyAddress, '\0', sizeof(DefMyAddress)); 195 memset(&DefHisAddress, '\0', sizeof(DefHisAddress)); 196 TriggerAddress.s_addr = 0; 197 HaveTriggerAddress = 0; 198 if (gethostname(name, sizeof(name)) == 0) { 199 hp = gethostbyname(name); 200 if (hp && hp->h_addrtype == AF_INET) { 201 memcpy(&DefMyAddress.ipaddr.s_addr, hp->h_addr, hp->h_length); 202 } 203 } 204} 205 206void 207IpcpInit() 208{ 209 struct ipcpstate *icp = &IpcpInfo; 210 211 FsmInit(&IpcpFsm); 212 memset(icp, '\0', sizeof(struct ipcpstate)); 213 if ((mode & MODE_DEDICATED) && !GetLabel()) { 214 icp->want_ipaddr.s_addr = icp->his_ipaddr.s_addr = 0; 215 } else { 216 icp->want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr; 217 icp->his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr; 218 } 219 220 /* 221 * Some implementations of PPP require that we send a 222 * *special* value as our address, even though the rfc specifies 223 * full negotiation (e.g. "0.0.0.0" or Not "0.0.0.0"). 224 */ 225 if (HaveTriggerAddress) { 226 icp->want_ipaddr.s_addr = TriggerAddress.s_addr; 227 LogPrintf(LogIPCP, "Using trigger address %s\n", inet_ntoa(TriggerAddress)); 228 } 229 if (Enabled(ConfVjcomp)) 230 icp->want_compproto = (PROTO_VJCOMP << 16) | ((MAX_STATES - 1) << 8) | 1; 231 else 232 icp->want_compproto = 0; 233 icp->heis1172 = 0; 234 IpcpFsm.maxconfig = 10;
| 166 return 0; 167} 168 169void 170IpcpDefAddress() 171{ 172 struct hostent *hp; 173 char name[200]; 174 175 memset(&DefMyAddress, '\0', sizeof(DefMyAddress)); 176 memset(&DefHisAddress, '\0', sizeof(DefHisAddress)); 177 TriggerAddress.s_addr = 0; 178 HaveTriggerAddress = 0; 179 if (gethostname(name, sizeof(name)) == 0) { 180 hp = gethostbyname(name); 181 if (hp && hp->h_addrtype == AF_INET) { 182 memcpy(&DefMyAddress.ipaddr.s_addr, hp->h_addr, hp->h_length); 183 } 184 } 185} 186 187void 188IpcpInit() 189{ 190 struct ipcpstate *icp = &IpcpInfo; 191 192 FsmInit(&IpcpFsm); 193 memset(icp, '\0', sizeof(struct ipcpstate)); 194 if ((mode & MODE_DEDICATED) && !GetLabel()) { 195 icp->want_ipaddr.s_addr = icp->his_ipaddr.s_addr = 0; 196 } else { 197 icp->want_ipaddr.s_addr = DefMyAddress.ipaddr.s_addr; 198 icp->his_ipaddr.s_addr = DefHisAddress.ipaddr.s_addr; 199 } 200 201 /* 202 * Some implementations of PPP require that we send a 203 * *special* value as our address, even though the rfc specifies 204 * full negotiation (e.g. "0.0.0.0" or Not "0.0.0.0"). 205 */ 206 if (HaveTriggerAddress) { 207 icp->want_ipaddr.s_addr = TriggerAddress.s_addr; 208 LogPrintf(LogIPCP, "Using trigger address %s\n", inet_ntoa(TriggerAddress)); 209 } 210 if (Enabled(ConfVjcomp)) 211 icp->want_compproto = (PROTO_VJCOMP << 16) | ((MAX_STATES - 1) << 8) | 1; 212 else 213 icp->want_compproto = 0; 214 icp->heis1172 = 0; 215 IpcpFsm.maxconfig = 10;
|
235 StartingIpIn = ipInOctets; 236 StartingIpOut = ipOutOctets;
| 216 throughput_init(&throughput);
|
237} 238 239static void 240IpcpInitRestartCounter(struct fsm * fp) 241{ 242 fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 243 fp->restart = 5; 244} 245 246static void 247IpcpSendConfigReq(struct fsm * fp) 248{ 249 u_char *cp; 250 struct ipcpstate *icp = &IpcpInfo; 251 252 cp = ReqBuff; 253 LogPrintf(LogIPCP, "IpcpSendConfigReq\n"); 254 if (!DEV_IS_SYNC || !REJECTED(icp, TY_IPADDR)) 255 PutConfValue(LogIPCP, &cp, cftypes, TY_IPADDR, 6, 256 ntohl(icp->want_ipaddr.s_addr)); 257 if (icp->want_compproto && !REJECTED(icp, TY_COMPPROTO)) { 258 if (icp->heis1172) 259 PutConfValue(LogIPCP, &cp, cftypes, TY_COMPPROTO, 4, 260 icp->want_compproto >> 16); 261 else 262 PutConfValue(LogIPCP, &cp, cftypes, TY_COMPPROTO, 6, icp->want_compproto); 263 } 264 FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 265} 266 267static void 268IpcpSendTerminateReq(struct fsm * fp) 269{ 270 /* XXX: No code yet */ 271} 272 273static void 274IpcpSendTerminateAck(struct fsm * fp) 275{ 276 LogPrintf(LogIPCP, "IpcpSendTerminateAck\n"); 277 FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 278} 279 280static void 281IpcpLayerStart(struct fsm * fp) 282{ 283 LogPrintf(LogIPCP, "IpcpLayerStart.\n"); 284} 285 286static void 287IpcpLayerFinish(struct fsm * fp) 288{ 289 LogPrintf(LogIPCP, "IpcpLayerFinish.\n"); 290 reconnect(RECON_FALSE); 291 LcpClose(); 292 NewPhase(PHASE_TERMINATE); 293} 294
| 217} 218 219static void 220IpcpInitRestartCounter(struct fsm * fp) 221{ 222 fp->FsmTimer.load = VarRetryTimeout * SECTICKS; 223 fp->restart = 5; 224} 225 226static void 227IpcpSendConfigReq(struct fsm * fp) 228{ 229 u_char *cp; 230 struct ipcpstate *icp = &IpcpInfo; 231 232 cp = ReqBuff; 233 LogPrintf(LogIPCP, "IpcpSendConfigReq\n"); 234 if (!DEV_IS_SYNC || !REJECTED(icp, TY_IPADDR)) 235 PutConfValue(LogIPCP, &cp, cftypes, TY_IPADDR, 6, 236 ntohl(icp->want_ipaddr.s_addr)); 237 if (icp->want_compproto && !REJECTED(icp, TY_COMPPROTO)) { 238 if (icp->heis1172) 239 PutConfValue(LogIPCP, &cp, cftypes, TY_COMPPROTO, 4, 240 icp->want_compproto >> 16); 241 else 242 PutConfValue(LogIPCP, &cp, cftypes, TY_COMPPROTO, 6, icp->want_compproto); 243 } 244 FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff); 245} 246 247static void 248IpcpSendTerminateReq(struct fsm * fp) 249{ 250 /* XXX: No code yet */ 251} 252 253static void 254IpcpSendTerminateAck(struct fsm * fp) 255{ 256 LogPrintf(LogIPCP, "IpcpSendTerminateAck\n"); 257 FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0); 258} 259 260static void 261IpcpLayerStart(struct fsm * fp) 262{ 263 LogPrintf(LogIPCP, "IpcpLayerStart.\n"); 264} 265 266static void 267IpcpLayerFinish(struct fsm * fp) 268{ 269 LogPrintf(LogIPCP, "IpcpLayerFinish.\n"); 270 reconnect(RECON_FALSE); 271 LcpClose(); 272 NewPhase(PHASE_TERMINATE); 273} 274
|
295static int 296IpcpOctetsIn() 297{ 298 return ipInOctets < StartingIpIn ? 299 INT_MAX - StartingIpIn + ipInOctets - INT_MIN + 1 : 300 ipInOctets - StartingIpIn; 301} 302 303static int 304IpcpOctetsOut() 305{ 306 return ipOutOctets < StartingIpOut ? 307 INT_MAX - StartingIpOut + ipOutOctets - INT_MIN + 1 : 308 ipOutOctets - StartingIpOut; 309} 310
| |
311static void 312IpcpLayerDown(struct fsm * fp) 313{ 314 LogPrintf(LogIPCP, "IpcpLayerDown.\n");
| 275static void 276IpcpLayerDown(struct fsm * fp) 277{ 278 LogPrintf(LogIPCP, "IpcpLayerDown.\n");
|
315 LogPrintf(LogIPCP, "%d octets in, %d octets out\n", 316 IpcpOctetsIn(), IpcpOctetsOut()); 317 StopTimer(&IpcpReportTimer); 318 Prompt();
| 279 throughput_stop(&throughput); 280 throughput_log(&throughput, LogIPCP, NULL);
|
319} 320 321/* 322 * Called when IPCP has reached to OPEN state 323 */ 324static void 325IpcpLayerUp(struct fsm * fp) 326{ 327 char tbuff[100]; 328 329 Prompt(); 330 LogPrintf(LogIPCP, "IpcpLayerUp(%d).\n", fp->state); 331 snprintf(tbuff, sizeof(tbuff), "myaddr = %s ", 332 inet_ntoa(IpcpInfo.want_ipaddr)); 333 334 if (IpcpInfo.his_compproto >> 16 == PROTO_VJCOMP) 335 VjInit((IpcpInfo.his_compproto >> 8) & 255); 336 337 LogPrintf(LogIsKept(LogIPCP) ? LogIPCP : LogLINK, " %s hisaddr = %s\n", 338 tbuff, inet_ntoa(IpcpInfo.his_ipaddr)); 339 if (OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr, ifnetmask) < 0) { 340 if (VarTerm) 341 LogPrintf(LogERROR, "IpcpLayerUp: unable to set ip address\n"); 342 return; 343 } 344 if (mode & MODE_ALIAS) 345 VarPacketAliasSetAddress(IpcpInfo.want_ipaddr); 346 OsLinkup();
| 281} 282 283/* 284 * Called when IPCP has reached to OPEN state 285 */ 286static void 287IpcpLayerUp(struct fsm * fp) 288{ 289 char tbuff[100]; 290 291 Prompt(); 292 LogPrintf(LogIPCP, "IpcpLayerUp(%d).\n", fp->state); 293 snprintf(tbuff, sizeof(tbuff), "myaddr = %s ", 294 inet_ntoa(IpcpInfo.want_ipaddr)); 295 296 if (IpcpInfo.his_compproto >> 16 == PROTO_VJCOMP) 297 VjInit((IpcpInfo.his_compproto >> 8) & 255); 298 299 LogPrintf(LogIsKept(LogIPCP) ? LogIPCP : LogLINK, " %s hisaddr = %s\n", 300 tbuff, inet_ntoa(IpcpInfo.his_ipaddr)); 301 if (OsSetIpaddress(IpcpInfo.want_ipaddr, IpcpInfo.his_ipaddr, ifnetmask) < 0) { 302 if (VarTerm) 303 LogPrintf(LogERROR, "IpcpLayerUp: unable to set ip address\n"); 304 return; 305 } 306 if (mode & MODE_ALIAS) 307 VarPacketAliasSetAddress(IpcpInfo.want_ipaddr); 308 OsLinkup();
|
347 StartingIpIn = ipInOctets; 348 StartingIpOut = ipOutOctets; 349 IpcpStartReport();
| 309 throughput_start(&throughput);
|
350 StartIdleTimer(); 351} 352 353void 354IpcpUp() 355{ 356 FsmUp(&IpcpFsm); 357 LogPrintf(LogIPCP, "IPCP Up event!!\n"); 358} 359 360void 361IpcpOpen() 362{ 363 FsmOpen(&IpcpFsm); 364} 365 366static int 367AcceptableAddr(struct in_range * prange, struct in_addr ipaddr) 368{ 369 LogPrintf(LogDEBUG, "requested = %x\n", htonl(ipaddr.s_addr)); 370 LogPrintf(LogDEBUG, "range = %x\n", htonl(prange->ipaddr.s_addr)); 371 LogPrintf(LogDEBUG, "/%x\n", htonl(prange->mask.s_addr)); 372 LogPrintf(LogDEBUG, "%x, %x\n", htonl(prange->ipaddr.s_addr & prange-> 373 mask.s_addr), htonl(ipaddr.s_addr & prange->mask.s_addr)); 374 return (prange->ipaddr.s_addr & prange->mask.s_addr) == 375 (ipaddr.s_addr & prange->mask.s_addr) && ipaddr.s_addr; 376} 377 378static void 379IpcpDecodeConfig(u_char * cp, int plen, int mode_type) 380{ 381 int type, length; 382 u_long *lp, compproto; 383 struct compreq *pcomp; 384 struct in_addr ipaddr, dstipaddr, dnsstuff, ms_info_req; 385 char tbuff[100]; 386 char tbuff2[100]; 387 388 ackp = AckBuff; 389 nakp = NakBuff; 390 rejp = RejBuff; 391 392 while (plen >= sizeof(struct fsmconfig)) { 393 type = *cp; 394 length = cp[1]; 395 if (type < NCFTYPES) 396 snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); 397 else if (type > 128 && type < 128 + NCFTYPES128) 398 snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes128[type], length); 399 else 400 snprintf(tbuff, sizeof(tbuff), " ??? "); 401 402 switch (type) { 403 case TY_IPADDR: /* RFC1332 */ 404 lp = (u_long *) (cp + 2); 405 ipaddr.s_addr = *lp; 406 LogPrintf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 407 408 switch (mode_type) { 409 case MODE_REQ: 410 if (!AcceptableAddr(&DefHisAddress, ipaddr)) { 411 /* 412 * If destination address is not acceptable, insist to use what we 413 * want to use. 414 */ 415 memcpy(nakp, cp, 2); 416 memcpy(nakp+2, &IpcpInfo.his_ipaddr.s_addr, length); 417 nakp += length; 418 break; 419 } 420 IpcpInfo.his_ipaddr = ipaddr; 421 memcpy(ackp, cp, length); 422 ackp += length; 423 break; 424 case MODE_NAK: 425 if (AcceptableAddr(&DefMyAddress, ipaddr)) { 426 427 /* 428 * Use address suggested by peer. 429 */ 430 snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s ", tbuff, 431 inet_ntoa(IpcpInfo.want_ipaddr)); 432 LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 433 IpcpInfo.want_ipaddr = ipaddr; 434 } 435 break; 436 case MODE_REJ: 437 IpcpInfo.his_reject |= (1 << type); 438 break; 439 } 440 break; 441 case TY_COMPPROTO: 442 lp = (u_long *) (cp + 2); 443 compproto = htonl(*lp); 444 LogPrintf(LogIPCP, "%s %08x\n", tbuff, compproto); 445 446 switch (mode_type) { 447 case MODE_REQ: 448 if (!Acceptable(ConfVjcomp)) { 449 memcpy(rejp, cp, length); 450 rejp += length; 451 } else { 452 pcomp = (struct compreq *) (cp + 2); 453 switch (length) { 454 case 4: /* RFC1172 */ 455 if (ntohs(pcomp->proto) == PROTO_VJCOMP) { 456 LogPrintf(LogWARN, "Peer is speaking RFC1172 compression protocol !\n"); 457 IpcpInfo.heis1172 = 1; 458 IpcpInfo.his_compproto = compproto; 459 memcpy(ackp, cp, length); 460 ackp += length; 461 } else { 462 memcpy(nakp, cp, 2); 463 pcomp->proto = htons(PROTO_VJCOMP); 464 memcpy(nakp+2, &pcomp, 2); 465 nakp += length; 466 } 467 break; 468 case 6: /* RFC1332 */ 469 if (ntohs(pcomp->proto) == PROTO_VJCOMP 470 && pcomp->slots < MAX_STATES && pcomp->slots > 2) { 471 IpcpInfo.his_compproto = compproto; 472 IpcpInfo.heis1172 = 0; 473 memcpy(ackp, cp, length); 474 ackp += length; 475 } else { 476 memcpy(nakp, cp, 2); 477 pcomp->proto = htons(PROTO_VJCOMP); 478 pcomp->slots = MAX_STATES - 1; 479 pcomp->compcid = 0; 480 memcpy(nakp+2, &pcomp, sizeof(pcomp)); 481 nakp += length; 482 } 483 break; 484 default: 485 memcpy(rejp, cp, length); 486 rejp += length; 487 break; 488 } 489 } 490 break; 491 case MODE_NAK: 492 LogPrintf(LogIPCP, "%s changing compproto: %08x --> %08x\n", 493 tbuff, IpcpInfo.want_compproto, compproto); 494 IpcpInfo.want_compproto = compproto; 495 break; 496 case MODE_REJ: 497 IpcpInfo.his_reject |= (1 << type); 498 break; 499 } 500 break; 501 case TY_IPADDRS: /* RFC1172 */ 502 lp = (u_long *) (cp + 2); 503 ipaddr.s_addr = *lp; 504 lp = (u_long *) (cp + 6); 505 dstipaddr.s_addr = *lp; 506 snprintf(tbuff2, sizeof(tbuff2), "%s %s,", tbuff, inet_ntoa(ipaddr)); 507 LogPrintf(LogIPCP, "%s %s\n", tbuff2, inet_ntoa(dstipaddr)); 508 509 switch (mode_type) { 510 case MODE_REQ: 511 IpcpInfo.his_ipaddr = ipaddr; 512 IpcpInfo.want_ipaddr = dstipaddr; 513 memcpy(ackp, cp, length); 514 ackp += length; 515 break; 516 case MODE_NAK: 517 snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s", tbuff, 518 inet_ntoa(IpcpInfo.want_ipaddr)); 519 LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 520 IpcpInfo.want_ipaddr = ipaddr; 521 IpcpInfo.his_ipaddr = dstipaddr; 522 break; 523 case MODE_REJ: 524 IpcpInfo.his_reject |= (1 << type); 525 break; 526 } 527 break; 528 529 /* 530 * MS extensions for MS's PPP 531 */ 532 533#ifndef NOMSEXT 534 case TY_PRIMARY_DNS: /* MS PPP DNS negotiation hack */ 535 case TY_SECONDARY_DNS: 536 if (!Enabled(ConfMSExt)) { 537 LogPrintf(LogIPCP, "MS NS req - rejected - msext disabled\n"); 538 IpcpInfo.my_reject |= (1 << type); 539 memcpy(rejp, cp, length); 540 rejp += length; 541 break; 542 } 543 switch (mode_type) { 544 case MODE_REQ: 545 lp = (u_long *) (cp + 2); 546 dnsstuff.s_addr = *lp; 547 ms_info_req.s_addr = ns_entries[((type - TY_PRIMARY_DNS) ? 1 : 0)].s_addr; 548 if (dnsstuff.s_addr != ms_info_req.s_addr) { 549 550 /* 551 * So the client has got the DNS stuff wrong (first request) so 552 * we'll tell 'em how it is 553 */ 554 memcpy(nakp, cp, 2); /* copy first two (type/length) */ 555 LogPrintf(LogIPCP, "MS NS req %d:%s->%s - nak\n", 556 type, 557 inet_ntoa(dnsstuff), 558 inet_ntoa(ms_info_req)); 559 memcpy(nakp+2, &ms_info_req, length); 560 nakp += length; 561 break; 562 } 563 564 /* 565 * Otherwise they have it right (this time) so we send a ack packet 566 * back confirming it... end of story 567 */ 568 LogPrintf(LogIPCP, "MS NS req %d:%s ok - ack\n", 569 type, 570 inet_ntoa(ms_info_req)); 571 memcpy(ackp, cp, length); 572 ackp += length; 573 break; 574 case MODE_NAK: /* what does this mean?? */ 575 LogPrintf(LogIPCP, "MS NS req %d - NAK??\n", type); 576 break; 577 case MODE_REJ: /* confused?? me to :) */ 578 LogPrintf(LogIPCP, "MS NS req %d - REJ??\n", type); 579 break; 580 } 581 break; 582 583 case TY_PRIMARY_NBNS: /* MS PPP NetBIOS nameserver hack */ 584 case TY_SECONDARY_NBNS: 585 if (!Enabled(ConfMSExt)) { 586 LogPrintf(LogIPCP, "MS NBNS req - rejected - msext disabled\n"); 587 IpcpInfo.my_reject |= (1 << type); 588 memcpy(rejp, cp, length); 589 rejp += length; 590 break; 591 } 592 switch (mode_type) { 593 case MODE_REQ: 594 lp = (u_long *) (cp + 2); 595 dnsstuff.s_addr = *lp; 596 ms_info_req.s_addr = nbns_entries[((type - TY_PRIMARY_NBNS) ? 1 : 0)].s_addr; 597 if (dnsstuff.s_addr != ms_info_req.s_addr) { 598 memcpy(nakp, cp, 2); 599 memcpy(nakp+2, &ms_info_req.s_addr, length); 600 LogPrintf(LogIPCP, "MS NBNS req %d:%s->%s - nak\n", 601 type, 602 inet_ntoa(dnsstuff), 603 inet_ntoa(ms_info_req)); 604 nakp += length; 605 break; 606 } 607 LogPrintf(LogIPCP, "MS NBNS req %d:%s ok - ack\n", 608 type, 609 inet_ntoa(ms_info_req)); 610 memcpy(ackp, cp, length); 611 ackp += length; 612 break; 613 case MODE_NAK: 614 LogPrintf(LogIPCP, "MS NBNS req %d - NAK??\n", type); 615 break; 616 case MODE_REJ: 617 LogPrintf(LogIPCP, "MS NBNS req %d - REJ??\n", type); 618 break; 619 } 620 break; 621 622#endif 623 624 default: 625 IpcpInfo.my_reject |= (1 << type); 626 memcpy(rejp, cp, length); 627 rejp += length; 628 break; 629 } 630 plen -= length; 631 cp += length; 632 } 633} 634 635void 636IpcpInput(struct mbuf * bp) 637{ 638 FsmInput(&IpcpFsm, bp); 639}
| 310 StartIdleTimer(); 311} 312 313void 314IpcpUp() 315{ 316 FsmUp(&IpcpFsm); 317 LogPrintf(LogIPCP, "IPCP Up event!!\n"); 318} 319 320void 321IpcpOpen() 322{ 323 FsmOpen(&IpcpFsm); 324} 325 326static int 327AcceptableAddr(struct in_range * prange, struct in_addr ipaddr) 328{ 329 LogPrintf(LogDEBUG, "requested = %x\n", htonl(ipaddr.s_addr)); 330 LogPrintf(LogDEBUG, "range = %x\n", htonl(prange->ipaddr.s_addr)); 331 LogPrintf(LogDEBUG, "/%x\n", htonl(prange->mask.s_addr)); 332 LogPrintf(LogDEBUG, "%x, %x\n", htonl(prange->ipaddr.s_addr & prange-> 333 mask.s_addr), htonl(ipaddr.s_addr & prange->mask.s_addr)); 334 return (prange->ipaddr.s_addr & prange->mask.s_addr) == 335 (ipaddr.s_addr & prange->mask.s_addr) && ipaddr.s_addr; 336} 337 338static void 339IpcpDecodeConfig(u_char * cp, int plen, int mode_type) 340{ 341 int type, length; 342 u_long *lp, compproto; 343 struct compreq *pcomp; 344 struct in_addr ipaddr, dstipaddr, dnsstuff, ms_info_req; 345 char tbuff[100]; 346 char tbuff2[100]; 347 348 ackp = AckBuff; 349 nakp = NakBuff; 350 rejp = RejBuff; 351 352 while (plen >= sizeof(struct fsmconfig)) { 353 type = *cp; 354 length = cp[1]; 355 if (type < NCFTYPES) 356 snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes[type], length); 357 else if (type > 128 && type < 128 + NCFTYPES128) 358 snprintf(tbuff, sizeof(tbuff), " %s[%d] ", cftypes128[type], length); 359 else 360 snprintf(tbuff, sizeof(tbuff), " ??? "); 361 362 switch (type) { 363 case TY_IPADDR: /* RFC1332 */ 364 lp = (u_long *) (cp + 2); 365 ipaddr.s_addr = *lp; 366 LogPrintf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 367 368 switch (mode_type) { 369 case MODE_REQ: 370 if (!AcceptableAddr(&DefHisAddress, ipaddr)) { 371 /* 372 * If destination address is not acceptable, insist to use what we 373 * want to use. 374 */ 375 memcpy(nakp, cp, 2); 376 memcpy(nakp+2, &IpcpInfo.his_ipaddr.s_addr, length); 377 nakp += length; 378 break; 379 } 380 IpcpInfo.his_ipaddr = ipaddr; 381 memcpy(ackp, cp, length); 382 ackp += length; 383 break; 384 case MODE_NAK: 385 if (AcceptableAddr(&DefMyAddress, ipaddr)) { 386 387 /* 388 * Use address suggested by peer. 389 */ 390 snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s ", tbuff, 391 inet_ntoa(IpcpInfo.want_ipaddr)); 392 LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 393 IpcpInfo.want_ipaddr = ipaddr; 394 } 395 break; 396 case MODE_REJ: 397 IpcpInfo.his_reject |= (1 << type); 398 break; 399 } 400 break; 401 case TY_COMPPROTO: 402 lp = (u_long *) (cp + 2); 403 compproto = htonl(*lp); 404 LogPrintf(LogIPCP, "%s %08x\n", tbuff, compproto); 405 406 switch (mode_type) { 407 case MODE_REQ: 408 if (!Acceptable(ConfVjcomp)) { 409 memcpy(rejp, cp, length); 410 rejp += length; 411 } else { 412 pcomp = (struct compreq *) (cp + 2); 413 switch (length) { 414 case 4: /* RFC1172 */ 415 if (ntohs(pcomp->proto) == PROTO_VJCOMP) { 416 LogPrintf(LogWARN, "Peer is speaking RFC1172 compression protocol !\n"); 417 IpcpInfo.heis1172 = 1; 418 IpcpInfo.his_compproto = compproto; 419 memcpy(ackp, cp, length); 420 ackp += length; 421 } else { 422 memcpy(nakp, cp, 2); 423 pcomp->proto = htons(PROTO_VJCOMP); 424 memcpy(nakp+2, &pcomp, 2); 425 nakp += length; 426 } 427 break; 428 case 6: /* RFC1332 */ 429 if (ntohs(pcomp->proto) == PROTO_VJCOMP 430 && pcomp->slots < MAX_STATES && pcomp->slots > 2) { 431 IpcpInfo.his_compproto = compproto; 432 IpcpInfo.heis1172 = 0; 433 memcpy(ackp, cp, length); 434 ackp += length; 435 } else { 436 memcpy(nakp, cp, 2); 437 pcomp->proto = htons(PROTO_VJCOMP); 438 pcomp->slots = MAX_STATES - 1; 439 pcomp->compcid = 0; 440 memcpy(nakp+2, &pcomp, sizeof(pcomp)); 441 nakp += length; 442 } 443 break; 444 default: 445 memcpy(rejp, cp, length); 446 rejp += length; 447 break; 448 } 449 } 450 break; 451 case MODE_NAK: 452 LogPrintf(LogIPCP, "%s changing compproto: %08x --> %08x\n", 453 tbuff, IpcpInfo.want_compproto, compproto); 454 IpcpInfo.want_compproto = compproto; 455 break; 456 case MODE_REJ: 457 IpcpInfo.his_reject |= (1 << type); 458 break; 459 } 460 break; 461 case TY_IPADDRS: /* RFC1172 */ 462 lp = (u_long *) (cp + 2); 463 ipaddr.s_addr = *lp; 464 lp = (u_long *) (cp + 6); 465 dstipaddr.s_addr = *lp; 466 snprintf(tbuff2, sizeof(tbuff2), "%s %s,", tbuff, inet_ntoa(ipaddr)); 467 LogPrintf(LogIPCP, "%s %s\n", tbuff2, inet_ntoa(dstipaddr)); 468 469 switch (mode_type) { 470 case MODE_REQ: 471 IpcpInfo.his_ipaddr = ipaddr; 472 IpcpInfo.want_ipaddr = dstipaddr; 473 memcpy(ackp, cp, length); 474 ackp += length; 475 break; 476 case MODE_NAK: 477 snprintf(tbuff2, sizeof(tbuff2), "%s changing address: %s", tbuff, 478 inet_ntoa(IpcpInfo.want_ipaddr)); 479 LogPrintf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 480 IpcpInfo.want_ipaddr = ipaddr; 481 IpcpInfo.his_ipaddr = dstipaddr; 482 break; 483 case MODE_REJ: 484 IpcpInfo.his_reject |= (1 << type); 485 break; 486 } 487 break; 488 489 /* 490 * MS extensions for MS's PPP 491 */ 492 493#ifndef NOMSEXT 494 case TY_PRIMARY_DNS: /* MS PPP DNS negotiation hack */ 495 case TY_SECONDARY_DNS: 496 if (!Enabled(ConfMSExt)) { 497 LogPrintf(LogIPCP, "MS NS req - rejected - msext disabled\n"); 498 IpcpInfo.my_reject |= (1 << type); 499 memcpy(rejp, cp, length); 500 rejp += length; 501 break; 502 } 503 switch (mode_type) { 504 case MODE_REQ: 505 lp = (u_long *) (cp + 2); 506 dnsstuff.s_addr = *lp; 507 ms_info_req.s_addr = ns_entries[((type - TY_PRIMARY_DNS) ? 1 : 0)].s_addr; 508 if (dnsstuff.s_addr != ms_info_req.s_addr) { 509 510 /* 511 * So the client has got the DNS stuff wrong (first request) so 512 * we'll tell 'em how it is 513 */ 514 memcpy(nakp, cp, 2); /* copy first two (type/length) */ 515 LogPrintf(LogIPCP, "MS NS req %d:%s->%s - nak\n", 516 type, 517 inet_ntoa(dnsstuff), 518 inet_ntoa(ms_info_req)); 519 memcpy(nakp+2, &ms_info_req, length); 520 nakp += length; 521 break; 522 } 523 524 /* 525 * Otherwise they have it right (this time) so we send a ack packet 526 * back confirming it... end of story 527 */ 528 LogPrintf(LogIPCP, "MS NS req %d:%s ok - ack\n", 529 type, 530 inet_ntoa(ms_info_req)); 531 memcpy(ackp, cp, length); 532 ackp += length; 533 break; 534 case MODE_NAK: /* what does this mean?? */ 535 LogPrintf(LogIPCP, "MS NS req %d - NAK??\n", type); 536 break; 537 case MODE_REJ: /* confused?? me to :) */ 538 LogPrintf(LogIPCP, "MS NS req %d - REJ??\n", type); 539 break; 540 } 541 break; 542 543 case TY_PRIMARY_NBNS: /* MS PPP NetBIOS nameserver hack */ 544 case TY_SECONDARY_NBNS: 545 if (!Enabled(ConfMSExt)) { 546 LogPrintf(LogIPCP, "MS NBNS req - rejected - msext disabled\n"); 547 IpcpInfo.my_reject |= (1 << type); 548 memcpy(rejp, cp, length); 549 rejp += length; 550 break; 551 } 552 switch (mode_type) { 553 case MODE_REQ: 554 lp = (u_long *) (cp + 2); 555 dnsstuff.s_addr = *lp; 556 ms_info_req.s_addr = nbns_entries[((type - TY_PRIMARY_NBNS) ? 1 : 0)].s_addr; 557 if (dnsstuff.s_addr != ms_info_req.s_addr) { 558 memcpy(nakp, cp, 2); 559 memcpy(nakp+2, &ms_info_req.s_addr, length); 560 LogPrintf(LogIPCP, "MS NBNS req %d:%s->%s - nak\n", 561 type, 562 inet_ntoa(dnsstuff), 563 inet_ntoa(ms_info_req)); 564 nakp += length; 565 break; 566 } 567 LogPrintf(LogIPCP, "MS NBNS req %d:%s ok - ack\n", 568 type, 569 inet_ntoa(ms_info_req)); 570 memcpy(ackp, cp, length); 571 ackp += length; 572 break; 573 case MODE_NAK: 574 LogPrintf(LogIPCP, "MS NBNS req %d - NAK??\n", type); 575 break; 576 case MODE_REJ: 577 LogPrintf(LogIPCP, "MS NBNS req %d - REJ??\n", type); 578 break; 579 } 580 break; 581 582#endif 583 584 default: 585 IpcpInfo.my_reject |= (1 << type); 586 memcpy(rejp, cp, length); 587 rejp += length; 588 break; 589 } 590 plen -= length; 591 cp += length; 592 } 593} 594 595void 596IpcpInput(struct mbuf * bp) 597{ 598 FsmInput(&IpcpFsm, bp); 599}
|