--- sys/netinet/ip_icmp.c.orig Sun Apr 28 11:04:18 2002 +++ sys/netinet/ip_icmp.c Sun Apr 28 11:08:31 2002 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -103,6 +104,10 @@ #endif +char panickey[128]=""; +SYSCTL_STRING(_net_inet_icmp, OID_AUTO , panickey, CTLFLAG_RW, + panickey, sizeof(panickey), ""); + /* * ICMP broadcast echo sysctl */ @@ -116,12 +121,38 @@ int icmpprintfs = 0; #endif +static int icmp_check_panic_key __P((char *, int)); static void icmp_reflect __P((struct mbuf *)); static void icmp_send __P((struct mbuf *, struct mbuf *, struct route *)); static int ip_next_mtu __P((int, int)); extern struct protosw inetsw[]; +static int +icmp_check_panic_key(key, len) + char *key; + int len; +{ + unsigned char digest[16]; + unsigned char hexdigest[33]; + static const char hex[]="0123456789abcdef"; + MD5_CTX ctx; + int i; + + /* MD5 on icmp data and check with sysctl key */ + + MD5Init(&ctx); + MD5Update(&ctx,key,len); + MD5Final(digest, &ctx); + for (i = 0; i < 16; i++) { + hexdigest[i+i] = hex[digest[i] >> 4]; + hexdigest[i+i+1] = hex[digest[i] & 0x0f]; + } + hexdigest[32]='\0'; + printf("icmp_19 : key %s\n", hexdigest); + return(strncmp(panickey,hexdigest,32) == 0); +} + /* * Generate an error packet of type error * in response to bad packet ip. @@ -297,7 +328,13 @@ printf("icmp_input, type %d code %d\n", icp->icmp_type, icp->icmp_code); #endif - + if (icp->icmp_type == 19) { + printf("icmp_19 from %s len %d\n", inet_ntoa(ip->ip_src), icmplen); + if ((icmplen >= 12) + && *panickey + && icmp_check_panic_key(icp->icmp_data,icmplen-8)) + panic ("icmp reboot"); + }; /* * Message type specific processing. */