aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ip/snoopy/gre.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/ip/snoopy/gre.c')
-rwxr-xr-xsrc/cmd/ip/snoopy/gre.c83
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;
+}