Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/planix-v0/sys/src/cmd/ip/snoopy/ppp.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <ip.h>
4
#include <libsec.h>
5
#include "dat.h"
6
#include "protos.h"
7
 
8
/* PPP stuff */
9
enum {
10
	PPP_addr=	0xff,
11
	PPP_ctl=	0x3,
12
	PPP_period=	3*1000,	/* period of retransmit process (in ms) */
13
};
14
 
15
/* PPP protocols */
16
enum {
17
	PPP_ip=		0x21,		/* internet */
18
	PPP_vjctcp=	0x2d,		/* compressing van jacobson tcp */
19
	PPP_vjutcp=	0x2f,		/* uncompressing van jacobson tcp */
20
	PPP_ml=		0x3d,		/* multi link */
21
	PPP_comp=	0xfd,		/* compressed packets */
22
	PPP_ipcp=	0x8021,		/* ip control */
23
	PPP_ccp=	0x80fd,		/* compression control */
24
	PPP_passwd=	0xc023,		/* passwd authentication */
25
	PPP_lcp=	0xc021,		/* link control */
26
	PPP_lqm=	0xc025,		/* link quality monitoring */
27
	PPP_chap=	0xc223,		/* challenge/response */
28
};
29
 
30
/* LCP protocol (and IPCP) */
31
 
32
 
33
typedef struct Lcppkt	Lcppkt;
34
struct Lcppkt
35
{
36
	uchar	code;
37
	uchar	id;
38
	uchar	len[2];
39
	uchar	data[1];
40
};
41
 
42
typedef struct Lcpopt	Lcpopt;
43
struct Lcpopt
44
{
45
	uchar	type;
46
	uchar	len;
47
	uchar	data[1];
48
};
49
 
50
enum
51
{
52
	/* LCP codes */
53
	Lconfreq=	1,
54
	Lconfack=	2,
55
	Lconfnak=	3,
56
	Lconfrej=	4,
57
	Ltermreq=	5,
58
	Ltermack=	6,
59
	Lcoderej=	7,
60
	Lprotorej=	8,
61
	Lechoreq=	9,
62
	Lechoack=	10,
63
	Ldiscard=	11,
64
	Lresetreq=	14,	/* for ccp only */
65
	Lresetack=	15,	/* for ccp only */
66
 
67
	/* Lcp configure options */
68
	Omtu=		1,
69
	Octlmap=	2,
70
	Oauth=		3,
71
	Oquality=	4,
72
	Omagic=		5,
73
	Opc=		7,
74
	Oac=		8,
75
 
76
	/* authentication protocols */
77
	APmd5=		5,
78
	APmschap=	128,
79
 
80
	/* Chap codes */
81
	Cchallenge=	1,
82
	Cresponse=	2,
83
	Csuccess=	3,
84
	Cfailure=	4,
85
 
86
	/* ipcp configure options */
87
	Oipaddrs=	1,
88
	Oipcompress=	2,
89
	Oipaddr=	3,
90
	Oipdns=		129,
91
	Oipwins=	130,
92
	Oipdns2=	131,
93
	Oipwins2=	132,
94
};
95
 
96
char *
97
lcpcode[] = {
98
	0,
99
	"confreq",
100
	"confack",
101
	"confnak",
102
	"confrej",
103
	"termreq",
104
	"termack",
105
	"coderej",
106
	"protorej",
107
	"echoreq",
108
	"echoack",
109
	"discard",
110
	"id",
111
	"timeremain",
112
	"resetreq",
113
	"resetack",
114
};
115
 
116
static Mux p_mux[] =
117
{
118
	{"ip",		PPP_ip, },
119
	{"ppp_vjctcp",	PPP_vjctcp, },
120
	{"ppp_vjutcp",	PPP_vjutcp, },
121
	{"ppp_ml",	PPP_ml, },
122
	{"ppp_comp",	PPP_comp, },
123
	{"ppp_ipcp",	PPP_ipcp, },
124
	{"ppp_ccp",	PPP_ccp, },
125
	{"ppp_passwd",	PPP_passwd, },
126
	{"ppp_lcp",	PPP_lcp, },
127
	{"ppp_lqm",	PPP_lqm, },
128
	{"ppp_chap",	PPP_chap, },
129
	{0},
130
};
131
 
