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

📄 gping.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <libc.h>#include <ctype.h>#include <auth.h>#include <fcall.h>#include <draw.h>#include <event.h>#include <ip.h>#define	MAXNUM	8	/* maximum number of numbers on data line */typedef struct Graph	Graph;typedef struct Machine	Machine;typedef struct Req	Req;typedef struct Icmp	Icmp;enum {	Gmsglen	= 16,};struct Graph{	int		colindex;	Rectangle	r;	int		*data;	int		ndata;	char		*label;	void		(*newvalue)(Machine*, long*, long*, long*);	void		(*update)(Graph*, long, long, long);	Machine		*mach;	int		overflow;	Image		*overtmp;	int		overtmplen;	char		msg[Gmsglen];	int		cursor;	int		vmax;};struct Icmp{	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	ipcksum[2];	/* Header checksum */	uchar	src[4];		/* Ip source */	uchar	dst[4];		/* Ip destination */	uchar	type;	uchar	code;	uchar	cksum[2];	uchar	icmpid[2];	uchar	seq[2];	uchar	data[1];};enum{			/* Packet Types */	EchoReply	= 0,	Unreachable	= 3,	SrcQuench	= 4,	EchoRequest	= 8,	TimeExceed	= 11,	Timestamp	= 13,	TimestampReply	= 14,	InfoRequest	= 15,	InfoReply	= 16,	ICMP_IPSIZE	= 20,	ICMP_HDRSIZE	= 8,	MSGLEN		= 64,	Rttmax		= 50,};struct Req{	int	seq;	// sequence number	vlong	time;	// time sent	int	rtt;	Req	 *next;};struct Machine{	Lock;	char	*name;	int	pingfd;	int	nproc;	int	rttmsgs;	ulong	rttsum;	ulong	lastrtt;	int	lostmsgs;	int	rcvdmsgs;	ulong	lostavg;	int	unreachable;	ushort	seq;	Req	*first;	Req	*last;	Req	*rcvd;		char	buf[1024];	char	*bufp;	char	*ebufp;};enum{	Ncolor		= 6,	Ysqueeze	= 2,	/* vertical squeezing of label text */	Labspace	= 2,	/* room around label */	Dot		= 2,	/* height of dot */	Opwid		= 5,	/* strlen("add  ") or strlen("drop ") */	NPROC		= 128,	NMACH		= 32,};enum Menu2{	Mrtt,	Mlost,	Nmenu2,};char	*menu2str[Nmenu2+1] = {	"add  sec rtt",	"add  % lost ",	nil,};void	rttval(Machine*, long*, long*, long*);void	lostval(Machine*, long*, long*, long*);Menu	menu2 = {menu2str, nil};int		present[Nmenu2];void		(*newvaluefn[Nmenu2])(Machine*, long*, long*, long*) = {	rttval,	lostval,};Image		*cols[Ncolor][3];Graph		*graph;Machine		mach[NMACH];Font		*mediumfont;int		pids[NPROC];int		npid;int 		parity;	/* toggled to avoid patterns in textured background */int		nmach;int		ngraph;	/* totaly number is ngraph*nmach */long		starttime;int		pinginterval;void	dropgraph(int);void	addgraph(int);void	startproc(void (*)(void*), void*);void	resize(void);ulong	rttscale(ulong);int	which2index(int);int	index2which(int);voidkillall(char *s){	int i, pid;	pid = getpid();	for(i=0; i<NPROC; i++)		if(pids[i] && pids[i]!=pid)			postnote(PNPROC, pids[i], "kill");	exits(s);}void*emalloc(ulong sz){	void *v;	v = malloc(sz);	if(v == nil) {		fprint(2, "%s: out of memory allocating %ld: %r\n", argv0, sz);		killall("mem");	}	memset(v, 0, sz);	return v;}void*erealloc(void *v, ulong sz){	v = realloc(v, sz);	if(v == nil) {		fprint(2, "%s: out of memory reallocating %ld: %r\n", argv0, sz);		killall("mem");	}	return v;}char*estrdup(char *s){	char *t;	if((t = strdup(s)) == nil) {		fprint(2, "%s: out of memory in strdup(%.10s): %r\n", argv0, s);		killall("mem");	}	return t;}voidmkcol(int i, int c0, int c1, int c2){	cols[i][0] = allocimagemix(display, c0, DWhite);	cols[i][1] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, c1);	cols[i][2] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, c2);}voidcolinit(void){	mediumfont = openfont(display, "/lib/font/bit/pelm/latin1.8.font");	if(mediumfont == nil)		mediumfont = font;	/* Peach */	mkcol(0, 0xFFAAAAFF, 0xFFAAAAFF, 0xBB5D5DFF);	/* Aqua */	mkcol(1, DPalebluegreen, DPalegreygreen, DPurpleblue);	/* Yellow */	mkcol(2, DPaleyellow, DDarkyellow, DYellowgreen);	/* Green */	mkcol(3, DPalegreen, DMedgreen, DDarkgreen);	/* Blue */	mkcol(4, 0x00AAFFFF, 0x00AAFFFF, 0x0088CCFF);	/* Grey */	cols[5][0] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xEEEEEEFF);	cols[5][1] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xCCCCCCFF);	cols[5][2] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x888888FF);}intloadbuf(Machine *m, int *fd){	int n;	if(*fd < 0)		return 0;	seek(*fd, 0, 0);	n = read(*fd, m->buf, sizeof m->buf);	if(n <= 0){		close(*fd);		*fd = -1;		return 0;	}	m->bufp = m->buf;	m->ebufp = m->buf+n;	return 1;}voidlabel(Point p, int dy, char *text){	char *s;	Rune r[2];	int w, maxw, maxy;	p.x += Labspace;	maxy = p.y+dy;	maxw = 0;	r[1] = '\0';	for(s=text; *s; ){		if(p.y+mediumfont->height-Ysqueeze > maxy)			break;		w = chartorune(r, s);		s += w;		w = runestringwidth(mediumfont, r);		if(w > maxw)			maxw = w;		runestring(screen, p, display->black, ZP, mediumfont, r);		p.y += mediumfont->height-Ysqueeze;	}}voidhashmark(Point p, int dy, int v, int vmax, char *label){	int y;	int x;	x = p.x + Labspace;	y = p.y + (dy*(vmax-v))/vmax;	draw(screen, Rect(p.x, y-1, p.x+Labspace, y+1), display->black, nil, ZP);	if(dy > 5*mediumfont->height)		string(screen, Pt(x, y-mediumfont->height/2),			display->black, ZP, mediumfont, label);}voidhashmarks(Point p, int dy, int which){	switch(index2which(which)){	case Mrtt:		hashmark(p, dy, rttscale(1000000), Rttmax, "1.");		hashmark(p, dy, rttscale(100000), Rttmax, "0.1");		hashmark(p, dy, rttscale(10000), Rttmax, "0.01");		hashmark(p, dy, rttscale(1000), Rttmax, "0.001");		break;	case Mlost:		hashmark(p, dy, 75, 100, " 75%");		hashmark(p, dy, 50, 100, " 50%");		hashmark(p, dy, 25, 100, " 25%");		break;	}}Pointparitypt(int x){	return Pt(x+parity, 0);}Pointdatapoint(Graph *g, int x, long v, long vmax){	Point p;	p.x = x;	p.y = g->r.max.y - Dy(g->r)*v/vmax - Dot;	if(p.y < g->r.min.y)		p.y = g->r.min.y;	if(p.y > g->r.max.y-Dot)		p.y = g->r.max.y-Dot;	return p;}voiddrawdatum(Graph *g, int x, long prev, long v, long vmax){	int c;	Point p, q;	c = g->colindex;	p = datapoint(g, x, v, vmax);	q = datapoint(g, x, prev, vmax);	if(p.y < q.y){		draw(screen, Rect(p.x, g->r.min.y, p.x+1, p.y), cols[c][0], nil, paritypt(p.x));		draw(screen, Rect(p.x, p.y, p.x+1, q.y+Dot), cols[c][2], nil, ZP);		draw(screen, Rect(p.x, q.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP);	}else{		draw(screen, Rect(p.x, g->r.min.y, p.x+1, q.y), cols[c][0], nil, paritypt(p.x));		draw(screen, Rect(p.x, q.y, p.x+1, p.y+Dot), cols[c][2], nil, ZP);		draw(screen, Rect(p.x, p.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP);	}	g->vmax = vmax;}voiddrawmark(Graph *g, int x){	int c;	c = (g->colindex+1)&Ncolor;	draw(screen, Rect(x, g->r.min.y, x+1, g->r.max.y), cols[c][2], nil, ZP);}voidredraw(Graph *g, int vmax){	int i, c;	c = g->colindex;	draw(screen, g->r, cols[c][0], nil, paritypt(g->r.min.x));	for(i=1; i<Dx(g->r); i++)		drawdatum(g, g->r.max.x-i, g->data[i-1], g->data[i], vmax);	drawdatum(g, g->r.min.x, g->data[i], g->data[i], vmax);}voidclearmsg(Graph *g){	if(g->overtmp != nil)		draw(screen, g->overtmp->r, g->overtmp, nil, g->overtmp->r.min);	g->overflow = 0;}voiddrawmsg(Graph *g, char *msg){	if(g->overtmp == nil)		return;	// save previous contents of screen	draw(g->overtmp, g->overtmp->r, screen, nil, g->overtmp->r.min);	// draw message	if(strlen(msg) > g->overtmplen)		msg[g->overtmplen] = 0;	string(screen, g->overtmp->r.min, display->black, ZP, mediumfont, msg);}voidclearcursor(Graph *g){	int x;	long prev;	if(g->overtmp == nil)		return;	if(g->cursor > 0 && g->cursor < g->ndata){		x = g->r.max.x - g->cursor;		prev = 0;		if(g->cursor > 0)			prev = g->data[g->cursor-1];		drawdatum(g, x, prev, g->data[g->cursor], g->vmax);		g->cursor = -1;	}}voiddrawcursor(Graph *g, int x){	if(g->overtmp == nil)		return;	draw(screen, Rect(x, g->r.min.y, x+1, g->r.max.y), cols[g->colindex][2], nil, ZP);}voidupdate1(Graph *g, long v, long vmax, long mark){	char buf[Gmsglen];	// put back screen value sans message	if(g->overflow || *g->msg){		clearmsg(g);		g->overflow = 0;	}	draw(screen, g->r, screen, nil, Pt(g->r.min.x+1, g->r.min.y));	drawdatum(g, g->r.max.x-1, g->data[0], v, vmax);	if(mark)		drawmark(g, g->r.max.x-1);	memmove(g->data+1, g->data, (g->ndata-1)*sizeof(g->data[0]));	g->data[0] = v;	if(v>vmax){		g->overflow = 1;		sprint(buf, "%ld", v);		drawmsg(g, buf);	} else if(*g->msg)		drawmsg(g, g->msg);	if(g->cursor >= 0){		g->cursor++;		if(g->cursor >= g->ndata){			g->cursor = -1;			if(*g->msg){				clearmsg(g);				*g->msg = 0;			}		}	}	}voidpinglost(Machine *m, Req*){	m->lostmsgs++;}voidpingreply(Machine *m, Req *r){	ulong x;	x = r->time/1000LL;	m->rttsum += x;	m->rcvdmsgs++;	m->rttmsgs++;}voidpingclean(Machine *m, ushort seq, vlong now, int){	Req **l, *r;	vlong x, y;	y = 10LL*1000000000LL;	for(l = &m->first; *l; ){		r = *l;		x = now - r->time;		if(x > y || r->seq == seq){			*l = r->next;			r->time = x;			if(r->seq != seq)				pinglost(m, r);			else				pingreply(m, r);			free(r);		} else			l = &(r->next);	}}voidpingsend(Machine *m){	char buf[128];	Icmp *ip;	int i;	Req *r;	char err[ERRMAX];	ip = (Icmp*)buf;	r = malloc(sizeof *r);	if(r == nil)		return;	for(i = 32; i < 64; i++)		buf[i] = i;	ip->type = EchoRequest;	ip->code = 0;	ip->seq[0] = m->seq;	ip->seq[1] = m->seq>>8;	r->seq = m->seq;	r->next = nil;	lock(m);	pingclean(m, -1, nsec(), 0);	if(m->first == nil)		m->first = r;	else		m->last->next = r;	m->last = r;	r->time = nsec();	unlock(m);	if(write(m->pingfd, ip, MSGLEN) < MSGLEN){		errstr(err, sizeof err);		if(strstr(err, "unreach")||strstr(err, "exceed"))

⌨️ 快捷键说明

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