diff options
Diffstat (limited to 'src/cmd/ip/snoopy/gre.c')
-rwxr-xr-x | src/cmd/ip/snoopy/gre.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/cmd/ip/snoopy/gre.c b/src/cmd/ip/snoopy/gre.c new file mode 100755 index 00000000..908d1553 --- /dev/null +++ b/src/cmd/ip/snoopy/gre.c @@ -0,0 +1,83 @@ + +/* GRE flag bits */ +enum { + GRE_chksum = (1<<15), + GRE_routing = (1<<14), + GRE_key = (1<<13), + GRE_seq = (1<<12), + GRE_srcrt = (1<<11), + GRE_recur = (7<<8), + GRE_ack = (1<<7), + GRE_ver = 0x7, +}; + +/* GRE protocols */ +enum { + GRE_sna = 0x0004, + GRE_osi = 0x00fe, + GRE_pup = 0x0200, + GRE_xns = 0x0600, + GRE_ip = 0x0800, + GRE_chaos = 0x0804, + GRE_rfc826 = 0x0806, + GRE_frarp = 0x0808, + GRE_vines = 0x0bad, + GRE_vinesecho = 0x0bae, + GRE_vinesloop = 0x0baf, + GRE_decnetIV = 0x6003, + GRE_ppp = 0x880b, +}; + +int +sprintgre(void *a, char *buf, int len) +{ + int flag, prot, chksum, offset, key, seq, ack; + int n; + uchar *p = a; + + chksum = offset = key = seq = ack = 0; + + flag = NetS(p); + prot = NetS(p+2); + p += 4; len -= 4; + if(flag & (GRE_chksum|GRE_routing)){ + chksum = NetS(p); + offset = NetS(p+2); + p += 4; len -= 4; + } + if(flag&GRE_key){ + key = NetL(p); + p += 4; len -= 4; + } + if(flag&GRE_seq){ + seq = NetL(p); + p += 4; len -= 4; + } + if(flag&GRE_ack){ + ack = NetL(p); + p += 4; len -= 4; + } + /* skip routing if present */ + if(flag&GRE_routing) { + while(len >= 4 && (n=p[3]) != 0) { + len -= n; + p += n; + } + } + + USED(offset); + USED(chksum); + + n = sprint(buf, "GRE(f %4.4ux p %ux k %ux", flag, prot, key); + if(flag&GRE_seq) + n += sprint(buf+n, " s %ux", seq); + if(flag&GRE_ack) + n += sprint(buf+n, " a %ux", ack); + n += sprint(buf+n, " len = %d/%d) ", len, key>>16); + if(prot == GRE_ppp && len > 0) + n += sprintppp(p, buf+n, len); + else + n += sprintx(p, buf+n, len); + + return n; +} |