llc.c (2491B)
1 /* 2 * LLC. Only enough to dispatch to SNAP and IP. 3 */ 4 5 #include <u.h> 6 #include <libc.h> 7 #include <ip.h> 8 #include "dat.h" 9 #include "protos.h" 10 11 enum 12 { 13 UFmt = 3, 14 Gsap = 1, 15 IG = 1, 16 SFmt = 1, 17 UPoll = 0x10, 18 IsPoll = 0x100, 19 XidFi = 0x81, 20 21 SapNull = 0, 22 SapGlobal = 0xff, 23 Sap8021BI = 0x02, 24 Sap8021BG = 0x03, 25 SapSNA = 0x04, 26 SapIP = 0x06, 27 SapProwayNM = 0x0e, 28 Sap8021D = 0x42, 29 SapRS511 = 0x4e, 30 SapISO8208 = 0x7e, 31 SapProway = 0x8e, 32 SapSnap = 0xaa, 33 SapIpx = 0xe0, 34 SapNetbeui = 0xf0, 35 SapIsons = 0xfe, 36 }; 37 38 static Mux p_mux[] = 39 { 40 // Linux gives llc -> snap not llc -> ip. 41 // If we don't tell snoopy about llc -> ip, then the default patterns 42 // like snoopy -h radiotap -f dns work better. 43 // { "ip", SapIP }, 44 { "snap", SapSnap }, 45 { 0 } 46 }; 47 48 typedef struct Hdr Hdr; 49 struct Hdr 50 { 51 uchar dsap; 52 uchar ssap; 53 uchar dsapf; 54 uchar ssapf; 55 ushort ctl; 56 uchar isu; 57 int hdrlen; 58 }; 59 60 static int 61 unpackhdr(uchar *p, uchar *ep, Hdr *h) 62 { 63 if(p+3 > ep) 64 return -1; 65 h->dsapf = p[0]; 66 h->dsap = h->dsapf & ~IG; 67 h->ssapf = p[1]; 68 h->ssap = h->ssapf & ~Gsap; 69 h->ctl = p[2]; 70 h->hdrlen = 3; 71 if((h->ctl&UFmt) == UFmt) 72 h->isu = 1; 73 else{ 74 if(p+4 > ep) 75 return -1; 76 h->hdrlen = 4; 77 h->ctl = LittleS(p+2); 78 } 79 return 0; 80 } 81 82 enum 83 { 84 Ossap, 85 Odsap, 86 Ot, 87 }; 88 89 static Field p_fields[] = 90 { 91 { "ssap", Fnum, Ossap, "ssap" }, 92 { "dsap", Fnum, Odsap, "dsap" }, 93 { 0 } 94 }; 95 96 static void 97 p_compile(Filter *f) 98 { 99 Mux *m; 100 101 if(f->op == '='){ 102 compile_cmp(llc.name, f, p_fields); 103 return; 104 } 105 for(m = p_mux; m->name != nil; m++){ 106 if(strcmp(f->s, m->name) == 0){ 107 f->pr = m->pr; 108 f->ulv = m->val; 109 f->subop = Ot; 110 return; 111 } 112 } 113 sysfatal("unknown llc field or protocol: %s", f->s); 114 } 115 116 static int 117 p_filter(Filter *f, Msg *m) 118 { 119 Hdr h; 120 121 memset(&h, 0, sizeof h); 122 if(unpackhdr(m->ps, m->pe, &h) < 0) 123 return 0; 124 m->ps += h.hdrlen; 125 126 switch(f->subop){ 127 case Ossap: 128 return f->ulv == h.ssap; 129 case Odsap: 130 return f->ulv == h.dsap; 131 case Ot: 132 return f->ulv == h.ssap && f->ulv == h.dsap; 133 } 134 return 0; 135 } 136 137 static int 138 p_seprint(Msg *m) 139 { 140 Hdr h; 141 142 memset(&h, 0, sizeof h); 143 if(unpackhdr(m->ps, m->pe, &h) < 0) 144 return -1; 145 146 m->pr = &dump; 147 m->p = seprint(m->p, m->e, "ssap=%02x dsap=%02x ctl=%04x", h.ssap, h.dsap, h.ctl); 148 m->ps += h.hdrlen; 149 m->pr = &dump; 150 if(h.ssap == h.dsap){ 151 switch(h.ssap){ 152 case SapIP: 153 m->pr = &ip; 154 break; 155 case SapSnap: 156 m->pr = &snap; 157 break; 158 } 159 } 160 return 0; 161 } 162 163 Proto llc = 164 { 165 "llc", 166 p_compile, 167 p_filter, 168 p_seprint, 169 p_mux, 170 nil, 171 nil, 172 defaultframer 173 };