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--