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

📄 rarpd.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <ip.h>#include <ndb.h>#include "arp.h"typedef struct Rarp	Rarp;struct Rarp{	uchar	edst[6];	uchar	esrc[6];	uchar	type[2];	uchar	hrd[2];	uchar	pro[2];	uchar	hln;	uchar	pln;	uchar	op[2];	uchar	sha[6];	uchar	spa[4];	uchar	tha[6];	uchar	tpa[4];};uchar	myip[IPaddrlen];uchar	myether[6];char	rlog[] = "ipboot";char	*device = "ether0";int	debug;Ndb	*db;char*	lookup(char*, char*, char*, char*, int);voiderror(char *s){	syslog(1, rlog, "error %s: %r", s);	exits(s);}char net[32];voidusage(void){	fprint(2, "usage: %s [-e device] [-x netmtpt] [-f ndb-file] [-d]\n", argv0);	exits("usage");}voidmain(int argc, char *argv[]){	int edata, ectl;	uchar buf[2048];	long n;	Rarp *rp;	char ebuf[16];	char ipbuf[64];	char file[128];	int arp;	char *p, *ndbfile;	ndbfile = nil;	setnetmtpt(net, sizeof(net), nil);	ARGBEGIN{	case 'e':		p = ARGF();		if(p == nil)			usage();		device = p;		break;	case 'd':		debug = 1;		break;	case 'f':		p = ARGF();		if(p == nil)			usage();		ndbfile = p;		break;	case 'x':		p = ARGF();		if(p == nil)			usage();		setnetmtpt(net, sizeof(net), p);		break;	}ARGEND	USED(argc, argv);	fmtinstall('E', eipfmt);	fmtinstall('I', eipfmt);	fmtinstall('V', eipfmt);	db = ndbopen(ndbfile);	if(db == 0)		error("can't open the database");	edata = dial(netmkaddr("0x8035", device, 0), 0, 0, &ectl);	if(edata < 0)		error("can't open ethernet");	if(myipaddr(myip, net) < 0)		error("can't get my ip address");	sprint(ebuf, "%s/%s", net, device);	if(myetheraddr(myether, ebuf) < 0)		error("can't get my ether address");	snprint(file, sizeof(file), "%s/arp", net);	if((arp = open(file, ORDWR)) < 0)		fprint(2, "rarpd: can't open %s\n", file);	switch(rfork(RFNOTEG|RFPROC|RFFDG)) {	case -1:		error("fork");	case 0:		break;	default:		exits(0);	}	for(;;){		n = read(edata, buf, sizeof(buf));		if(n <= 0)			error("reading");		if(n < sizeof(Rarp)){			syslog(debug, rlog, "bad packet size %ld", n);			continue;		}		rp = (Rarp*)buf;		if(rp->op[0]!=0 && rp->op[1]!=3){			syslog(debug, rlog, "bad op %d %d %E",				rp->op[1], rp->op[0], rp->esrc);			continue;		}		if(debug)			syslog(debug, rlog, "rcv se %E si %V te %E ti %V",				 rp->sha, rp->spa, rp->tha, rp->tpa);		sprint(ebuf, "%E", rp->tha);		if(lookup("ether", ebuf, "ip", ipbuf, sizeof ipbuf) == nil){			syslog(debug, rlog, "client lookup failed: %s", ebuf);			continue;		}		v4parseip(rp->tpa, ipbuf);		memmove(rp->sha, myether, sizeof(rp->sha));		v6tov4(rp->spa, myip);		rp->op[0] = 0;		rp->op[1] = 4;		memmove(rp->edst, rp->esrc, sizeof(rp->edst));		if(debug)			syslog(debug, rlog, "send se %E si %V te %E ti %V",				 rp->sha, rp->spa, rp->tha, rp->tpa);		if(write(edata, buf, 60) != 60)			error("write failed");		if(arp < 0)			continue;		if(fprint(arp, "add %E %V", rp->esrc, rp->tpa) < 0)			fprint(2, "can't write arp entry\n");	}}char*lookup(char *sattr, char *sval, char *tattr, char *tval, int len){	static Ndb *db;	char *attrs[1];	Ndbtuple *t;	if(db == nil)		db = ndbopen(0);	if(db == nil)		return nil;	if(sattr == nil)		sattr = ipattr(sval);	attrs[0] = tattr;	t = ndbipinfo(db, sattr, sval, attrs, 1);	if(t == nil)		return nil;	strncpy(tval, t->val, len);	tval[len-1] = 0;	ndbfree(t);	return tval;}

⌨️ 快捷键说明

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