This commit is contained in:
rsc 2006-02-14 19:42:28 +00:00
parent 2eef1fa316
commit a38a183626
22 changed files with 187 additions and 144 deletions

View file

@ -112,6 +112,7 @@ Proto arp =
p_filter, p_filter,
p_seprint, p_seprint,
nil, nil,
nil,
p_fields, p_fields,
defaultframer, defaultframer,
}; };
@ -123,6 +124,7 @@ Proto rarp =
p_filter, p_filter,
p_seprint, p_seprint,
nil, nil,
nil,
p_fields, p_fields,
defaultframer, defaultframer,
}; };

View file

@ -171,6 +171,7 @@ Proto bootp =
p_filter, p_filter,
p_seprint, p_seprint,
p_mux, p_mux,
"%#.8lux",
p_fields, p_fields,
defaultframer, defaultframer,
}; };

View file

@ -18,6 +18,7 @@ struct Proto
int (*filter)(Filter*, Msg*); int (*filter)(Filter*, Msg*);
int (*seprint)(Msg*); int (*seprint)(Msg*);
Mux* mux; Mux* mux;
char* valfmt;
Field* field; Field* field;
int (*framer)(int, uchar*, int); int (*framer)(int, uchar*, int);
}; };

View file

@ -106,15 +106,7 @@ enum
static void static void
p_compile(Filter *f) p_compile(Filter *f)
{ {
sysfatal("unknown bootp field: %s", f->s); sysfatal("unknown dhcp field: %s", f->s);
}
static int
p_filter(Filter *f, Msg *m)
{
USED(f);
USED(m);
return 0;
} }
/* /*
@ -474,10 +466,11 @@ Proto dhcp =
{ {
"dhcp", "dhcp",
p_compile, p_compile,
p_filter, nil,
p_seprint, p_seprint,
nil, nil,
nil, nil,
nil,
defaultframer, defaultframer,
}; };

View file

@ -5,20 +5,6 @@
#include "dat.h" #include "dat.h"
#include "protos.h" #include "protos.h"
static void
p_compile(Filter *f)
{
USED(f);
}
static int
p_filter(Filter *f, Msg *m)
{
USED(f);
USED(m);
return 0;
}
static char tohex[16] = { static char tohex[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' 'a', 'b', 'c', 'd', 'e', 'f'
@ -83,10 +69,11 @@ p_seprint(Msg *m)
Proto dump = Proto dump =
{ {
"dump", "dump",
p_compile, nil,
p_filter, nil,
p_seprint, p_seprint,
nil, nil,
nil, nil,
nil,
defaultframer, defaultframer,
}; };

View file

@ -23,6 +23,7 @@ static Mux p_mux[] =
{"ip6", 0x86dd, } , {"ip6", 0x86dd, } ,
{"pppoe_disc", 0x8863, }, {"pppoe_disc", 0x8863, },
{"pppoe_sess", 0x8864, }, {"pppoe_sess", 0x8864, },
{"eapol", 0x888e, },
{0} {0}
}; };
@ -116,6 +117,7 @@ Proto ether =
p_filter, p_filter,
p_seprint, p_seprint,
p_mux, p_mux,
"%#.4lux",
p_fields, p_fields,
defaultframer defaultframer
}; };

View file

@ -12,6 +12,7 @@ char *yyend; /* end of buffer to be parsed */
%term LOR %term LOR
%term LAND %term LAND
%term WORD %term WORD
%term NE
%right '!' %right '!'
%left '|' %left '|'
%left '&' %left '&'
@ -27,6 +28,14 @@ expr : WORD
{ $$ = $1; } { $$ = $1; }
| WORD '=' WORD | WORD '=' WORD
{ $2->l = $1; $2->r = $3; $$ = $2; } { $2->l = $1; $2->r = $3; $$ = $2; }
| WORD NE WORD
{ $2->l = newfilter();
$2->l->op = '=';
$2->l->l = $1;
$2->l->r = $3;
$2->op = '!';
$$ = $2;
}
| WORD '(' expr ')' | WORD '(' expr ')'
{ $1->l = $3; free($2); free($4); $$ = $1; } { $1->l = $3; free($2); free($4); $$ = $1; }
| '(' expr ')' | '(' expr ')'
@ -84,16 +93,17 @@ yylex(void)
} }
yylp++; yylp++;
if(*yylp == c) if(c == '!' && *yylp == '='){
switch(c){ c = NE;
case '&': yylp++;
}
else if(c == '&' && *yylp == '&'){
c = LAND; c = LAND;
yylp++; yylp++;
break; }
case '|': else if(c == '|' && *yylp == '|'){
c = LOR; c = LOR;
yylp++; yylp++;
break;
} }
yylval->op = c; yylval->op = c;
return c; return c;
@ -103,5 +113,6 @@ void
yyerror(char *e) yyerror(char *e)
{ {
USED(e); USED(e);
// longjmp(errjmp, 1);
sysfatal("error parsing filter"); sysfatal("error parsing filter");
} }