132
enum
133
{
134
	OOproto,
135
};
136
 
137
static void
138
p_compile(Filter *f)
139
{
140
	Mux *m;
141
 
142
	for(m = p_mux; m->name != nil; m++)
143
		if(strcmp(f->s, m->name) == 0){
144
			f->pr = m->pr;
145
			f->ulv = m->val;
146
			f->subop = OOproto;
147
			return;
148
		}
149
 
150
	sysfatal("unknown ppp field or protocol: %s", f->s);
151
}
152
 
153
static int
154
p_filter(Filter *f, Msg *m)
155
{
156
	int proto;
157
	int len;
158
 
159
	if(f->subop != OOproto)
160
		return 0;
161
 
162
	len = m->pe - m->ps;
163
	if(len < 3)
164
		return -1;
165
 
166
	if(m->ps[0] == PPP_addr && m->ps[1] == PPP_ctl)
167
		m->ps += 2;
168
 
169
	proto = *m->ps++;
170
	if((proto&1) == 0)
171
		proto = (proto<<8) | *m->ps++;
172
 
173
	if(proto == f->ulv)
174
		return 1;
175
 
176
	return 0;
177
}
178
 
179
static int
180
p_seprint(Msg *m)
181
{
182
	int proto;
183
	int len;
184
 
185
	len = m->pe - m->ps;
186
	if(len < 3)
187
		return -1;
188
 
189
	if(m->ps[0] == PPP_addr && m->ps[1] == PPP_ctl)
190
		m->ps += 2;
191
 
192
	proto = *m->ps++;
193
	if((proto&1) == 0)
194
		proto = (proto<<8) | *m->ps++;
195
 
196
	m->p = seprint(m->p, m->e, "pr=%ud len=%d", proto, len);
197
	demux(p_mux, proto, proto, m, &dump);
198
 
199
	return 0;
200
}
201
 
202
static int
203
p_seprintchap(Msg *m)
204
{
205
	Lcppkt *lcp;
206
	char *p, *e;
207
	int len;
208
 
209
	if(m->pe-m->ps < 4)
210
		return -1;
211
 
212
	p = m->p;
213
	e = m->e;
214
	m->pr = nil;
215
 
216
	/* resize packet */
217
	lcp = (Lcppkt*)m->ps;
218
	len = NetS(lcp->len);
219
	if(m->ps+len < m->pe)
220
		m->pe = m->ps+len;
221
	else if(m->ps+len > m->pe)
222
		return -1;
223
 
224
	p = seprint(p, e, "id=%d code=%d", lcp->id, lcp->code);
225
	switch(lcp->code) {
226
	default:
227
		p = seprint(p, e, " data=%.*H", len>64?64:len, lcp->data);
228
		break;
229
	case 1:
230
	case 2:
231
		if(lcp->data[0] > len-4){
232
			p = seprint(p, e, "%.*H", len-4, lcp->data);
233
		} else {
234
			p = seprint(p, e, " %s=", lcp->code==1?"challenge ":"response ");
235
			p = seprint(p, e, "%.*H", lcp->data[0], lcp->data+1);
236
			p = seprint(p, e, " name=");
237
			p = seprint(p, e, "%.*H", len-4-lcp->data[0]-1, lcp->data+lcp->data[0]+1);
238
		}
239
		break;
240
	case 3:
241
	case 4:
242
		if(len > 64)
243
			len = 64;
244
		p = seprint(p, e, " %s=%.*H", lcp->code==3?"success ":"failure",
245
				len>64?64:len, lcp->data);
246
		break;
247
	}
248
	m->p = seprint(p, e, " len=%d", len);
249
	return 0;
250
}
251
 
252
static char*
253
seprintlcpopt(char *p, char *e, void *a, int len)
254
{
255
	Lcpopt *o;
256
	int proto, x, period;
257
	uchar *cp, *ecp;
258
 
259
	cp = a;
260
	ecp = cp+len;
261
 
262
	for(; cp < ecp; cp += o->len){
263
		o = (Lcpopt*)cp;
264
		if(cp + o->len > ecp || o->len == 0){
265
			p = seprint(p, e, " bad-opt-len=%d", o->len);
266
			return p;
267
		}
268
 
269
		switch(o->type){
270
		default:
271
			p = seprint(p, e, " (type=%d len=%d)", o->type, o->len);
272
			break;
273
		case Omtu:
274
			p = seprint(p, e, " mtu=%d", NetS(o->data));
275
			break;
276
		case Octlmap:
277
			p = seprint(p, e, " ctlmap=%ux", NetL(o->data));
278
			break;
279
		case Oauth:
280
			proto = NetS(o->data);
281
			switch(proto) {
282
			default:
283
				p = seprint(p, e, " auth=%d", proto);
284
				break;
285
			case PPP_passwd:
286
				p = seprint(p, e, " auth=passwd");
287
				break;
288
			case PPP_chap:
289
				p = seprint(p, e, " (auth=chap data=%2.2ux)", o->data[2]);
290
				break;
291
			}
292
			break;
293
		case Oquality:
294
			proto = NetS(o->data);
295
			switch(proto) {
296
			default:
297
				p = seprint(p, e, " qproto=%d", proto);
298
				break;
299
			case PPP_lqm:
300
				x = NetL(o->data+2)*10;
301
				period = (x+(PPP_period-1))/PPP_period;
302
				p = seprint(p, e, " (qproto=lqm period=%d)", period);
303
				break;
304
			}
305
		case Omagic:
306
			p = seprint(p, e, " magic=%ux", NetL(o->data));
307
			break;
308
		case Opc:
309
			p = seprint(p, e, " protocol-compress");
310
			break;
311
		case Oac:
312
			p = seprint(p, e, " addr-compress");
313
			break;
314
		}
315
	}
316
	return p;
317
}
318
 
319
 
320
static int
321
p_seprintlcp(Msg *m)
322
{
323
	Lcppkt *lcp;
324
	char *p, *e;
325
	int len;
326
 
327
	if(m->pe-m->ps < 4)
328
		return -1;
329
 
330
	p = m->p;
331
	e = m->e;
332
	m->pr = nil;
333
 
334
	lcp = (Lcppkt*)m->ps;
335
	len = NetS(lcp->len);
336
	if(m->ps+len < m->pe)
337
		m->pe = m->ps+len;
338
	else if(m->ps+len > m->pe)
339
		return -1;
340
 
341
	p = seprint(p, e, "id=%d code=%d", lcp->id, lcp->code);
342
	switch(lcp->code) {
343
	default:
344
		p = seprint(p, e, " data=%.*H", len>64?64:len, lcp->data);
345
		break;
346
	case Lconfreq:
347
	case Lconfack:
348
	case Lconfnak:
349
	case Lconfrej:
350
		p = seprint(p, e, "=%s", lcpcode[lcp->code]);
351
		p = seprintlcpopt(p, e, lcp->data, len-4);
352
		break;
353
	case Ltermreq:
354
	case Ltermack:
355
	case Lcoderej:
356
	case Lprotorej:
357
	case Lechoreq:
358
	case Lechoack:
359
	case Ldiscard:
360
		p = seprint(p, e, "=%s", lcpcode[lcp->code]);
361
		break;
362
	}
363
	m->p = seprint(p, e, " len=%d", len);
364
	return 0;
365
}
366
 
