1 #include <u.h> 2 #include <libc.h> 3 #include <ip.h> 4 #include "dat.h" 5 #include "protos.h" 6 7 typedef struct { 8 uchar cmd; 9 uchar nea; 10 } Hdr; 11 12 enum { 13 Ocmd, 14 Onea, 15 Oea, 16 17 Hsize = 2, 18 }; 19 20 static Field p_fields[] = { 21 {"cmd", Fnum, Ocmd, "command", }, 22 {"nea", Fnum, Onea, "ea count", }, 23 {"ea", Fnum, Onea, "ethernet addr", }, 24 nil 25 }; 26 27 static void 28 p_compile(Filter *f) 29 { 30 if(f->op == '='){ 31 compile_cmp(aoerr.name, f, p_fields); 32 return; 33 } 34 sysfatal("unknown aoerr field: %s", f->s); 35 } 36 37 static int 38 p_filter(Filter *f, Msg *m) 39 { 40 uchar buf[6]; 41 int i; 42 Hdr *h; 43 44 if(m->pe - m->ps < Hsize) 45 return 0; 46 47 h = (Hdr*)m->ps; 48 m->ps += Hsize; 49 50 switch(f->subop){ 51 case Ocmd: 52 return h->cmd == f->ulv; 53 case Onea: 54 return h->nea == f->ulv; 55 case Oea: 56 if(m->pe - m->ps < 6*h->nea) 57 return 0; 58 for(i = 0; i < 6; i++) 59 buf[i] = f->ulv >> ((5 - i)*8); 60 for(i = 0; i < h->nea; i++) 61 if(memcmp(m->ps + 6*i, buf, 6) == 0) 62 return 1; 63 return 0; 64 } 65 return 0; 66 } 67 68 static char *ctab[] = { 69 "read", 70 "write", 71 "force", 72 }; 73 74 static int 75 p_seprint(Msg *m) 76 { 77 char *s; 78 int i; 79 Hdr *h; 80 81 if(m->pe - m->ps < Hsize) 82 return 0; 83 84 h = (Hdr*)m->ps; 85 m->ps += Hsize; 86 87 /* no next protocol */ 88 m->pr = nil; 89 90 s = "unk"; 91 if(h->cmd < nelem(ctab)) 92 s = ctab[h->cmd]; 93 m->p = seprint(m->p, m->e, "cmd=%d %s nea=%d", h->cmd, s, h->nea); 94 for(i = 0;; i++){ 95 if(h->nea < i) 96 break; 97 if(i == 3){ 98 m->p = seprint(m->p, m->e, " ..."); 99 break; 100 } 101 if(m->pe - m->ps < 6*i){ 102 m->p = seprint(m->p, m->e, " *short*"); 103 break; 104 } 105 m->p = seprint(m->p, m->e, " %E", m->pe + 6*i); 106 } 107 m->p = seprint(m->p, m->e, "\n"); 108 return 0; 109 } 110 111 Proto aoerr = { 112 "aoerr", 113 p_compile, 114 p_filter, 115 p_seprint, 116 nil, 117 nil, 118 p_fields, 119 defaultframer, 120 }; 121