View file

@ -169,6 +169,7 @@ Proto hdlc =
p_filter, p_filter,
p_seprint, p_seprint,
p_mux, p_mux,
"%#.4lux",
nil, nil,
p_framer, p_framer,
}; };

View file

@ -191,6 +191,7 @@ Proto icmp =
p_filter, p_filter,
p_seprint, p_seprint,
p_mux, p_mux,
"%lud",
p_fields, p_fields,
defaultframer, defaultframer,
}; };

View file

@ -423,6 +423,7 @@ Proto icmp6 =
p_filter, p_filter,
p_seprint, p_seprint,
p_mux, p_mux,
"%lud",
p_fields, p_fields,
defaultframer, defaultframer,
}; };

View file

@ -141,6 +141,7 @@ Proto il =
p_filter, p_filter,
p_seprint, p_seprint,
p_mux, p_mux,
"%lud",
p_fields, p_fields,
defaultframer, defaultframer,
}; };

View file

@ -231,6 +231,7 @@ Proto ip =
p_filter, p_filter,
p_seprint, p_seprint,
p_mux, p_mux,
"%lud",
p_fields, p_fields,
defaultframer, defaultframer,
}; };

View file

@ -304,6 +304,7 @@ Proto ip6 =
p_filter, p_filter,
p_seprint, p_seprint,
p_mux, p_mux,
"%lud",
p_fields, p_fields,
defaultframer, defaultframer,
}; };

View file

