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

📄 icmp6.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <ip.h>#include "dat.h"#include "protos.h"typedef struct Hdr	Hdr;struct Hdr{	uchar	type;	uchar	code;	uchar	cksum[2];	/* Checksum */	uchar	data[1];};enum{	ICMP6LEN=	4,};enum{	Ot,	/* type */	Op,	/* next protocol */};static Field p_fields[] = {	{"t",		Fnum,	Ot,	"type",	} ,	{0}};enum{		// ICMPv6 types	EchoReply	= 0,	UnreachableV6	= 1,	PacketTooBigV6	= 2,	TimeExceedV6	= 3,	ParamProblemV6	= 4,	Redirect	= 5,	EchoRequest	= 8,	TimeExceed	= 11,	InParmProblem	= 12,	Timestamp	= 13,	TimestampReply	= 14,	InfoRequest	= 15,	InfoReply	= 16,	AddrMaskRequest = 17,	AddrMaskReply   = 18,	EchoRequestV6	= 128,	EchoReplyV6	= 129,	RouterSolicit	= 133,	RouterAdvert	= 134,	NbrSolicit	= 135,	NbrAdvert	= 136,	RedirectV6	= 137,	Maxtype6	= 137,};static Mux p_mux[] ={	{"ip6",	UnreachableV6, },	{"ip6",	RedirectV6, },	{"ip6",	TimeExceedV6, },	{0},};char *icmpmsg6[256] ={[EchoReply]		"EchoReply",[UnreachableV6]		"UnreachableV6",[PacketTooBigV6]	"PacketTooBigV6",[TimeExceedV6]		"TimeExceedV6",[Redirect]		"Redirect",[EchoRequest]		"EchoRequest",[TimeExceed]		"TimeExceed",[InParmProblem]		"InParmProblem",[Timestamp]		"Timestamp",[TimestampReply]	"TimestampReply",[InfoRequest]		"InfoRequest",[InfoReply]		"InfoReply",[AddrMaskRequest]	"AddrMaskRequest",[AddrMaskReply]		"AddrMaskReply",[EchoRequestV6]		"EchoRequestV6",[EchoReplyV6]		"EchoReplyV6",[RouterSolicit]		"RouterSolicit",[RouterAdvert]		"RouterAdvert",[NbrSolicit]		"NbrSolicit",[NbrAdvert]		"NbrAdvert",[RedirectV6]		"RedirectV6",};static char *unreachcode[] ={[0]	"no route to destination",[1]	"comm with destination administratively prohibited",[2]	"icmp unreachable: unassigned error code (2)",[3]	"address unreachable",[4]	"port unreachable",[5]	"icmp unreachable: unknown code",};static char *timexcode[] ={[0]	"hop limit exc",[1]	"reassmbl time exc",[2]	"icmp time exc: unknown code",};static char *parpcode[] ={[0]	"erroneous header field encountered",[1]	"unrecognized Next Header type encountered",[2]	"unrecognized IPv6 option encountered",[3]	"icmp par prob: unknown code",};enum {	sll	= 1,	tll	= 2,	pref	= 3,	redir	= 4,	mtu	= 5,};static char *icmp6opts[256] = {[0]	"unknown opt",[1]	"sll_addr",[2]	"tll_addr",[3]	"pref_opt",[4]	"redirect",[5]	"mtu_opt",};static voidp_compile(Filter *f){	if(f->op == '='){		compile_cmp(icmp6.name, f, p_fields);		return;	}	if(strcmp(f->s, "ip6") == 0){		f->pr = p_mux->pr;		f->subop = Op;		return;	}	sysfatal("unknown icmp field or protocol: %s", f->s);}static intp_filter(Filter *f, Msg *m){	Hdr *h;	if(m->pe - m->ps < ICMP6LEN)		return 0;	h = (Hdr*)m->ps;	m->ps += ICMP6LEN;	switch(f->subop){	case Ot:		if(h->type == f->ulv)			return 1;		break;	case Op:		switch(h->type){		case UnreachableV6:		case RedirectV6:		case TimeExceedV6:			m->ps += 4;			return 1;		}	}	return 0;}static char*opt_seprint(Msg *m){	int otype, osz, pktsz;	uchar *a;	char *p = m->p;	char *e = m->e;	char *opt;	char optbuf[12];	pktsz = m->pe - m->ps;	a = m->ps;	while (pktsz > 0) {		otype = *a;		opt = icmp6opts[otype];		if(opt == nil){			sprint(optbuf, "0x%ux", otype);			opt = optbuf;		}		osz = (*(a+1)) * 8;		switch (otype) {		default:			p = seprint(p, e, "\n	  option=%s ", opt);			m->pr = &dump;			return p;		case sll:		case tll:			if ((pktsz < osz) || (osz != 8)) { 				p = seprint(p, e, "\n	  option=%s bad size=%d", opt, osz);				m->pr = &dump;				return p;			}			p = seprint(p, e, "\n	  option=%s maddr=%E", opt, a+2);			pktsz -= osz;			a += osz;			break;		case pref:			if ((pktsz < osz) || (osz != 32)) { 				p = seprint(p, e, "\n	  option=%s: bad size=%d", opt, osz);				m->pr = &dump;				return p;			}			p = seprint(p, e, "\n	  option=%s pref=%I preflen=%3.3d lflag=%1.1d aflag=%1.1d unused1=%1.1d validlt=%d preflt=%d unused2=%1.1d",				opt,				a+16,				(int) (*(a+2)),				(*(a+3) & (1 << 7))!=0,				(*(a+3) & (1 << 6))!=0,				(*(a+3) & 63) != 0,				NetL(a+4),				NetL(a+8),				NetL(a+12)!=0);			pktsz -= osz;			a += osz;						break;		case redir:			if (pktsz < osz) { 				p = seprint(p, e, "\n	  option=%s: bad size=%d", opt, osz);				m->pr = &dump;				return p;			}			p = seprint(p, e, "\n	  option=%s len %d", opt, osz);			a += osz;			m->ps = a;			return p;					case mtu:			if ((pktsz < osz) || (osz != 8)) { 				p = seprint(p, e, "\n	  option=%s: bad size=%d", opt, osz);				m->pr = &dump;				return p;			}			p = seprint(p, e, "\n	  option=%s unused=%1.1d mtu=%d", opt, NetL(a+2)!=0, NetL(a+4));			pktsz -= osz;			a += osz;			break;		}	}	m->ps = a;	return p;}static intp_seprint(Msg *m){	Hdr *h;	char *tn;	char *p = m->p;	char *e = m->e;	int i;	uchar *a;//	ushort cksum2, cksum;	h = (Hdr*)m->ps;	m->ps += ICMP6LEN;	m->pr = &dump;	a = m->ps;	if(m->pe - m->ps < ICMP6LEN)		return -1;	tn = icmpmsg6[h->type];	if(tn == nil)		p = seprint(p, e, "t=%ud c=%d ck=%4.4ux", h->type,			h->code, (ushort)NetS(h->cksum));	else		p = seprint(p, e, "t=%s c=%d ck=%4.4ux", tn,			h->code, (ushort)NetS(h->cksum));	/*	if(Cflag){		cksum = NetS(h->cksum);		h->cksum[0] = 0;		h->cksum[1] = 0;		cksum2 = ~ptclbsum((uchar*)h, m->pe - m->ps + ICMP6LEN) & 0xffff;		if(cksum != cksum2)			p = seprint(p,e, " !ck=%4.4ux", cksum2);	}	*/	switch(h->type){	case UnreachableV6:		m->ps += 4;		m->pr = &ip6;		if (h->code >= nelem(unreachcode))			i = nelem(unreachcode)-1;		else			i = h->code;		p = seprint(p, e, " code=%s unused=%1.1d ", unreachcode[i], NetL(a)!=0);		break;	case PacketTooBigV6:		m->ps += 4;		m->pr = &ip6;		p = seprint(p, e, " mtu=%4.4d ", NetL(a));		break;	case TimeExceedV6:		m->ps += 4;		m->pr = &ip6;		if (h->code >= nelem(timexcode))			i = nelem(timexcode)-1;		else			i = h->code;		p = seprint(p, e, " code=%s unused=%1.1d ", timexcode[i], NetL(a)!=0);		break;	case ParamProblemV6:		m->ps += 4;		m->pr = &ip6;		if (h->code > nelem(parpcode))			i = nelem(parpcode)-1;		else			i = h->code;		p = seprint(p, e, " code=%s ptr=%2.2ux", parpcode[i], h->data[0]);		break;	case EchoReplyV6:	case EchoRequestV6:		m->ps += 4;		p = seprint(p, e, " id=%ux seq=%ux",			NetS(h->data), NetS(h->data+2));		break;	case RouterSolicit:		m->ps += 4;		m->pr = nil;		m->p = seprint(p, e, " unused=%1.1d ", NetL(a)!=0);		p = opt_seprint(m);		break;	case RouterAdvert:		m->ps += 12;		m->pr = nil;		m->p = seprint(p, e, " hoplim=%3.3d mflag=%1.1d oflag=%1.1d unused=%1.1d routerlt=%8.8d reachtime=%d rxmtimer=%d",			(int) *a,			(*(a+1) & (1 << 7)) != 0,			(*(a+1) & (1 << 6)) != 0,			(*(a+1) & 63) != 0,			NetS(a+2),			NetL(a+4),			NetL(a+8));		p = opt_seprint(m);		break;	case NbrSolicit:		m->ps += 20;		m->pr = nil;		m->p = seprint(p, e, " unused=%1.1d targ %I", NetL(a)!=0, a+4);		p = opt_seprint(m);		break;	case NbrAdvert:		m->ps += 20;		m->pr = nil;		m->p = seprint(p, e, " rflag=%1.1d sflag=%1.1d oflag=%1.1d targ=%I",			(*a & (1 << 7)) != 0,			(*a & (1 << 6)) != 0,			(*a & (1 << 5)) != 0,			a+4);		p = opt_seprint(m);		break;	case RedirectV6:		m->ps += 36;		m->pr = &ip6;		m->p = seprint(p, e, " unused=%1.1d targ=%I dest=%I", NetL(a)!=0, a+4, a+20);		p = opt_seprint(m);		break;	case Timestamp:	case TimestampReply:		m->ps += 12;		p = seprint(p, e, " orig=%ud rcv=%ux xmt=%ux",			NetL(h->data), NetL(h->data+4),			NetL(h->data+8));		m->pr = nil;		break;	case InfoRequest:	case InfoReply:		break;	}	m->p = p;	return 0;}Proto icmp6 ={	"icmp6",	p_compile,	p_filter,	p_seprint,	p_mux,	"%lud",	p_fields,	defaultframer,};

⌨️ 快捷键说明

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