Subject: printing ICMP type/subtype codes with ipmon
To: None <netbsd-users@netbsd.org>
From: Steve Bellovin <smb@research.att.com>
List: netbsd-users
Date: 12/10/2001 08:54:47
This is a multipart MIME message.

--==_Exmh_-3616449160
Content-Type: text/plain; charset=us-ascii

Here are some changes to the 1.5.2 ipmon so that it prints ICMP type 
and subtype codes symbolically.  I know that this is external code 
imported into NetBSD, so I've sent it off to Darren as well, but folks 
may want to use it now regardless of when or if it's integrated into 
the base source.


--==_Exmh_-3616449160
Content-Type: text/plain ; name="ipmon.diff"; charset=us-ascii
Content-Description: ipmon.diff
Content-Disposition: attachment; filename="ipmon.diff"

*** /usr/src/dist/ipf/ipmon.c	Thu Aug 31 08:49:46 2000
--- ipmon.c	Sun Dec  9 11:24:58 2001
***************
*** 130,135 ****
--- 130,138 ----
  static	void	init_tabs __P((void));
  static	char	*getproto __P((u_int));
  
+ static	char *icmp_subtype __P((int, int));
+ static	char *icmp_type __P((int));
+ 
  static	char	**protocols = NULL;
  static	char	**udp_ports = NULL;
  static	char	**tcp_ports = NULL;
***************
*** 500,508 ****
  		(void) sprintf(t, "%s -> ", hostname(res, sl->isl_v,
  						     (u_32_t *)&sl->isl_src));
  		t += strlen(t);
! 		(void) sprintf(t, "%s PR icmp %d",
  			hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst),
! 			sl->isl_itype);
  	}
  	t += strlen(t);
  	if (sl->isl_type != ISL_NEW) {
--- 503,511 ----
  		(void) sprintf(t, "%s -> ", hostname(res, sl->isl_v,
  						     (u_32_t *)&sl->isl_src));
  		t += strlen(t);
! 		(void) sprintf(t, "%s PR icmp %s",
  			hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst),
! 			icmp_type(sl->isl_itype));
  	}
  	t += strlen(t);
  	if (sl->isl_type != ISL_NEW) {
***************
*** 736,744 ****
  		ic = (struct icmp *)((char *)ip + hl);
  		(void) sprintf(t, "%s -> ", hostname(res, v, s));
  		t += strlen(t);
! 		(void) sprintf(t, "%s PR icmp len %hu %hu icmp %d/%d",
  			hostname(res, v, d), hl, plen,
! 			ic->icmp_type, ic->icmp_code);
  		if (ic->icmp_type == ICMP_UNREACH ||
  		    ic->icmp_type == ICMP_SOURCEQUENCH ||
  		    ic->icmp_type == ICMP_PARAMPROB ||
--- 739,747 ----
  		ic = (struct icmp *)((char *)ip + hl);
  		(void) sprintf(t, "%s -> ", hostname(res, v, s));
  		t += strlen(t);
! 		(void) sprintf(t, "%s PR icmp len %hu %hu icmp %s/%s",
  			hostname(res, v, d), hl, plen,
! 			icmp_type(ic->icmp_type), icmp_subtype(ic->icmp_type, ic->icmp_code));
  		if (ic->icmp_type == ICMP_UNREACH ||
  		    ic->icmp_type == ICMP_SOURCEQUENCH ||
  		    ic->icmp_type == ICMP_PARAMPROB ||
***************
*** 773,782 ****
  					HOSTNAME_V4(res, ipc->ip_src));
  				t += strlen(t);
  				(void) sprintf(t,
! 					" %s PR icmp len %hu %hu icmp %d/%d",
  					HOSTNAME_V4(res, ipc->ip_dst),
  					ipc->ip_hl << 2, i,
! 					icmp->icmp_type, icmp->icmp_code);
  
  			} else {
  				t += strlen(t);
--- 776,786 ----
  					HOSTNAME_V4(res, ipc->ip_src));
  				t += strlen(t);
  				(void) sprintf(t,
! 					" %s PR icmp len %hu %hu icmp %s/%s",
  					HOSTNAME_V4(res, ipc->ip_dst),
  					ipc->ip_hl << 2, i,
! 					icmp_type(icmp->icmp_type),
! 					icmp_subtype(icmp->icmp_type, icmp->icmp_code));
  
  			} else {
  				t += strlen(t);
***************
*** 1146,1149 ****
--- 1150,1259 ----
  	}
  	exit(0);
  	/* NOTREACHED */