@ -35,14 +35,21 @@ void mkprotograph(void);
Proto* findproto(char *name); Proto* findproto(char *name);
Filter* compile(Filter *f); Filter* compile(Filter *f);
void printfilter(Filter *f, char *tag); void printfilter(Filter *f, char *tag);
void printhelp(void); void printhelp(char*);
void tracepkt(uchar*, int); void tracepkt(uchar*, int);
void pcaphdr(void); void pcaphdr(void);
void
printusage(void)
{
fprint(2, "usage: %s [-CDdpst] [-N n] [-f filter] [-h first-header] path\n", argv0);
fprint(2, " for protocol help: %s -? [proto]\n", argv0);
}
void void
usage(void) usage(void)
{ {
fprint(2, "usage: %s [-std?] [-c] [-N n] [-f filter] [-h first-header] path", argv0); printusage();
exits("usage"); exits("usage");
} }
@ -74,20 +81,19 @@ main(int argc, char **argv)
mkprotograph(); mkprotograph();
ARGBEGIN{ ARGBEGIN{
default:
usage();
case '?': case '?':
printhelp(); printusage();
printhelp(ARGF());
exits(0); exits(0);
break; break;
case 'N': case 'N':
p = ARGF(); p = EARGF(usage());
if(p == nil)
usage();
Nflag = atoi(p); Nflag = atoi(p);
break; break;
case 'f': case 'f':
p = ARGF(); p = EARGF(usage());
if(p == nil)
usage();
yyinit(p); yyinit(p);
yyparse(); yyparse();
break; break;
@ -95,9 +101,7 @@ main(int argc, char **argv)
sflag = 1; sflag = 1;
break; break;
case 'h': case 'h':
p = ARGF(); p = EARGF(usage());
if(p == nil)
usage();
root = findproto(p); root = findproto(p);
if(root == nil) if(root == nil)
sysfatal("unknown protocol: %s", p); sysfatal("unknown protocol: %s", p);
@ -123,22 +127,28 @@ main(int argc, char **argv)
if(pcap) if(pcap)
pcaphdr(); pcaphdr();
if(argc > 1)
usage();
if(argc == 0) if(argc == 0)
file = nil; file = nil;
else else
file = argv[0]; file = argv[0];
if(tiflag){ if(tiflag){
if(file == nil)
sysfatal("must specify file with -t");
fd = open(file, OREAD); fd = open(file, OREAD);
if(fd < 0) if(fd < 0)
sysfatal("opening %s: %r", file); sysfatal("opening %s: %r", file);
}else{ }else{
fd = opendevice(file, pflag); fd = opendevice(file, pflag);
if(fd < 0) if(fd < 0)
sysfatal("opening device %s: %r", file ? file : "(all)"); sysfatal("opening device %s: %r", file);
} }
if(root == nil) if(root == nil)
root = &ether; root = &ether;
filter = compile(filter); filter = compile(filter);
if(tiflag){ if(tiflag){
@ -215,7 +225,7 @@ _filterpkt(Filter *f, Msg *m)
return 0; return 0;
m->needroot = 0; m->needroot = 0;
}else{ }else{
if(m->pr != nil && !(m->pr->filter)(f, m)) if(m->pr && (m->pr->filter==nil || !(m->pr->filter)(f, m)))
return 0; return 0;
} }
if(f->l == nil) if(f->l == nil)
@ -313,13 +323,10 @@ void
printpkt(char *p, char *e, uchar *ps, uchar *pe) printpkt(char *p, char *e, uchar *ps, uchar *pe)
{ {
Msg m; Msg m;
uvlong dt; ulong dt;
Tm tm;
tm = *localtime(pkttime/1000000000LL); dt = (pkttime-starttime)/1000000LL;
m.p = seprint(p, e, "%02d/%02d/%04d %02d:%02d:%02d.%09lld", m.p = seprint(p, e, "%6.6uld ms ", dt);
tm.mon+1, tm.mday, tm.year+1900, tm.hour, tm.min, tm.sec,
pkttime%1000000000LL);
m.ps = ps; m.ps = ps;
m.pe = pe; m.pe = pe;
m.e = e; m.e = e;
@ -635,14 +642,20 @@ _compile(Filter *f, Proto *last)
_compile(f->r, last); _compile(f->r, last);
break; break;
case WORD: case WORD:
if(last != nil) if(last != nil){
if(last->compile == nil)
sysfatal("unknown %s subprotocol: %s", f->pr->name, f->s);
(*last->compile)(f); (*last->compile)(f);
}
if(f->l) if(f->l)
_compile(f->l, f->pr); _compile(f->l, f->pr);
break; break;
case '=': case '=':
if(last == nil) if(last == nil)
sysfatal("internal error: compilewalk: badly formed tree"); sysfatal("internal error: compilewalk: badly formed tree");
if(last->compile == nil)
sysfatal("unknown %s field: %s", f->pr->name, f->s);
(*last->compile)(f); (*last->compile)(f);
break; break;
default: default:
@ -794,24 +807,96 @@ printfilter(Filter *f, char *tag)
} }
void void
printhelp(void) cat(void)
{ {
char buf[1024];
int n;
while((n = read(0, buf, sizeof buf)) > 0)
write(1, buf, n);
}
static int fd1 = -1;
void
startmc(void)
{
int p[2];
if(fd1 == -1)
fd1 = dup(1, -1);
if(pipe(p) < 0)
return;
switch(fork()){
case -1:
return;
default:
close(p[0]);
dup(p[1], 1);
if(p[1] != 1)
close(p[1]);
return;
case 0:
close(p[1]);
dup(p[0], 0);
if(p[0] != 0)
close(p[0]);
execl("/bin/mc", "mc", nil);
cat();
_exits(0);
}
}
void
stopmc(void)
{
close(1);
dup(fd1, 1);
waitpid();
}
void
printhelp(char *name)
{
int len;
Proto *pr, **l; Proto *pr, **l;
Mux *m; Mux *m;
Field *f; Field *f;
char fmt[40];
for(l = protos; *l != nil; l++){ if(name == nil){
pr = *l; print("protocols:\n");
if(pr->field != nil){ startmc();
print("%s's filter attr:\n", pr->name); for(l=protos; (pr=*l) != nil; l++)
for(f = pr->field; f->name != nil; f++) print(" %s\n", pr->name);
print("\t%s\t- %s\n", f->name, f->help); stopmc();
return;
} }
if(pr->mux != nil){
pr = findproto(name);
if(pr == nil){
print("unknown protocol %s\n", name);
return;
}
if(pr->field){
print("%s's filter attributes:\n", pr->name);
len = 0;
for(f=pr->field; f->name; f++)
if(len < strlen(f->name))
len = strlen(f->name);
startmc();
for(f=pr->field; f->name; f++)
print(" %-*s - %s\n", len, f->name, f->help);
stopmc();
}
if(pr->mux){
print("%s's subprotos:\n", pr->name); print("%s's subprotos:\n", pr->name);
startmc();
snprint(fmt, sizeof fmt, " %s %%s\n", pr->valfmt);
for(m=pr->mux; m->name != nil; m++) for(m=pr->mux; m->name != nil; m++)
print("\t%s\n", m->name); print(fmt, m->val, m->name);
} stopmc();
} }
} }

View file

@ -5,20 +5,6 @@
#include "dat.h" #include "dat.h"
#include "protos.h" #include "protos.h"
static void
p_compile(Filter *f)
{
sysfatal("unknown ninep field: %s", f->s);
}
static int
p_filter(Filter *f, Msg *m)
{
USED(f);
USED(m);
return 0;
}
static int static int
p_seprint(Msg *m) p_seprint(Msg *m)
{ {
@ -46,10 +32,11 @@ p_seprint(Msg *m)
Proto ninep = Proto ninep =
{ {
"ninep", "ninep",
p_compile, nil,
p_filter, nil,
p_seprint, p_seprint,
nil, nil,
nil, nil,
nil,
defaultframer, defaultframer,
}; };

View file

@ -90,11 +90,10 @@ struct Ospfhello
}; };
char* char*
seprintospfhello(char *p, char *e, void *a, int x) seprintospfhello(char *p, char *e, void *a)
{ {
Ospfhello *h = a; Ospfhello *h = a;
USED(x);
return seprint(p, e, "%s(mask %V interval %d opt %ux pri %ux deadt %d designated %V bdesignated %V)", return seprint(p, e, "%s(mask %V interval %d opt %ux pri %ux deadt %d designated %V bdesignated %V)",
ospftype[OSPFhello], ospftype[OSPFhello],
h->mask, NetS(h->interval), h->options, h->pri, h->mask, NetS(h->interval), h->options, h->pri,
@ -328,20 +327,6 @@ seprintospflsack(char *p, char *e, void *a, int len)
return seprint(p, e, ")"); return seprint(p, e, ")");
} }
static void
p_compile(Filter *f)
{
sysfatal("unknown ospf field: %s", f->s);
}
static int
p_filter(Filter *f, Msg *m)
{
USED(f);
USED(m);
return 0;
}
int int
p_seprint(Msg *m) p_seprint(Msg *m)
{ {
@ -369,7 +354,7 @@ p_seprint(Msg *m)
switch (ospf->type) { switch (ospf->type) {
case OSPFhello: case OSPFhello:
p = seprintospfhello(p, e, ospf->data, x); p = seprintospfhello(p, e, ospf->data);
break; break;
case OSPFdd: case OSPFdd:
p = seprintospfdatadesc(p, e, ospf->data, x); p = seprintospfdatadesc(p, e, ospf->data, x);
@ -395,10 +380,11 @@ Default:
Proto ospf = Proto ospf =
{ {
"ospf", "ospf",
p_compile, nil,
p_filter, nil,
p_seprint, p_seprint,
nil, nil,
nil, nil,
nil,
defaultframer, defaultframer,
}; };

View file

@ -569,6 +569,7 @@ Proto ppp =
p_filter, p_filter,
p_seprint, p_seprint,
p_mux, p_mux,
"%#.4lux",
nil, nil,
defaultframer, defaultframer,
}; };
@ -581,6 +582,7 @@ Proto ppp_ipcp =
p_seprintipcp, p_seprintipcp,
nil, nil,
nil, nil,
nil,
defaultframer, defaultframer,
}; };
@ -592,6 +594,7 @@ Proto ppp_lcp =
p_seprintlcp, p_seprintlcp,
nil, nil,
nil, nil,
nil,
defaultframer, defaultframer,
}; };
@ -603,6 +606,7 @@ Proto ppp_ccp =
p_seprintccp, p_seprintccp,
nil, nil,
nil, nil,
nil,
defaultframer, defaultframer,
}; };
@ -614,6 +618,7 @@ Proto ppp_chap =
p_seprintchap, p_seprintchap,
nil, nil,
nil, nil,
nil,
defaultframer, defaultframer,
}; };
@ -625,5 +630,6 @@ Proto ppp_comp =
p_seprintcomp, p_seprintcomp,
nil, nil,
nil, nil,
nil,
defaultframer, defaultframer,
}; };

