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

📄 esp.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
		ecb->header = 1;	else if(strcmp(f[0], "noheader") == 0)		ecb->header = 0;	else		e = "unknown control request";	return e;}voidespadvise(Proto *esp, Block *bp, char *msg){	Esphdr *h;	Conv *c;	ulong spi;	h = (Esphdr*)(bp->rp);	spi = nhgets(h->espspi);	qlock(esp);	c = convlookup(esp, spi);	if(c != nil) {		qhangup(c->rq, msg);		qhangup(c->wq, msg);	}	qunlock(esp);	freeblist(bp);}intespstats(Proto *esp, char *buf, int len){	Esppriv *upriv;	upriv = esp->priv;	return snprint(buf, len, "%lud %lud\n",		upriv->in,		upriv->inerrors);}static intesplocal(Conv *c, char *buf, int len){	Espcb *ecb = c->ptcl;	int n;	qlock(c);	if(ecb->incoming)		n = snprint(buf, len, "%I!%uld\n", c->laddr, ecb->spi);	else		n = snprint(buf, len, "%I\n", c->laddr);	qunlock(c);	return n;}static intespremote(Conv *c, char *buf, int len){	Espcb *ecb = c->ptcl;	int n;	qlock(c);	if(ecb->incoming)		n = snprint(buf, len, "%I\n", c->raddr);	else		n = snprint(buf, len, "%I!%uld\n", c->raddr, ecb->spi);	qunlock(c);	return n;}static	Conv*convlookup(Proto *esp, ulong spi){	Conv *c, **p;	Espcb *ecb;	for(p=esp->conv; *p; p++){		c = *p;		ecb = c->ptcl;		if(ecb->incoming && ecb->spi == spi)			return c;	}	return nil;}static char *setalg(Espcb *ecb, char **f, int n, Algorithm *alg){	uchar *key;	int i, nbyte, nchar;	int c;	if(n < 2)		return "bad format";	for(; alg->name; alg++)		if(strcmp(f[1], alg->name) == 0)			break;	if(alg->name == nil)		return "unknown algorithm";	if(n != 3)		return "bad format";	nbyte = (alg->keylen + 7) >> 3;	nchar = strlen(f[2]);	for(i=0; i<nchar; i++) {		c = f[2][i];		if(c >= '0' && c <= '9')			f[2][i] -= '0';		else if(c >= 'a' && c <= 'f')			f[2][i] -= 'a'-10;		else if(c >= 'A' && c <= 'F')			f[2][i] -= 'A'-10;		else			return "bad character in key";	}	key = smalloc(nbyte);	for(i=0; i<nchar && i*2<nbyte; i++) {		c = f[2][nchar-i-1];		if(i&1)			c <<= 4;		key[i>>1] |= c;	}	alg->init(ecb, alg->name, key, alg->keylen);	free(key);	return nil;}static intnullcipher(Espcb*, uchar*, int){	return 1;}static voidnullespinit(Espcb *ecb, char *name, uchar*, int){	ecb->espalg = name;	ecb->espblklen = 1;	ecb->espivlen = 0;	ecb->cipher = nullcipher;}static intnullauth(Espcb*, uchar*, int, uchar*){	return 1;}static voidnullahinit(Espcb *ecb, char *name, uchar*, int){	ecb->ahalg = name;	ecb->ahblklen = 1;	ecb->ahlen = 0;	ecb->auth = nullauth;}voidseanq_hmac_sha1(uchar hash[SHA1dlen], uchar *t, long tlen, uchar *key, long klen){	uchar ipad[65], opad[65];	int i;	DigestState *digest;	uchar innerhash[SHA1dlen];	for(i=0; i<64; i++){		ipad[i] = 0x36;		opad[i] = 0x5c;	}	ipad[64] = opad[64] = 0;	for(i=0; i<klen; i++){		ipad[i] ^= key[i];		opad[i] ^= key[i];	}	digest = sha1(ipad, 64, nil, nil);	sha1(t, tlen, innerhash, digest);	digest = sha1(opad, 64, nil, nil);	sha1(innerhash, SHA1dlen, hash, digest);}static intshaauth(Espcb *ecb, uchar *t, int tlen, uchar *auth){	uchar hash[SHA1dlen];	int r;	memset(hash, 0, SHA1dlen);	seanq_hmac_sha1(hash, t, tlen, (uchar*)ecb->ahstate, 16);	r = memcmp(auth, hash, ecb->ahlen) == 0;	memmove(auth, hash, ecb->ahlen);	return r;}static voidshaahinit(Espcb *ecb, char *name, uchar *key, int klen){	if(klen != 128)		panic("shaahinit: bad keylen");	klen >>= 8;	// convert to bytes	ecb->ahalg = name;	ecb->ahblklen = 1;	ecb->ahlen = 12;	ecb->auth = shaauth;	ecb->ahstate = smalloc(klen);	memmove(ecb->ahstate, key, klen);}voidseanq_hmac_md5(uchar hash[MD5dlen], uchar *t, long tlen, uchar *key, long klen){	uchar ipad[65], opad[65];	int i;	DigestState *digest;	uchar innerhash[MD5dlen];	for(i=0; i<64; i++){		ipad[i] = 0x36;		opad[i] = 0x5c;	}	ipad[64] = opad[64] = 0;	for(i=0; i<klen; i++){		ipad[i] ^= key[i];		opad[i] ^= key[i];	}	digest = md5(ipad, 64, nil, nil);	md5(t, tlen, innerhash, digest);	digest = md5(opad, 64, nil, nil);	md5(innerhash, MD5dlen, hash, digest);}static intmd5auth(Espcb *ecb, uchar *t, int tlen, uchar *auth){	uchar hash[MD5dlen];	int r;	memset(hash, 0, MD5dlen);	seanq_hmac_md5(hash, t, tlen, (uchar*)ecb->ahstate, 16);	r = memcmp(auth, hash, ecb->ahlen) == 0;	memmove(auth, hash, ecb->ahlen);	return r;}static voidmd5ahinit(Espcb *ecb, char *name, uchar *key, int klen){	if(klen != 128)		panic("md5ahinit: bad keylen");	klen >>= 3;	// convert to bytes	ecb->ahalg = name;	ecb->ahblklen = 1;	ecb->ahlen = 12;	ecb->auth = md5auth;	ecb->ahstate = smalloc(klen);	memmove(ecb->ahstate, key, klen);}static intdescipher(Espcb *ecb, uchar *p, int n){	uchar tmp[8];	uchar *pp, *tp, *ip, *eip, *ep;	DESstate *ds = ecb->espstate;	ep = p + n;	if(ecb->incoming) {		memmove(ds->ivec, p, 8);		p += 8;		while(p < ep){			memmove(tmp, p, 8);			block_cipher(ds->expanded, p, 1);			tp = tmp;			ip = ds->ivec;			for(eip = ip+8; ip < eip; ){				*p++ ^= *ip;				*ip++ = *tp++;			}		}	} else {		memmove(p, ds->ivec, 8);		for(p += 8; p < ep; p += 8){			pp = p;			ip = ds->ivec;			for(eip = ip+8; ip < eip; )				*pp++ ^= *ip++;			block_cipher(ds->expanded, p, 0);			memmove(ds->ivec, p, 8);		}	}	return 1;}	static voiddesespinit(Espcb *ecb, char *name, uchar *k, int n){	uchar key[8];	uchar ivec[8];	int i;		// bits to bytes	n = (n+7)>>3;	if(n > 8)		n = 8;	memset(key, 0, sizeof(key));	memmove(key, k, n);	for(i=0; i<8; i++)		ivec[i] = nrand(256);	ecb->espalg = name;	ecb->espblklen = 8;	ecb->espivlen = 8;	ecb->cipher = descipher;	ecb->espstate = smalloc(sizeof(DESstate));	setupDESstate(ecb->espstate, key, ivec);}static intrc4cipher(Espcb *ecb, uchar *p, int n){	Esprc4 *esprc4;	RC4state tmpstate;	ulong seq;	long d, dd;	if(n < 4)		return 0;	esprc4 = ecb->espstate;	if(ecb->incoming) {		seq = nhgetl(p);		p += 4;		n -= 4;		d = seq-esprc4->cseq;		if(d == 0) {			rc4(&esprc4->current, p, n);			esprc4->cseq += n;			if(esprc4->ovalid) {				dd = esprc4->cseq - esprc4->lgseq;				if(dd > RC4back)					esprc4->ovalid = 0;			}		} else if(d > 0) {print("missing packet: %uld %ld\n", seq, d);			// this link is hosed			if(d > RC4forward) {				strcpy(up->errstr, "rc4cipher: skipped too much");				return 0;			}			esprc4->lgseq = seq;			if(!esprc4->ovalid) {				esprc4->ovalid = 1;				esprc4->oseq = esprc4->cseq;				memmove(&esprc4->old, &esprc4->current, sizeof(RC4state));			}			rc4skip(&esprc4->current, d);			rc4(&esprc4->current, p, n);			esprc4->cseq = seq+n;		} else {print("reordered packet: %uld %ld\n", seq, d);			dd = seq - esprc4->oseq;			if(!esprc4->ovalid || -d > RC4back || dd < 0) {				strcpy(up->errstr, "rc4cipher: too far back");				return 0;			}			memmove(&tmpstate, &esprc4->old, sizeof(RC4state));			rc4skip(&tmpstate, dd);			rc4(&tmpstate, p, n);			return 1;		}		// move old state up		if(esprc4->ovalid) {			dd = esprc4->cseq - RC4back - esprc4->oseq;			if(dd > 0) {				rc4skip(&esprc4->old, dd);				esprc4->oseq += dd;			}		}	} else {		hnputl(p, esprc4->cseq);		p += 4;		n -= 4;		rc4(&esprc4->current, p, n);		esprc4->cseq += n;	}	return 1;}static voidrc4espinit(Espcb *ecb, char *name, uchar *k, int n){		Esprc4 *esprc4;	// bits to bytes	n = (n+7)>>3;	esprc4 = smalloc(sizeof(Esprc4));	memset(esprc4, 0, sizeof(Esprc4));	setupRC4state(&esprc4->current, k, n);	ecb->espalg = name;	ecb->espblklen = 4;	ecb->espivlen = 4;	ecb->cipher = rc4cipher;	ecb->espstate = esprc4;}	voidespinit(Fs *fs){	Proto *esp;	esp = smalloc(sizeof(Proto));	esp->priv = smalloc(sizeof(Esppriv));	esp->name = "esp";	esp->connect = espconnect;	esp->announce = nil;	esp->ctl = espctl;	esp->state = espstate;	esp->create = espcreate;	esp->close = espclose;	esp->rcv = espiput;	esp->advise = espadvise;	esp->stats = espstats;	esp->local = esplocal;	esp->remote = espremote;	esp->ipproto = IP_ESPPROTO;	esp->nc = Nchans;	esp->ptclsize = sizeof(Espcb);	Fsproto(fs, esp);}

⌨️ 快捷键说明

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