+ }
+ 
+ struct icmp_subtype {
+ 	int	stval;
+ 	char	*stname;
+ };
+ 
+ struct icmp_subtype unreach_type[] = {
+ 	{ICMP_UNREACH_NET, "net"},
+ 	{ICMP_UNREACH_HOST, "host"},
+ 	{ICMP_UNREACH_PROTOCOL, "proto"},
+ 	{ICMP_UNREACH_PORT, "port"},
+ 	{ICMP_UNREACH_NEEDFRAG, "needfrag"},
+ 	{ICMP_UNREACH_SRCFAIL, "srcrtfail"},
+ 	{ICMP_UNREACH_NET_UNKNOWN, "netunknown"},
+ 	{ICMP_UNREACH_HOST_UNKNOWN, "hostunknown"},
+ 	{ICMP_UNREACH_ISOLATED, "isolated"},
+ 	{ICMP_UNREACH_NET_PROHIB, "netprohib"},
+ 	{ICMP_UNREACH_HOST_PROHIB, "hostprohib"},
+ 	{ICMP_UNREACH_TOSNET, "tosnet"},
+ 	{ICMP_UNREACH_TOSHOST, "hostnet"},
+ 	{ICMP_UNREACH_ADMIN_PROHIBIT, "admin"},
+ 	{0, NULL}
+ };
+ 
+ struct icmp_subtype redir_type[] = {
+ 	{ICMP_REDIRECT_NET, "net"},
+ 	{ICMP_REDIRECT_HOST, "host"},
+ 	{ICMP_REDIRECT_TOSNET, "tosnet"},
+ 	{ICMP_REDIRECT_TOSHOST, "toshost"},
+ 	{0, NULL}
+ };
+ 
+ struct icmp_subtype timxceed_type[] = {
+ 	{ICMP_TIMXCEED_INTRANS, "transit"},
+ 	{ICMP_TIMXCEED_REASS, "reassem"},
+ 	{0, NULL}
+ };
+ 
+ struct icmp_subtype param_type[] = {
+ 	{ICMP_PARAMPROB_OPTABSENT, "optmissing"},
+ 	{0, NULL}
+ };
+ 
+ 
+ struct icmp_types {
+ 	int	tval;
+ 	struct	icmp_subtype *stype;
+ 	char	*tname;
+ } icmp_types[] = {
+ 	{ICMP_ECHOREPLY, NULL, "pingrepl"},
+ 	{ICMP_UNREACH, unreach_type, "unreach"},
+ 	{ICMP_SOURCEQUENCH, NULL, "quench"},
+ 	{ICMP_REDIRECT, redir_type, "redir"},
+ 	{ICMP_ECHO, NULL, "ping"},
+ 	{ICMP_ROUTERADVERT, NULL, "radvrt"},
+ 	{ICMP_ROUTERSOLICIT, NULL, "rtsolicit"},
+ 	{ICMP_TIMXCEED, timxceed_type, "ttl"},
+ 	{ICMP_PARAMPROB, param_type, "param"},
+ 	{ICMP_TSTAMP, NULL, "timereq"},
+ 	{ICMP_TSTAMPREPLY, NULL, "timerepl"},
+ 	{ICMP_IREQ, NULL, "inforeq"},
+ 	{ICMP_IREQREPLY, NULL, "inforepl"},
+ 	{ICMP_MASKREQ, NULL, "maskreq"},
+ 	{ICMP_MASKREPLY, NULL, "maskrepl"},
+ 	{0, NULL, NULL}
+ };
+ 
+ static struct icmp_types *find_icmp_type(int t)
+ {
+ 	struct icmp_types *tp;
+ 
+ 	for (tp = icmp_types; tp->tname; tp++)
+ 		if (t == tp->tval) return tp;
+ 	return NULL;
+ }
+ static struct icmp_subtype *find_icmp_subtype(struct icmp_subtype *sp, int s)
+ {
+ 	for (; sp->stname; sp++)
+ 		if (s == sp->stval) return sp;
+ 	return NULL;
+ }
+ 
+ char *icmp_type(int t)
+ {
+ 	struct icmp_types *tp;
+ 	static char tbuf[30];
+ 
+ 	tp = find_icmp_type(t);
+ 	if (tp) return tp->tname;
+ 	snprintf(tbuf, sizeof tbuf, "%d", t);
+ 	return tbuf;
+ }
+ 
+ char *icmp_subtype(int t, int s)
+ {
+ 	struct icmp_types *tp;
+ 	struct icmp_subtype *sp;
+ 	static char sbuf[30];
+ 
+ 	tp = find_icmp_type(t);
+ 	if (tp == NULL || tp->stype == NULL || (sp = find_icmp_subtype(tp->stype, s)) == NULL) {
+ 		snprintf(sbuf, sizeof sbuf, "%d", s);
+ 		return sbuf;
+ 	}
+ 	else return sp->stname;
  }

--==_Exmh_-3616449160
Content-Type: text/plain; charset=us-ascii

		--Steve Bellovin, http://www.research.att.com/~smb
		Full text of "Firewalls" book now at http://www.wilyhacker.com

--==_Exmh_-3616449160--