367
static char*
368
seprintipcpopt(char *p, char *e, void *a, int len)
369
{
370
	Lcpopt *o;
371
	uchar *cp, *ecp;
372
 
373
	cp = a;
374
	ecp = cp+len;
375
 
376
	for(; cp < ecp; cp += o->len){
377
		o = (Lcpopt*)cp;
378
		if(cp + o->len > ecp){
379
			p = seprint(p, e, " bad opt len %ux", o->type);
380
			return p;
381
		}
382
 
383
		switch(o->type){
384
		default:
385
			p = seprint(p, e, " (type=%d len=%d)", o->type, o->len);
386
			break;
387
		case Oipaddrs:	
388
			p = seprint(p, e, " ipaddrs(deprecated)");
389
			break;
390
		case Oipcompress:
391
			p = seprint(p, e, " ipcompress");
392
			break;
393
		case Oipaddr:	
394
			p = seprint(p, e, " ipaddr=%V", o->data);
395
			break;
396
		case Oipdns:	
397
			p = seprint(p, e, " dnsaddr=%V", o->data);
398
			break;
399
		case Oipwins:	
400
			p = seprint(p, e, " winsaddr=%V", o->data);
401
			break;
402
		case Oipdns2:	
403
			p = seprint(p, e, " dns2addr=%V", o->data);
404
			break;
405
		case Oipwins2:	
406
			p = seprint(p, e, " wins2addr=%V", o->data);
407
			break;
408
		}
409
	}
410
	return p;
411
}
412
 
413
static int
414
p_seprintipcp(Msg *m)
415
{
416
	Lcppkt *lcp;
417
	char *p, *e;
418
	int len;
419
 
420
	if(m->pe-m->ps < 4)
421
		return -1;
422
 
423
	p = m->p;
424
	e = m->e;
425
	m->pr = nil;
426
 
427
	lcp = (Lcppkt*)m->ps;
428
	len = NetS(lcp->len);
429
	if(m->ps+len < m->pe)
430
		m->pe = m->ps+len;
431
	else if(m->ps+len > m->pe)
432
		return -1;
433
 
434
	p = seprint(p, e, "id=%d code=%d", lcp->id, lcp->code);
435
	switch(lcp->code) {
436
	default:
437
		p = seprint(p, e, " data=%.*H", len>64?64:len, lcp->data);
438
		break;
439
	case Lconfreq:
440
	case Lconfack:
441
	case Lconfnak:
442
	case Lconfrej:
443
		p = seprint(p, e, "=%s", lcpcode[lcp->code]);
444
		p = seprintipcpopt(p, e, lcp->data, len-4);
445
		break;
446
	case Ltermreq:
447
	case Ltermack:
448
		p = seprint(p, e, "=%s", lcpcode[lcp->code]);
449
		break;
450
	}
451
	m->p = seprint(p, e, " len=%d", len);
452
	return 0;
453
}
454
 
455
static char*
456
seprintccpopt(char *p, char *e, void *a, int len)
457
{
458
	Lcpopt *o;
459
	uchar *cp, *ecp;
460
 
461
	cp = a;
462
	ecp = cp+len;
463
 
464
	for(; cp < ecp; cp += o->len){
465
		o = (Lcpopt*)cp;
466
		if(cp + o->len > ecp){
467
			p = seprint(p, e, " bad opt len %ux", o->type);
468
			return p;
469
		}
470
 
471
		switch(o->type){
472
		default:
473
			p = seprint(p, e, " type=%d ", o->type);
474
			break;
475
		case 0:
476
			p = seprint(p, e, " OUI=(%d %.2ux%.2ux%.2ux) ", o->type, 
477
				o->data[0], o->data[1], o->data[2]);
478
			break;
479
		case 17:
480
			p = seprint(p, e, " Stac-LZS");
481
			break;
482
		case 18:
483
			p = seprint(p, e, " Microsoft-PPC=%ux", NetL(o->data));
484
			break;
485
		}
486
	}
487
	return p;
488
}
489
 
