⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mppc.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
	s = mallocz(sizeof(Uncstate), 1);	s->count = 0xfff;	/* count of non existant last packet */	memmove(s->startkey, ppp->key, 16);	memmove(s->key, ppp->key, 16);	setkey(s->key, s->startkey);	setupRC4state(&s->rc4key, s->key, 16);	return s;}static	Block*uncomp(PPP *ppp, Block *b, int *protop, Block **r){	Uncstate *s;	ushort proto;	ushort count;	Lcpmsg *m;	*r = nil;	*protop = 0;	s = ppp->uncstate;	if(BLEN(b) < 2){		syslog(0, "ppp", ": mppc: short packet\n");		freeb(b);		return nil;	}	count = nhgets(b->rptr);	b->rptr += 2;	b = uncomp2(s, b, count);	if(b == nil) {//netlog("ppp: mppc: reset request\n");		/* return reset request packet */		*r = alloclcp(Lresetreq, s->resetid++, 4, &m);		hnputs(m->len, 4);		*protop = 0;		return nil;	}	if(BLEN(b) < 2){		syslog(0, "ppp", ": mppc: short packet\n");		freeb(b);		*protop = 0;		return nil;	}	proto = nhgets(b->rptr);	b->rptr += 2;/*	if(proto == 0x21)		if(!ipcheck(b->rptr, BLEN(b)))			hischeck(s);*/	*protop = proto;	return b;}#define NEXTBYTE	sreg = (sreg<<8) | *p++; n--; bits += 8int	maxoff;	static	Block*uncomp2(Uncstate *s, Block *b, ushort count){	int ecount, n, bits, off, len, ones;	ulong sreg;	int t;	uchar *p, c, *hp, *hs, *he, *hq;	if(count&Preset) {//netlog("mppc reset\n");		s->indx = 0;		s->size = 0;		setupRC4state(&s->rc4key, s->key, 16);	} else {		ecount = (s->count+1)&0xfff;		if((count&0xfff) != ecount) {netlog("******* bad count - got %ux expected %ux\n", count&0xfff, ecount);			freeb(b);			return nil;		}		if(count&Pfront) {			s->indx = 0;/*			netlog("ppp: mppc: frount flag set\n"); */		}	}	/* update key */	n = (((count+1)>>8)&0xf) - (((s->count+1)>>8)&0xf);	if(n < 0)		n += 16;//netlog("mppc count = %ux oldcount %ux n = %d\n", count, s->count, n);	if(n < 0 || n > 1) {		syslog(0, "ppp", ": mppc bad count %ux, %ux", count, s->count);		freeb(b);		return nil;	}	if(n == 1) {		setkey(s->key, s->startkey);		setupRC4state(&s->rc4key, s->key, 16);		rc4(&s->rc4key, s->key, 16);		setupRC4state(&s->rc4key, s->key, 16);	}		s->count = count;	n = BLEN(b);	p = b->rptr;	if(count & Pencrypt) {//netlog("mppc unencrypt count = %ux\n", count);		rc4(&s->rc4key, p, n);	}	if(!(count & Pcompress)) {//netlog("uncompress blen = %d\n", BLEN(b));		return  b;	}	bits = 0;	sreg = 0;	hs = s->his;		/* history start */	hp = hs+s->indx;	/* write pointer in history */	he = hs+sizeof(s->his);	/* hsitory end */	for(;;) {		if(bits<4) {			if(n==0) goto Done;			NEXTBYTE;		}		t = decode[(sreg>>(bits-4))&0xf];		switch(t) {		default:			sysfatal("mppc: bad decode!");		case Lit7:			bits -= 1;			if(bits<7) {				if(n==0) goto Done;				NEXTBYTE;			}			c = (sreg>>(bits-7))&0x7f;			bits -= 7;			if(hp >= he) goto His;			*hp++ = c;/* netlog("\tlit7 %.2ux\n", c); */			continue;		case Lit8:			bits -= 2;			if(bits<7) {				if(n==0) goto Eof;				NEXTBYTE;			}			c = 0x80 | ((sreg>>(bits-7))&0x7f);			bits -= 7;			if(hp >= he) goto His;			*hp++ = c;/* netlog("\tlit8 %.2ux\n", c); */			continue;		case Off6:			bits -= 4;			if(bits<6) {				if(n==0) goto Eof;				NEXTBYTE;			}			off = (sreg>>(bits-6))&0x3f;			bits -= 6;			break;		case Off8:			bits -= 4;			if(bits<8) {				if(n==0) goto Eof;				NEXTBYTE;			}			off = ((sreg>>(bits-8))&0xff)+64;			bits -= 8;			break;		case Off13:			bits -= 3;			while(bits<13) {				if(n==0) goto Eof;				NEXTBYTE;			}			off = ((sreg>>(bits-13))&0x1fff)+320;			bits -= 13;/* netlog("\toff=%d bits = %d sreg = %ux t = %x\n", off, bits, sreg, t); */			break;		}		for(ones=0;;ones++) {			if(bits == 0) {				if(n==0) goto Eof;				NEXTBYTE;			}			bits--;			if(!(sreg&(1<<bits)))				break;		}		if(ones>11) {netlog("ppp: mppc: bad length %d\n", ones);			freeb(b);			return nil;		}		if(ones == 0) {			len = 3;		} else {			ones++;			while(bits<ones) {				if(n==0) goto Eof;				NEXTBYTE;			}			len = (1<<ones) | ((sreg>>(bits-ones))&((1<<ones)-1));			bits -= ones;		}		hq = hp-off;		if(hq < hs) {			hq += sizeof(s->his);			if(hq-hs+len > s->size) 				goto His;		}		if(hp+len > he) goto His;		while(len) {			*hp++ = *hq++;			len--;		}	}Done:	freeb(b);	/* build up return block */	hq = hs+s->indx;	len = hp-hq;	b = allocb(len);	memmove(b->wptr, hq, len);	b->wptr += len;netlog("ppp: mppc: len %d bits = %d n=%d\n", len, bits, n);		s->indx += len;	if(s->indx > s->size)		s->size = s->indx;		return b;Eof:netlog("*****unexpected end of data\n");	freeb(b);	return nil;His:netlog("*****bad history\n");	freeb(b);	return nil;}static	voiduncresetack(void*, Block*){}static	voiduncfini(void *as){	Uncstate *s;		s = as;		free(s);}static voidsetkey(uchar *key, uchar *startkey){	uchar pad[40];	SHAstate *s;	uchar digest[SHA1dlen];	s = sha1(startkey, 16, nil, nil);	memset(pad, 0, 40);	sha1(pad, 40, nil, s);	sha1(key, 16, nil, s);	memset(pad, 0xf2, 40);	sha1(pad, 40, digest, s);	memmove(key, digest, 16);}/* code to check if IP packet looks good */typedef struct Iphdr Iphdr;struct Iphdr{	uchar	vihl;		/* Version and header length */	uchar	tos;		/* Type of service */	uchar	length[2];	/* packet length */	uchar	id[2];		/* Identification */	uchar	frag[2];	/* Fragment information */	uchar	ttl;		/* Time to live */	uchar	proto;		/* Protocol */	uchar	cksum[2];	/* Header checksum */	uchar	src[4];		/* Ip source */	uchar	dst[4];		/* Ip destination */};enum{	QMAX		= 64*1024-1,	IP_TCPPROTO	= 6,	TCP_IPLEN	= 8,	TCP_PHDRSIZE	= 12,	TCP_HDRSIZE	= 20,	TCP_PKT		= TCP_IPLEN+TCP_PHDRSIZE,};enum{	UDP_PHDRSIZE	= 12,	UDP_HDRSIZE	= 20,	UDP_IPHDR	= 8,	IP_UDPPROTO	= 17,	UDP_USEAD	= 12,	UDP_RELSIZE	= 16,	Udprxms		= 200,	Udptickms	= 100,	Udpmaxxmit	= 10,};typedef struct UDPhdr UDPhdr;struct UDPhdr{	/* ip header */	uchar	vihl;		/* Version and header length */	uchar	tos;		/* Type of service */	uchar	length[2];	/* packet length */	uchar	id[2];		/* Identification */	uchar	frag[2];	/* Fragment information */	uchar	Unused;		uchar	udpproto;	/* Protocol */	uchar	udpplen[2];	/* Header plus data length */	uchar	udpsrc[4];	/* Ip source */	uchar	udpdst[4];	/* Ip destination */	/* udp header */	uchar	udpsport[2];	/* Source port */	uchar	udpdport[2];	/* Destination port */	uchar	udplen[2];	/* data length */	uchar	udpcksum[2];	/* Checksum */};typedef struct TCPhdr TCPhdr;struct TCPhdr{	uchar	vihl;		/* Version and header length */	uchar	tos;		/* Type of service */	uchar	length[2];	/* packet length */	uchar	id[2];		/* Identification */	uchar	frag[2];	/* Fragment information */	uchar	Unused;	uchar	proto;	uchar	tcplen[2];	uchar	tcpsrc[4];	uchar	tcpdst[4];	uchar	tcpsport[2];	uchar	tcpdport[2];	uchar	tcpseq[4];	uchar	tcpack[4];	uchar	tcpflag[2];	uchar	tcpwin[2];	uchar	tcpcksum[2];	uchar	tcpurg[2];	/* Options segment */	uchar	tcpopt[2];	uchar	tcpmss[2];};static voidhischeck(Uncstate *s){	uchar *p;	Iphdr *iph;	int len;	p = s->his;netlog("***** history check\n");	while(p < s->his+s->size) {		if(p[0] != 0 || p[1] != 0x21) {netlog("***** unknown protocol\n");			return;		}		p += 2;netlog("off = %ld ", p-s->his);		iph = (Iphdr*)p;		len = nhgets(iph->length);		ipcheck(p, len);		p += len;	}}static intipcheck(uchar *p, int len){	Iphdr *iph;	TCPhdr *tcph;	ushort length;	UDPhdr *uh;	Block *bp;	ushort cksum;	int good;	bp = allocb(len);	memmove(bp->wptr, p, len);	bp->wptr += len;	good = 1;	iph = (Iphdr *)(bp->rptr);/* netlog("ppp: mppc: ipcheck %I %I len %d proto %d\n", iph->src, iph->dst, BLEN(bp), iph->proto); */	if(len != nhgets(iph->length)) {		netlog("***** bad length! %d %d\n", len, nhgets(iph->length));		good = 0;	}	cksum = ipcsum(&iph->vihl);	if(cksum) {		netlog("***** IP proto cksum!!! %I %ux\n", iph->src, cksum);		good = 0;	}	switch(iph->proto) {	default:		break;	case IP_TCPPROTO:		tcph = (TCPhdr*)(bp->rptr);		length = nhgets(tcph->length);		tcph->Unused = 0;		hnputs(tcph->tcplen, length-TCP_PKT);		cksum = ptclcsum(bp, TCP_IPLEN, length-TCP_IPLEN);		if(cksum) {			netlog("***** bad tcp proto cksum %ux!!!\n", cksum);			good = 0;		}		break;	case IP_UDPPROTO:		uh = (UDPhdr*)(bp->rptr);		/* Put back pseudo header for checksum */		uh->Unused = 0;		len = nhgets(uh->udplen);		hnputs(uh->udpplen, len);		if(nhgets(uh->udpcksum)) {			cksum = ptclcsum(bp, UDP_IPHDR, len+UDP_PHDRSIZE);			if(cksum) {				netlog("***** udp: proto cksum!!! %I %ux\n", uh->udpsrc, cksum);				good = 0;			}		}		break;	}	freeb(bp);	return good;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -