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

📄 main.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <libc.h>#include <ip.h>#include <bio.h>#include <fcall.h>#include <libsec.h>#include "dat.h"#include "protos.h"#include "y.tab.h"int Cflag;int pflag;int Nflag;int Mflag;int sflag;int tiflag;int toflag;char *prom = "promiscuous";enum{	Pktlen=	64*1024,	Blen=	16*1024,};Filter *filter;Proto *root;Biobuf out;vlong starttime, pkttime;int pcap;int	filterpkt(Filter *f, uchar *ps, uchar *pe, Proto *pr, int);void	printpkt(char *p, char *e, uchar *ps, uchar *pe);void	mkprotograph(void);Proto*	findproto(char *name);Filter*	compile(Filter *f);void	printfilter(Filter *f, char *tag);void	printhelp(char*);void	tracepkt(uchar*, int);void	pcaphdr(void);voidprintusage(void){	fprint(2, "usage: %s [-CDdpst] [-N n] [-f filter] [-h first-header] path\n", argv0);	fprint(2, "  for protocol help: %s -? [proto]\n", argv0);}voidusage(void){	printusage();	exits("usage");}voidmain(int argc, char **argv){	uchar *pkt;	char *buf, *file, *p, *e;	int fd, cfd;	int n;	Binit(&out, 1, OWRITE);	fmtinstall('E', eipfmt);	fmtinstall('V', eipfmt);	fmtinstall('I', eipfmt);	fmtinstall('H', encodefmt);	fmtinstall('F', fcallfmt);	pkt = malloc(Pktlen+16);	pkt += 16;	buf = malloc(Blen);	e = buf+Blen-1;	pflag = 1;	Nflag = 32;	sflag = 0;	mkprotograph();	ARGBEGIN{	default:		usage();	case '?':		printusage();		printhelp(ARGF());		exits(0);		break;	case 'M':		p = EARGF(usage());		Mflag = atoi(p);		break;	case 'N':		p = EARGF(usage());		Nflag = atoi(p);		break;	case 'f':		p = EARGF(usage());		yyinit(p);		yyparse();		break;	case 's':		sflag = 1;		break;	case 'h':		p = EARGF(usage());		root = findproto(p);		if(root == nil)			sysfatal("unknown protocol: %s", p);		break;	case 'd':		toflag = 1;		break;	case 'D':		toflag = 1;		pcap = 1;		break;	case 't':		tiflag = 1;		break;	case 'C':		Cflag = 1;		break;	case 'p':		pflag = 0;		break;	}ARGEND;	if(pcap)		pcaphdr();	if(argc == 0){		file = "/net/ether0";		if(root != nil)			root = &ether;	} else		file = argv[0];	if((!tiflag) && strstr(file, "ether")){		if(root == nil)			root = &ether;		snprint(buf, Blen, "%s!-1", file);		fd = dial(buf, 0, 0, &cfd);		if(fd < 0)			sysfatal("dialing %s", buf);		if(pflag && fprint(cfd, prom, strlen(prom)) < 0)			sysfatal("setting %s", prom);	} else if((!tiflag) && strstr(file, "ipifc")){		if(root == nil)			root = &ip;		snprint(buf, Blen, "%s/snoop", file);		fd = open(buf, OREAD);		if(fd < 0)			sysfatal("opening %s: %r", buf);	} else {		if(root == nil)			root = &ether;		fd = open(file, OREAD);		if(fd < 0)			sysfatal("opening %s: %r", file);	}	filter = compile(filter);	if(tiflag){		/* read a trace file */		for(;;){			n = read(fd, pkt, 10);			if(n != 10)				break;			pkttime = NetL(pkt+2);			pkttime = (pkttime<<32) | NetL(pkt+6);			if(starttime == 0LL)				starttime = pkttime;			n = NetS(pkt);			if(readn(fd, pkt, n) != n)				break;			if(filterpkt(filter, pkt, pkt+n, root, 1))				if(toflag)					tracepkt(pkt, n);				else					printpkt(buf, e, pkt, pkt+n);		}	} else {		/* read a real time stream */		starttime = nsec();		for(;;){			n = root->framer(fd, pkt, Pktlen);			if(n <= 0)				break;			pkttime = nsec();			if(filterpkt(filter, pkt, pkt+n, root, 1))				if(toflag)					tracepkt(pkt, n);				else					printpkt(buf, e, pkt, pkt+n);		}	}}/* create a new filter node */Filter*newfilter(void){	Filter *f;	f = mallocz(sizeof(*f), 1);	if(f == nil)		sysfatal("newfilter: %r");	return f;}/* *  apply filter to packet */int_filterpkt(Filter *f, Msg *m){	Msg ma;	if(f == nil)		return 1;	switch(f->op){	case '!':		return !_filterpkt(f->l, m);	case LAND:		ma = *m;		return _filterpkt(f->l, &ma) && _filterpkt(f->r, m);	case LOR:		ma = *m;		return _filterpkt(f->l, &ma) || _filterpkt(f->r, m);	case WORD:		if(m->needroot){			if(m->pr != f->pr)				return 0;			m->needroot = 0;		}else{			if(m->pr && (m->pr->filter==nil || !(m->pr->filter)(f, m)))				return 0;		}		if(f->l == nil)			return 1;		m->pr = f->pr;		return _filterpkt(f->l, m);	}	sysfatal("internal error: filterpkt op: %d", f->op);	return 0;}intfilterpkt(Filter *f, uchar *ps, uchar *pe, Proto *pr, int needroot){	Msg m;	if(f == nil)		return 1;	m.needroot = needroot;	m.ps = ps;	m.pe = pe;	m.pr = pr;	return _filterpkt(f, &m);}/* *  from the Unix world */#define PCAP_VERSION_MAJOR 2#define PCAP_VERSION_MINOR 4#define TCPDUMP_MAGIC 0xa1b2c3d4struct pcap_file_header {	ulong		magic;	ushort		version_major;	ushort		version_minor;	long		thiszone;    /* gmt to local correction */	ulong		sigfigs;    /* accuracy of timestamps */	ulong		snaplen;    /* max length saved portion of each pkt */	ulong		linktype;   /* data link type (DLT_*) */};struct pcap_pkthdr {        uvlong	ts;	/* time stamp */        ulong	caplen;	/* length of portion present */        ulong	len;	/* length this packet (off wire) */};/* *  pcap trace header  */voidpcaphdr(void){	struct pcap_file_header hdr;	hdr.magic = TCPDUMP_MAGIC;	hdr.version_major = PCAP_VERSION_MAJOR;	hdr.version_minor = PCAP_VERSION_MINOR;  	hdr.thiszone = 0;	hdr.snaplen = 1500;	hdr.sigfigs = 0;	hdr.linktype = 1;	write(1, &hdr, sizeof(hdr));}/* *  write out a packet trace */voidtracepkt(uchar *ps, int len){	struct pcap_pkthdr *goo;	if(Mflag && len > Mflag)		len = Mflag;	if(pcap){		goo = (struct pcap_pkthdr*)(ps-16);		goo->ts = pkttime;		goo->caplen = len;		goo->len = len;		write(1, goo, len+16);	} else {		hnputs(ps-10, len);		hnputl(ps-8, pkttime>>32);		hnputl(ps-4, pkttime);		write(1, ps-10, len+10);	}}/* *  format and print a packet */voidprintpkt(char *p, char *e, uchar *ps, uchar *pe){	Msg m;	ulong dt;	dt = (pkttime-starttime)/1000000LL;	m.p = seprint(p, e, "%6.6uld ms ", dt);	m.ps = ps;	m.pe = pe;	m.e = e;	m.pr = root;	while(m.p < m.e){		if(!sflag)			m.p = seprint(m.p, m.e, "\n\t");		m.p = seprint(m.p, m.e, "%s(", m.pr->name);		if((*m.pr->seprint)(&m) < 0){			m.p = seprint(m.p, m.e, "TOO SHORT");			m.ps = m.pe;		}		m.p = seprint(m.p, m.e, ")");		if(m.pr == nil || m.ps >= m.pe)			break;	}	*m.p++ = '\n';	if(write(1, p, m.p - p) < 0)		sysfatal("stdout: %r");}Proto **xprotos;int nprotos;/* look up a protocol by its name */Proto*findproto(char *name){	int i;	for(i = 0; i < nprotos; i++)		if(strcmp(xprotos[i]->name, name) == 0)			return xprotos[i];	return nil;}/* *  add an undefined protocol to protos[] */Proto*addproto(char *name){	Proto *pr;	xprotos = realloc(xprotos, (nprotos+1)*sizeof(Proto*));	pr = malloc(sizeof *pr);	*pr = dump;	pr->name = name;	xprotos[nprotos++] = pr;	return pr;}/* *  build a graph of protocols, this could easily be circular.  This *  links together all the multiplexing in the protocol modules. */voidmkprotograph(void){	Proto **l;	Proto *pr;	Mux *m;	/* copy protos into a reallocable area */	for(nprotos = 0; protos[nprotos] != nil; nprotos++)		;	xprotos = malloc(nprotos*sizeof(Proto*));	memmove(xprotos, protos, nprotos*sizeof(Proto*));	for(l = protos; *l != nil; l++){		pr = *l;		for(m = pr->mux; m != nil && m->name != nil; m++){			m->pr = findproto(m->name);			if(m->pr == nil)				m->pr = addproto(m->name);		}	}}/* *  add in a protocol node */static Filter*addnode(Filter *f, Proto *pr){	Filter *nf;	nf = newfilter();	nf->pr = pr;	nf->s = pr->name;	nf->l = f;	nf->op = WORD;	return nf;}/* *  recurse through the protocol graph adding missing nodes *  to the filter if we reach the filter's protocol */static Filter*_fillin(Filter *f, Proto *last, int depth){	Mux *m;	Filter *nf;	if(depth-- <= 0)		return nil;	for(m = last->mux; m != nil && m->name != nil; m++){		if(m->pr == nil)			continue;		if(f->pr == m->pr)			return f;		nf = _fillin(f, m->pr, depth);		if(nf != nil)			return addnode(nf, m->pr);	}	return nil;}static Filter*fillin(Filter *f, Proto *last){	int i;	Filter *nf;	/* hack to make sure top level node is the root */

⌨️ 快捷键说明

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