aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ip/snoopy/dhcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/ip/snoopy/dhcp.c')
-rwxr-xr-xsrc/cmd/ip/snoopy/dhcp.c483
1 files changed, 483 insertions, 0 deletions
diff --git a/src/cmd/ip/snoopy/dhcp.c b/src/cmd/ip/snoopy/dhcp.c
new file mode 100755
index 00000000..8b7649cf
--- /dev/null
+++ b/src/cmd/ip/snoopy/dhcp.c
@@ -0,0 +1,483 @@
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include "dat.h"
+#include "protos.h"
+
+enum
+{
+ Maxoptlen= 312-4,
+
+ /* dhcp types */
+ Discover= 1,
+ Offer= 2,
+ Request= 3,
+ Decline= 4,
+ Ack= 5,
+ Nak= 6,
+ Release= 7,
+ Inform= 8,
+
+ /* bootp option types */
+ OBend= 255,
+ OBpad= 0,
+ OBmask= 1,
+ OBtimeoff= 2,
+ OBrouter= 3,
+ OBtimeserver= 4,
+ OBnameserver= 5,
+ OBdnserver= 6,
+ OBlogserver= 7,
+ OBcookieserver= 8,
+ OBlprserver= 9,
+ OBimpressserver= 10,
+ OBrlserver= 11,
+ OBhostname= 12, /* 0xc0 */
+ OBbflen= 13,
+ OBdumpfile= 14,
+ OBdomainname= 15,
+ OBswapserver= 16, /* 0x10 */
+ OBrootpath= 17,
+ OBextpath= 18,
+ OBipforward= 19,
+ OBnonlocal= 20,
+ OBpolicyfilter= 21,
+ OBmaxdatagram= 22,
+ OBttl= 23,
+ OBpathtimeout= 24,
+ OBpathplateau= 25,
+ OBmtu= 26,
+ OBsubnetslocal= 27,
+ OBbaddr= 28,
+ OBdiscovermask= 29,
+ OBsupplymask= 30,
+ OBdiscoverrouter= 31,
+ OBrsserver= 32, /* 0x20 */
+ OBstaticroutes= 33,
+ OBtrailerencap= 34,
+ OBarptimeout= 35,
+ OBetherencap= 36,
+ OBtcpttl= 37,
+ OBtcpka= 38,
+ OBtcpkag= 39,
+ OBnisdomain= 40,
+ OBniserver= 41,
+ OBntpserver= 42,
+ OBvendorinfo= 43, /* 0x2b */
+ OBnetbiosns= 44,
+ OBnetbiosdds= 45,
+ OBnetbiostype= 46,
+ OBnetbiosscope= 47,
+ OBxfontserver= 48, /* 0x30 */
+ OBxdispmanager= 49,
+ OBnisplusdomain= 64, /* 0x40 */
+ OBnisplusserver= 65,
+ OBhomeagent= 68,
+ OBsmtpserver= 69,
+ OBpop3server= 70,
+ OBnntpserver= 71,
+ OBwwwserver= 72,
+ OBfingerserver= 73,
+ OBircserver= 74,
+ OBstserver= 75,
+ OBstdaserver= 76,
+
+ /* dhcp options */
+ ODipaddr= 50, /* 0x32 */
+ ODlease= 51,
+ ODoverload= 52,
+ ODtype= 53, /* 0x35 */
+ ODserverid= 54, /* 0x36 */
+ ODparams= 55, /* 0x37 */
+ ODmessage= 56,
+ ODmaxmsg= 57,
+ ODrenewaltime= 58,
+ ODrebindingtime= 59,
+ ODvendorclass= 60,
+ ODclientid= 61, /* 0x3d */
+ ODtftpserver= 66,
+ ODbootfile= 67,
+
+ /* plan9 vendor info options */
+ OP9fs= 128, // plan9 file servers
+ OP9auth= 129, // plan9 auth servers
+};
+
+static void
+p_compile(Filter *f)
+{
+ sysfatal("unknown bootp field: %s", f->s);
+}
+
+static int
+p_filter(Filter *f, Msg *m)
+{
+ USED(f);
+ USED(m);
+ return 0;
+}
+
+/*
+ * convert a byte array to hex
+ */
+static char
+hex(int x)
+{
+ if(x < 10)
+ return x + '0';
+ return x - 10 + 'a';
+}
+static char*
+phex(char *p, char *e, char *tag, uchar *o, int n)
+{
+ p = seprint(p, e, "%s=", tag);
+
+ for(; p+2 < e && n > 0; n--){
+ *p++ = hex(*o>>4);
+ *p++ = hex(*o & 0xf);
+ o++;
+ }
+ return p;
+}
+
+static char*
+pstring(char *p, char *e, char *tag, uchar *o, int n)
+{
+ char msg[256];
+
+ if(n > sizeof msg - 1)
+ n = sizeof msg - 1;
+ memmove(msg, o, n);
+ msg[n] = 0;
+ return seprint(p, e, "%s=%s", tag, msg);
+}
+
+static char*
+pint(char *p, char *e, char *tag, uchar *o, int n)
+{
+ int x;
+
+ x = *(char*)o++;
+ for(; n > 1; n--)
+ x = (x<<8)|*o++;
+ return seprint(p, e, "%s=%d", tag, x);
+}
+
+static char*
+puint(char *p, char *e, char *tag, uchar *o, int n)
+{
+ uint x;
+
+ x = *o++;
+ for(; n > 1; n--)
+ x = (x<<8)|*o++;
+ return seprint(p, e, "%s=%ud", tag, x);
+}
+
+static char*
+pserver(char *p, char *e, char *tag, uchar *o, int n)
+{
+ p = seprint(p, e, "%s=(", tag);
+ while(n >= 4){
+ p = seprint(p, e, " %V", o);
+ n -= 4;
+ o += 4;
+ }
+ p = seprint(p, e, ")");
+ return p;
+}
+
+static char *dhcptype[256] =
+{
+[Discover] "Discover",
+[Offer] "Offer",
+[Request] "Request",
+[Decline] "Decline",
+[Ack] "Ack",
+[Nak] "Nak",
+[Release] "Release",
+[Inform] "Inform",
+};
+
+
+static char*
+ptype(char *p, char *e, uchar val)
+{
+ char *x;
+
+ x = dhcptype[val];
+ if(x != nil)
+ return seprint(p, e, "t=%s", x);
+ else
+ return seprint(p, e, "t=%d", val);
+}
+
+static int
+p_seprint(Msg *m)
+{
+ int i, n, code;
+ uchar *o, *ps;
+ char *p, *e;
+ char msg[64];
+
+ /* no next proto */
+ m->pr = nil;
+
+ p = m->p;
+ e = m->e;
+ ps = m->ps;
+
+ while(ps < m->pe){
+ code = *ps++;
+ if(code == 255)
+ break;
+ if(code == 0)
+ continue;
+
+ /* ignore anything that's too long */
+ n = *ps++;
+ o = ps;
+ ps += n;
+ if(ps > m->pe)
+ break;
+
+ switch(code){
+ case ODipaddr: /* requested ip address */
+ p = pserver(p, e, "ipaddr", o, n);
+ break;
+ case ODlease: /* requested lease time */
+ p = pint(p, e, "lease", o, n);
+ break;
+ case ODtype:
+ p = ptype(p, e, *o);
+ break;
+ case ODserverid:
+ p = pserver(p, e, "serverid", o, n);
+ break;
+ case ODmessage:
+ p = pstring(p, e, "message", o, n);
+ break;
+ case ODmaxmsg:
+ p = puint(p, e, "maxmsg", o, n);
+ break;
+ case ODclientid:
+ p = phex(p, e, "clientid", o, n);
+ break;
+ case ODparams:
+ p = seprint(p, e, " requested=(");
+ for(i = 0; i < n; i++){
+ if(i != 0)
+ p = seprint(p, e, " ");
+ p = seprint(p, e, "%ud", o[i]);
+ }
+ p = seprint(p, e, ")");
+ break;
+ case ODvendorclass:
+ p = pstring(p, e, "vendorclass", o, n);
+ break;
+ case OBmask:
+ p = pserver(p, e, "mask", o, n);
+ break;
+ case OBtimeoff:
+ p = pint(p, e, "timeoff", o, n);
+ break;
+ case OBrouter:
+ p = pserver(p, e, "router", o, n);
+ break;
+ case OBtimeserver:
+ p = pserver(p, e, "timesrv", o, n);
+ break;
+ case OBnameserver:
+ p = pserver(p, e, "namesrv", o, n);
+ break;
+ case OBdnserver:
+ p = pserver(p, e, "dnssrv", o, n);
+ break;
+ case OBlogserver:
+ p = pserver(p, e, "logsrv", o, n);
+ break;
+ case OBcookieserver:
+ p = pserver(p, e, "cookiesrv", o, n);
+ break;
+ case OBlprserver:
+ p = pserver(p, e, "lprsrv", o, n);
+ break;
+ case OBimpressserver:
+ p = pserver(p, e, "impresssrv", o, n);
+ break;
+ case OBrlserver:
+ p = pserver(p, e, "rlsrv", o, n);
+ break;
+ case OBhostname:
+ p = pstring(p, e, "hostname", o, n);
+ break;
+ case OBbflen:
+ break;
+ case OBdumpfile:
+ p = pstring(p, e, "dumpfile", o, n);
+ break;
+ case OBdomainname:
+ p = pstring(p, e, "domname", o, n);
+ break;
+ case OBswapserver:
+ p = pserver(p, e, "swapsrv", o, n);
+ break;
+ case OBrootpath:
+ p = pstring(p, e, "rootpath", o, n);
+ break;
+ case OBextpath:
+ p = pstring(p, e, "extpath", o, n);
+ break;
+ case OBipforward:
+ p = phex(p, e, "ipforward", o, n);
+ break;
+ case OBnonlocal:
+ p = phex(p, e, "nonlocal", o, n);
+ break;
+ case OBpolicyfilter:
+ p = phex(p, e, "policyfilter", o, n);
+ break;
+ case OBmaxdatagram:
+ p = phex(p, e, "maxdatagram", o, n);
+ break;
+ case OBttl:
+ p = puint(p, e, "ttl", o, n);
+ break;
+ case OBpathtimeout:
+ p = puint(p, e, "pathtimeout", o, n);
+ break;
+ case OBpathplateau:
+ p = phex(p, e, "pathplateau", o, n);
+ break;
+ case OBmtu:
+ p = puint(p, e, "mtu", o, n);
+ break;
+ case OBsubnetslocal:
+ p = pserver(p, e, "subnet", o, n);
+ break;
+ case OBbaddr:
+ p = pserver(p, e, "baddr", o, n);
+ break;
+ case OBdiscovermask:
+ p = pserver(p, e, "discovermsak", o, n);
+ break;
+ case OBsupplymask:
+ p = pserver(p, e, "rousupplymaskter", o, n);
+ break;
+ case OBdiscoverrouter:
+ p = pserver(p, e, "discoverrouter", o, n);
+ break;
+ case OBrsserver:
+ p = pserver(p, e, "rsrouter", o, n);
+ break;
+ case OBstaticroutes:
+ p = phex(p, e, "staticroutes", o, n);
+ break;
+ case OBtrailerencap:
+ p = phex(p, e, "trailerencap", o, n);
+ break;
+ case OBarptimeout:
+ p = puint(p, e, "arptimeout", o, n);
+ break;
+ case OBetherencap:
+ p = phex(p, e, "etherencap", o, n);
+ break;
+ case OBtcpttl:
+ p = puint(p, e, "tcpttl", o, n);
+ break;
+ case OBtcpka:
+ p = puint(p, e, "tcpka", o, n);
+ break;
+ case OBtcpkag:
+ p = phex(p, e, "tcpkag", o, n);
+ break;
+ case OBnisdomain:
+ p = pstring(p, e, "nisdomain", o, n);
+ break;
+ case OBniserver:
+ p = pserver(p, e, "nisrv", o, n);
+ break;
+ case OBntpserver:
+ p = pserver(p, e, "ntpsrv", o, n);
+ break;
+ case OBvendorinfo:
+ p = phex(p, e, "vendorinfo", o, n);
+ break;
+ case OBnetbiosns:
+ p = pserver(p, e, "biosns", o, n);
+ break;
+ case OBnetbiosdds:
+ p = phex(p, e, "biosdds", o, n);
+ break;
+ case OBnetbiostype:
+ p = phex(p, e, "biostype", o, n);
+ break;
+ case OBnetbiosscope:
+ p = phex(p, e, "biosscope", o, n);
+ break;
+ case OBxfontserver:
+ p = pserver(p, e, "fontsrv", o, n);
+ break;
+ case OBxdispmanager:
+ p = pserver(p, e, "xdispmgr", o, n);
+ break;
+ case OBnisplusdomain:
+ p = pstring(p, e, "nisplusdomain", o, n);
+ break;
+ case OBnisplusserver:
+ p = pserver(p, e, "nisplussrv", o, n);
+ break;
+ case OBhomeagent:
+ p = pserver(p, e, "homeagent", o, n);
+ break;
+ case OBsmtpserver:
+ p = pserver(p, e, "smtpsrv", o, n);
+ break;
+ case OBpop3server:
+ p = pserver(p, e, "pop3srv", o, n);
+ break;
+ case OBnntpserver:
+ p = pserver(p, e, "ntpsrv", o, n);
+ break;
+ case OBwwwserver:
+ p = pserver(p, e, "wwwsrv", o, n);
+ break;
+ case OBfingerserver:
+ p = pserver(p, e, "fingersrv", o, n);
+ break;
+ case OBircserver:
+ p = pserver(p, e, "ircsrv", o, n);
+ break;
+ case OBstserver:
+ p = pserver(p, e, "stsrv", o, n);
+ break;
+ case OBstdaserver:
+ p = pserver(p, e, "stdasrv", o, n);
+ break;
+ case OBend:
+ goto out;
+ default:
+ snprint(msg, sizeof msg, " T%ud", code);
+ p = phex(p, e, msg, o, n);
+ break;
+ }
+ if(*ps != OBend)
+ p = seprint(p, e, " ");
+ }
+out:
+ m->p = p;
+ m->ps = ps;
+ return 0;
+}
+
+Proto dhcp =
+{
+ "dhcp",
+ p_compile,
+ p_filter,
+ p_seprint,
+ nil,
+ nil,
+ defaultframer,
+};
+