490
static int
491
p_seprintccp(Msg *m)
492
{
493
	Lcppkt *lcp;
494
	char *p, *e;
495
	int len;
496
 
497
	if(m->pe-m->ps < 4)
498
		return -1;
499
 
500
	p = m->p;
501
	e = m->e;
502
	m->pr = nil;
503
 
504
	lcp = (Lcppkt*)m->ps;
505
	len = NetS(lcp->len);
506
	if(m->ps+len < m->pe)
507
		m->pe = m->ps+len;
508
	else if(m->ps+len > m->pe)
509
		return -1;
510
 
511
	p = seprint(p, e, "id=%d code=%d", lcp->id, lcp->code);
512
	switch(lcp->code) {
513
	default:
514
		p = seprint(p, e, " data=%.*H", len>64?64:len, lcp->data);
515
		break;
516
	case Lconfreq:
517
	case Lconfack:
518
	case Lconfnak:
519
	case Lconfrej:
520
		p = seprint(p, e, "=%s", lcpcode[lcp->code]);
521
		p = seprintccpopt(p, e, lcp->data, len-4);
522
		break;
523
	case Ltermreq:
524
	case Ltermack:
525
	case Lresetreq:
526
	case Lresetack:
527
		p = seprint(p, e, "=%s", lcpcode[lcp->code]);
528
		break;
529
	}
530
	m->p = seprint(p, e, " len=%d", len);
531
 
532
	return 0;
533
}
534
 
535
static int
536
p_seprintcomp(Msg *m)
537
{
538
	char compflag[5];
539
	ushort x;
540
	int i;
541
	int len;
542
 
543
	len = m->pe-m->ps;
544
	if(len < 2)
545
		return -1;
546
 
547
	x = NetS(m->ps);
548
	m->ps += 2;
549
	i = 0;
550
	if(x & (1<<15))
551
		compflag[i++] = 'r';
552
	if(x & (1<<14))
553
		compflag[i++] = 'f';
554
	if(x & (1<<13))
555
		compflag[i++] = 'c';
556
	if(x & (1<<12))
557
		compflag[i++] = 'e';
558
	compflag[i] = 0;
559
	m->p = seprint(m->p, m->e, "flag=%s count=%.3ux", compflag, x&0xfff);
560
	m->p = seprint(m->p, m->e, " data=%.*H", len>64?64:len, m->ps);
561
	m->pr = nil;
562
	return 0;
563
}
564
 
565
Proto ppp =
566
{
567
	"ppp",
568
	p_compile,
569
	p_filter,
570
	p_seprint,
571
	p_mux,
572
	"%#.4lux",
573
	nil,
574
	defaultframer,
575
};
576
 
577
Proto ppp_ipcp =
578
{
579
	"ppp_ipcp",
580
	p_compile,
581
	p_filter,
582
	p_seprintipcp,
583
	nil,
584
	nil,
585
	nil,
586
	defaultframer,
587
};
588
 
589
Proto ppp_lcp =
590
{
591
	"ppp_lcp",
592
	p_compile,
593
	p_filter,
594
	p_seprintlcp,
595
	nil,
596
	nil,
597
	nil,
598
	defaultframer,
599
};
600
 
601
Proto ppp_ccp =
602
{
603
	"ppp_ccp",
604
	p_compile,
605
	p_filter,
606
	p_seprintccp,
607
	nil,
608
	nil,
609
	nil,
610
	defaultframer,
611
};
612
 
613
Proto ppp_chap =
614
{
615
	"ppp_chap",
616
	p_compile,
617
	p_filter,
618
	p_seprintchap,
619
	nil,
620
	nil,
621
	nil,
622
	defaultframer,
623
};
624
 
625
Proto ppp_comp =
626
{
627
	"ppp_comp",
628
	p_compile,
629
	p_filter,
630
	p_seprintcomp,
631
	nil,
632
	nil,
633
	nil,
634
	defaultframer,
635
};