View file

@ -155,6 +155,7 @@ Proto pppoe_disc =
p_filter, p_filter,
p_seprintdisc, p_seprintdisc,
p_mux, p_mux,
"%lud",
p_fields, p_fields,
defaultframer defaultframer
}; };
@ -166,6 +167,7 @@ Proto pppoe_sess =
p_filter, p_filter,
p_seprintsess, p_seprintsess,
p_mux, p_mux,
"%lud",
p_fields, p_fields,
defaultframer defaultframer
}; };

View file

@ -31,21 +31,6 @@ enum{
REPORTLEN = 24, REPORTLEN = 24,
}; };
static void
p_compile(Filter *f)
{
sysfatal("unknown rtcp field: %s", f->s);
}
static int
p_filter(Filter *f, Msg *m)
{
USED(f);
USED(m);
return 0;
}
static int static int
p_seprint(Msg *m) p_seprint(Msg *m)
{ {
@ -88,10 +73,11 @@ p_seprint(Msg *m)
Proto rtcp = { Proto rtcp = {
"rtcp", "rtcp",
p_compile, nil,
p_filter, nil,
p_seprint, p_seprint,
nil, nil,
nil, nil,
nil,
defaultframer, defaultframer,
}; };

View file

@ -17,21 +17,6 @@ enum{
RTPLEN = 12, // Minimum size of an RTP header RTPLEN = 12, // Minimum size of an RTP header
}; };
static void
p_compile(Filter *f)
{
sysfatal("unknown rtp field: %s", f->s);
}
static int
p_filter(Filter *f, Msg *m)
{
USED(f);
USED(m);
return 0;
}
static int static int
p_seprint(Msg *m) p_seprint(Msg *m)
{ {
@ -67,10 +52,11 @@ p_seprint(Msg *m)
Proto rtp = { Proto rtp = {
"rtp", "rtp",
p_compile, nil,
p_filter, nil,
p_seprint, p_seprint,
nil, nil,
nil, nil,
nil,
defaultframer, defaultframer,
}; };

View file

@ -216,6 +216,7 @@ Proto tcp =
p_filter, p_filter,
p_seprint, p_seprint,
p_mux, p_mux,
"%lud",
p_fields, p_fields,
defaultframer, defaultframer,
}; };

View file

@ -126,6 +126,7 @@ Proto udp =
p_filter, p_filter,
p_seprint, p_seprint,
p_mux, p_mux,
"%lud",
p_fields, p_fields,
defaultframer, defaultframer,
}; };