diff --git a/sbin/ipf/common/ipf_y.y b/sbin/ipf/common/ipf_y.y index 2013fe5b9452..861d0ccd9a13 100644 --- a/sbin/ipf/common/ipf_y.y +++ b/sbin/ipf/common/ipf_y.y @@ -1,2754 +1,2738 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ %{ #include "ipf.h" #include #include #include #ifdef IPFILTER_BPF # include #endif #include "netinet/ip_pool.h" #include "netinet/ip_htable.h" #include "netinet/ipl.h" #include "ipf_l.h" #define YYDEBUG 1 #define DOALL(x) for (fr = frc; fr != NULL; fr = fr->fr_next) { x } #define DOREM(x) for (; fr != NULL; fr = fr->fr_next) { x } extern void yyerror(char *); extern int yyparse(void); extern int yylex(void); extern int yydebug; extern FILE *yyin; extern int yylineNum; static int addname(frentry_t **, char *); static frentry_t *addrule(void); static frentry_t *allocfr(void); static void build_dstaddr_af(frentry_t *, void *); static void build_srcaddr_af(frentry_t *, void *); static void dobpf(int, char *); static void doipfexpr(char *); static void do_tuneint(char *, int); static void do_tunestr(char *, char *); static void fillgroup(frentry_t *); static int lookuphost(char *, i6addr_t *); static u_int makehash(struct alist_s *); static int makepool(struct alist_s *); static struct alist_s *newalist(struct alist_s *); static void newrule(void); static void resetaddr(void); static void setgroup(frentry_t **, char *); static void setgrhead(frentry_t **, char *); static void seticmphead(frentry_t **, char *); static void setifname(frentry_t **, int, char *); static void setipftype(void); static void setsyslog(void); static void unsetsyslog(void); frentry_t *fr = NULL, *frc = NULL, *frtop = NULL, *frold = NULL; static int ifpflag = 0; static int nowith = 0; static int dynamic = -1; static int pooled = 0; static int hashed = 0; static int nrules = 0; static int newlist = 0; static int added = 0; static int ipffd = -1; static int *yycont = NULL; static ioctlfunc_t ipfioctls[IPL_LOGSIZE]; static addfunc_t ipfaddfunc = NULL; %} %union { char *str; u_32_t num; frentry_t fr; frtuc_t *frt; struct alist_s *alist; u_short port; struct in_addr ip4; struct { u_short p1; u_short p2; int pc; } pc; struct ipp_s { int type; int ifpos; int f; int v; int lif; union i6addr a; union i6addr m; char *name; } ipp; struct { i6addr_t adr; int f; } adr; i6addr_t ip6; struct { char *if1; char *if2; } ifs; char gname[FR_GROUPLEN]; }; %type portnum %type facility priority icmpcode seclevel secname icmptype %type opt compare range opttype flagset optlist ipv6hdrlist ipv6hdr %type portc porteq ipmask maskopts %type ipv4 ipv4_16 ipv4_24 %type hostname %type addr ipaddr %type servicename name interfacename groupname %type portrange portcomp %type addrlist poollist %type onname %token YY_NUMBER YY_HEX %token YY_STR %token YY_COMMENT %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT %token YY_RANGE_OUT YY_RANGE_IN %token YY_IPV6 %token IPFY_SET %token IPFY_PASS IPFY_BLOCK IPFY_COUNT IPFY_CALL IPFY_NOMATCH %token IPFY_RETICMP IPFY_RETRST IPFY_RETICMPASDST %token IPFY_IN IPFY_OUT %token IPFY_QUICK IPFY_ON IPFY_OUTVIA IPFY_INVIA %token IPFY_DUPTO IPFY_TO IPFY_FROUTE IPFY_REPLY_TO IPFY_ROUTETO %token IPFY_TOS IPFY_TTL IPFY_PROTO IPFY_INET IPFY_INET6 %token IPFY_HEAD IPFY_GROUP %token IPFY_AUTH IPFY_PREAUTH %token IPFY_LOG IPFY_BODY IPFY_FIRST IPFY_LEVEL IPFY_ORBLOCK IPFY_L5AS %token IPFY_LOGTAG IPFY_MATCHTAG IPFY_SETTAG IPFY_SKIP IPFY_DECAPS %token IPFY_FROM IPFY_ALL IPFY_ANY IPFY_BPFV4 IPFY_BPFV6 IPFY_POOL IPFY_HASH %token IPFY_IPFEXPR IPFY_PPS IPFY_FAMILY IPFY_DSTLIST %token IPFY_ESP IPFY_AH %token IPFY_WITH IPFY_AND IPFY_NOT IPFY_NO IPFY_OPT %token IPFY_TCPUDP IPFY_TCP IPFY_UDP %token IPFY_FLAGS IPFY_MULTICAST %token IPFY_MASK IPFY_BROADCAST IPFY_NETWORK IPFY_NETMASKED IPFY_PEER %token IPFY_RPC IPFY_PORT %token IPFY_NOW IPFY_COMMENT IPFY_RULETTL %token IPFY_ICMP IPFY_ICMPTYPE IPFY_ICMPCODE %token IPFY_IPOPTS IPFY_SHORT IPFY_NAT IPFY_BADSRC IPFY_LOWTTL IPFY_FRAG %token IPFY_MBCAST IPFY_BAD IPFY_BADNAT IPFY_OOW IPFY_NEWISN IPFY_NOICMPERR %token IPFY_KEEP IPFY_STATE IPFY_FRAGS IPFY_LIMIT IPFY_STRICT IPFY_AGE %token IPFY_SYNC IPFY_FRAGBODY IPFY_ICMPHEAD IPFY_NOLOG IPFY_LOOSE %token IPFY_MAX_SRCS IPFY_MAX_PER_SRC %token IPFY_IPOPT_NOP IPFY_IPOPT_RR IPFY_IPOPT_ZSU IPFY_IPOPT_MTUP %token IPFY_IPOPT_MTUR IPFY_IPOPT_ENCODE IPFY_IPOPT_TS IPFY_IPOPT_TR %token IPFY_IPOPT_SEC IPFY_IPOPT_LSRR IPFY_IPOPT_ESEC IPFY_IPOPT_CIPSO %token IPFY_IPOPT_SATID IPFY_IPOPT_SSRR IPFY_IPOPT_ADDEXT IPFY_IPOPT_VISA %token IPFY_IPOPT_IMITD IPFY_IPOPT_EIP IPFY_IPOPT_FINN IPFY_IPOPT_DPS %token IPFY_IPOPT_SDB IPFY_IPOPT_NSAPA IPFY_IPOPT_RTRALRT IPFY_IPOPT_UMP %token IPFY_SECCLASS IPFY_SEC_UNC IPFY_SEC_CONF IPFY_SEC_RSV1 IPFY_SEC_RSV2 %token IPFY_SEC_RSV4 IPFY_SEC_SEC IPFY_SEC_TS IPFY_SEC_RSV3 IPFY_DOI %token IPFY_V6HDRS IPFY_IPV6OPT IPFY_IPV6OPT_DSTOPTS IPFY_IPV6OPT_HOPOPTS %token IPFY_IPV6OPT_IPV6 IPFY_IPV6OPT_NONE IPFY_IPV6OPT_ROUTING IPFY_V6HDR %token IPFY_IPV6OPT_MOBILITY IPFY_IPV6OPT_ESP IPFY_IPV6OPT_FRAG %token IPFY_ICMPT_UNR IPFY_ICMPT_ECHO IPFY_ICMPT_ECHOR IPFY_ICMPT_SQUENCH %token IPFY_ICMPT_REDIR IPFY_ICMPT_TIMEX IPFY_ICMPT_PARAMP IPFY_ICMPT_TIMEST %token IPFY_ICMPT_TIMESTREP IPFY_ICMPT_INFOREQ IPFY_ICMPT_INFOREP %token IPFY_ICMPT_MASKREQ IPFY_ICMPT_MASKREP IPFY_ICMPT_ROUTERAD %token IPFY_ICMPT_ROUTERSOL %token IPFY_ICMPC_NETUNR IPFY_ICMPC_HSTUNR IPFY_ICMPC_PROUNR IPFY_ICMPC_PORUNR %token IPFY_ICMPC_NEEDF IPFY_ICMPC_SRCFAIL IPFY_ICMPC_NETUNK IPFY_ICMPC_HSTUNK %token IPFY_ICMPC_ISOLATE IPFY_ICMPC_NETPRO IPFY_ICMPC_HSTPRO %token IPFY_ICMPC_NETTOS IPFY_ICMPC_HSTTOS IPFY_ICMPC_FLTPRO IPFY_ICMPC_HSTPRE %token IPFY_ICMPC_CUTPRE %token IPFY_FAC_KERN IPFY_FAC_USER IPFY_FAC_MAIL IPFY_FAC_DAEMON IPFY_FAC_AUTH %token IPFY_FAC_SYSLOG IPFY_FAC_LPR IPFY_FAC_NEWS IPFY_FAC_UUCP IPFY_FAC_CRON %token IPFY_FAC_LOCAL0 IPFY_FAC_LOCAL1 IPFY_FAC_LOCAL2 IPFY_FAC_LOCAL3 %token IPFY_FAC_LOCAL4 IPFY_FAC_LOCAL5 IPFY_FAC_LOCAL6 IPFY_FAC_LOCAL7 %token IPFY_FAC_SECURITY IPFY_FAC_FTP IPFY_FAC_AUTHPRIV IPFY_FAC_AUDIT %token IPFY_FAC_LFMT IPFY_FAC_CONSOLE %token IPFY_PRI_EMERG IPFY_PRI_ALERT IPFY_PRI_CRIT IPFY_PRI_ERR IPFY_PRI_WARN %token IPFY_PRI_NOTICE IPFY_PRI_INFO IPFY_PRI_DEBUG %% file: settings rules | rules ; settings: YY_COMMENT | setting | settings setting ; rules: line | assign | rules line | rules assign ; setting: IPFY_SET YY_STR YY_NUMBER ';' { do_tuneint($2, $3); } | IPFY_SET YY_STR YY_HEX ';' { do_tuneint($2, $3); } | IPFY_SET YY_STR YY_STR ';' { do_tunestr($2, $3); } ; line: rule { while ((fr = frtop) != NULL) { frtop = fr->fr_next; fr->fr_next = NULL; if ((fr->fr_type == FR_T_IPF) && (fr->fr_ip.fi_v == 0)) fr->fr_mip.fi_v = 0; /* XXX validate ? */ (*ipfaddfunc)(ipffd, ipfioctls[IPL_LOGIPF], fr); fr->fr_next = frold; frold = fr; } resetlexer(); } | YY_COMMENT ; xx: { newrule(); } ; assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); resetlexer(); free($1); free($3); yyvarnext = 0; } ; assigning: '=' { yyvarnext = 1; } ; rule: inrule eol | outrule eol ; eol: | ';' ; inrule: rulehead markin inopts rulemain ruletail intag ruletail2 ; outrule: rulehead markout outopts rulemain ruletail outtag ruletail2 ; rulehead: xx collection action | xx insert collection action ; markin: IPFY_IN { fr->fr_flags |= FR_INQUE; } ; markout: IPFY_OUT { fr->fr_flags |= FR_OUTQUE; } ; rulemain: ipfrule | bpfrule | exprrule ; ipfrule: family tos ttl proto ip ; family: | IPFY_FAMILY IPFY_INET { if (use_inet6 == 1) { YYERROR; } else { frc->fr_family = AF_INET; } } | IPFY_INET { if (use_inet6 == 1) { YYERROR; } else { frc->fr_family = AF_INET; } } | IPFY_FAMILY IPFY_INET6 { if (use_inet6 == -1) { YYERROR; } else { frc->fr_family = AF_INET6; } } | IPFY_INET6 { if (use_inet6 == -1) { YYERROR; } else { frc->fr_family = AF_INET6; } } ; bpfrule: IPFY_BPFV4 '{' YY_STR '}' { dobpf(4, $3); free($3); } | IPFY_BPFV6 '{' YY_STR '}' { dobpf(6, $3); free($3); } ; exprrule: IPFY_IPFEXPR '{' YY_STR '}' { doipfexpr($3); } ; ruletail: with keep head group ; ruletail2: pps age new rulettl comment ; intag: settagin matchtagin ; outtag: settagout matchtagout ; insert: '@' YY_NUMBER { fr->fr_hits = (U_QUAD_T)$2 + 1; } ; collection: | YY_NUMBER { fr->fr_collect = $1; } ; action: block | IPFY_PASS { fr->fr_flags |= FR_PASS; } | IPFY_NOMATCH { fr->fr_flags |= FR_NOMATCH; } | log | IPFY_COUNT { fr->fr_flags |= FR_ACCOUNT; } | decaps { fr->fr_flags |= FR_DECAPSULATE; } | auth | IPFY_SKIP YY_NUMBER { fr->fr_flags |= FR_SKIP; fr->fr_arg = $2; } | IPFY_CALL func | IPFY_CALL IPFY_NOW func { fr->fr_flags |= FR_CALLNOW; } ; block: blocked | blocked blockreturn ; blocked: IPFY_BLOCK { fr->fr_flags = FR_BLOCK; } ; blockreturn: IPFY_RETICMP { fr->fr_flags |= FR_RETICMP; } | IPFY_RETICMP returncode { fr->fr_flags |= FR_RETICMP; } | IPFY_RETICMPASDST { fr->fr_flags |= FR_FAKEICMP; } | IPFY_RETICMPASDST returncode { fr->fr_flags |= FR_FAKEICMP; } | IPFY_RETRST { fr->fr_flags |= FR_RETRST; } ; decaps: IPFY_DECAPS | IPFY_DECAPS IPFY_L5AS '(' YY_STR ')' { fr->fr_icode = atoi($4); } ; log: IPFY_LOG { fr->fr_flags |= FR_LOG; } | IPFY_LOG logoptions { fr->fr_flags |= FR_LOG; } ; auth: IPFY_AUTH { fr->fr_flags |= FR_AUTH; } | IPFY_AUTH blockreturn { fr->fr_flags |= FR_AUTH;} | IPFY_PREAUTH { fr->fr_flags |= FR_PREAUTH; } ; func: YY_STR '/' YY_NUMBER { fr->fr_func = nametokva($1, ipfioctls[IPL_LOGIPF]); fr->fr_arg = $3; free($1); } ; inopts: | inopts inopt ; inopt: logopt | quick | on | dup | froute | proute | replyto ; outopts: | outopts outopt ; outopt: logopt | quick | on | dup | proute | froute | replyto ; tos: | settos YY_NUMBER { DOALL(fr->fr_tos = $2; fr->fr_mtos = 0xff;) } | settos YY_HEX { DOALL(fr->fr_tos = $2; fr->fr_mtos = 0xff;) } | settos lstart toslist lend ; settos: IPFY_TOS { setipftype(); } ; toslist: YY_NUMBER { DOALL(fr->fr_tos = $1; fr->fr_mtos = 0xff;) } | YY_HEX { DOREM(fr->fr_tos = $1; fr->fr_mtos = 0xff;) } | toslist lmore YY_NUMBER { DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) } | toslist lmore YY_HEX { DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) } ; ttl: | setttl YY_NUMBER { DOALL(fr->fr_ttl = $2; fr->fr_mttl = 0xff;) } | setttl lstart ttllist lend ; lstart: '{' { newlist = 1; fr = frc; added = 0; } ; lend: '}' { nrules += added; } ; lmore: lanother { if (newlist == 1) { newlist = 0; } fr = addrule(); if (yycont != NULL) *yycont = 1; } ; lanother: | ',' ; setttl: IPFY_TTL { setipftype(); } ; ttllist: YY_NUMBER { DOREM(fr->fr_ttl = $1; fr->fr_mttl = 0xff;) } | ttllist lmore YY_NUMBER { DOREM(fr->fr_ttl = $3; fr->fr_mttl = 0xff;) } ; proto: | protox protocol { yyresetdict(); } ; protox: IPFY_PROTO { setipftype(); fr = frc; yysetdict(NULL); } ; ip: srcdst flags icmp ; group: | IPFY_GROUP groupname { DOALL(setgroup(&fr, $2); \ fillgroup(fr);); free($2); } ; head: | IPFY_HEAD groupname { DOALL(setgrhead(&fr, $2);); free($2); } ; groupname: YY_STR { $$ = $1; if (strlen($$) >= FR_GROUPLEN) $$[FR_GROUPLEN - 1] = '\0'; } | YY_NUMBER { $$ = malloc(16); sprintf($$, "%d", $1); } ; settagin: | IPFY_SETTAG '(' taginlist ')' ; taginlist: taginspec | taginlist ',' taginspec ; taginspec: logtag ; nattag: IPFY_NAT '=' YY_STR { DOALL(strncpy(fr->fr_nattag.ipt_tag,\ $3, IPFTAG_LEN);); free($3); } | IPFY_NAT '=' YY_NUMBER { DOALL(sprintf(fr->fr_nattag.ipt_tag,\ "%d", $3 & 0xffffffff);) } ; logtag: IPFY_LOG '=' YY_NUMBER { DOALL(fr->fr_logtag = $3;) } ; settagout: | IPFY_SETTAG '(' tagoutlist ')' ; tagoutlist: tagoutspec | tagoutlist ',' tagoutspec ; tagoutspec: logtag | nattag ; matchtagin: | IPFY_MATCHTAG '(' tagoutlist ')' ; matchtagout: | IPFY_MATCHTAG '(' taginlist ')' ; pps: | IPFY_PPS YY_NUMBER { DOALL(fr->fr_pps = $2;) } ; new: | savegroup file restoregroup ; rulettl: | IPFY_RULETTL YY_NUMBER { DOALL(fr->fr_die = $2;) } ; comment: | IPFY_COMMENT YY_STR { DOALL(fr->fr_comment = addname(&fr, \ $2);) } ; savegroup: '{' ; restoregroup: '}' ; logopt: log ; quick: IPFY_QUICK { fr->fr_flags |= FR_QUICK; } ; on: IPFY_ON onname { setifname(&fr, 0, $2.if1); free($2.if1); if ($2.if2 != NULL) { setifname(&fr, 1, $2.if2); free($2.if2); } } | IPFY_ON lstart onlist lend | IPFY_ON onname IPFY_INVIA vianame { setifname(&fr, 0, $2.if1); free($2.if1); if ($2.if2 != NULL) { setifname(&fr, 1, $2.if2); free($2.if2); } } | IPFY_ON onname IPFY_OUTVIA vianame { setifname(&fr, 0, $2.if1); free($2.if1); if ($2.if2 != NULL) { setifname(&fr, 1, $2.if2); free($2.if2); } } ; onlist: onname { DOREM(setifname(&fr, 0, $1.if1); \ if ($1.if2 != NULL) \ setifname(&fr, 1, $1.if2); \ ) free($1.if1); if ($1.if2 != NULL) free($1.if2); } | onlist lmore onname { DOREM(setifname(&fr, 0, $3.if1); \ if ($3.if2 != NULL) \ setifname(&fr, 1, $3.if2); \ ) free($3.if1); if ($3.if2 != NULL) free($3.if2); } ; onname: interfacename { $$.if1 = $1; $$.if2 = NULL; } | interfacename ',' interfacename { $$.if1 = $1; $$.if2 = $3; } ; vianame: name { setifname(&fr, 2, $1); free($1); } | name ',' name { setifname(&fr, 2, $1); free($1); setifname(&fr, 3, $3); free($3); } ; dup: IPFY_DUPTO name { int idx = addname(&fr, $2); fr->fr_dif.fd_name = idx; free($2); } | IPFY_DUPTO IPFY_DSTLIST '/' name { int idx = addname(&fr, $4); fr->fr_dif.fd_name = idx; fr->fr_dif.fd_type = FRD_DSTLIST; free($4); } | IPFY_DUPTO name duptoseparator hostname { int idx = addname(&fr, $2); fr->fr_dif.fd_name = idx; fr->fr_dif.fd_ptr = (void *)-1; fr->fr_dif.fd_ip6 = $4.adr; if (fr->fr_family == AF_UNSPEC && $4.f != AF_UNSPEC) fr->fr_family = $4.f; yyexpectaddr = 0; free($2); } ; duptoseparator: ':' { yyexpectaddr = 1; yycont = &yyexpectaddr; resetaddr(); } ; froute: IPFY_FROUTE { fr->fr_flags |= FR_FASTROUTE; } ; proute: routeto name { int idx = addname(&fr, $2); fr->fr_tif.fd_name = idx; free($2); } | routeto IPFY_DSTLIST '/' name { int idx = addname(&fr, $4); fr->fr_tif.fd_name = idx; fr->fr_tif.fd_type = FRD_DSTLIST; free($4); } | routeto name duptoseparator hostname { int idx = addname(&fr, $2); fr->fr_tif.fd_name = idx; fr->fr_tif.fd_ptr = (void *)-1; fr->fr_tif.fd_ip6 = $4.adr; if (fr->fr_family == AF_UNSPEC && $4.f != AF_UNSPEC) fr->fr_family = $4.f; yyexpectaddr = 0; free($2); } ; routeto: IPFY_TO | IPFY_ROUTETO ; replyto: IPFY_REPLY_TO name { int idx = addname(&fr, $2); fr->fr_rif.fd_name = idx; free($2); } | IPFY_REPLY_TO IPFY_DSTLIST '/' name { fr->fr_rif.fd_name = addname(&fr, $4); fr->fr_rif.fd_type = FRD_DSTLIST; free($4); } | IPFY_REPLY_TO name duptoseparator hostname { int idx = addname(&fr, $2); fr->fr_rif.fd_name = idx; fr->fr_rif.fd_ptr = (void *)-1; fr->fr_rif.fd_ip6 = $4.adr; if (fr->fr_family == AF_UNSPEC && $4.f != AF_UNSPEC) fr->fr_family = $4.f; free($2); } ; logoptions: logoption | logoptions logoption ; logoption: IPFY_BODY { fr->fr_flags |= FR_LOGBODY; } | IPFY_FIRST { fr->fr_flags |= FR_LOGFIRST; } | IPFY_ORBLOCK { fr->fr_flags |= FR_LOGORBLOCK; } | level loglevel { unsetsyslog(); } ; returncode: starticmpcode icmpcode ')' { fr->fr_icode = $2; yyresetdict(); } ; starticmpcode: '(' { yysetdict(icmpcodewords); } ; srcdst: | IPFY_ALL | fromto ; protocol: YY_NUMBER { DOALL(fr->fr_proto = $1; \ fr->fr_mproto = 0xff;) } | YY_STR { if (!strcmp($1, "tcp-udp")) { DOALL(fr->fr_flx |= FI_TCPUDP; \ fr->fr_mflx |= FI_TCPUDP;) } else { int p = getproto($1); if (p == -1) yyerror("protocol unknown"); DOALL(fr->fr_proto = p; \ fr->fr_mproto = 0xff;) } free($1); } | YY_STR nextstring YY_STR { if (!strcmp($1, "tcp") && !strcmp($3, "udp")) { DOREM(fr->fr_flx |= FI_TCPUDP; \ fr->fr_mflx |= FI_TCPUDP;) } else { YYERROR; } free($1); free($3); } ; nextstring: '/' { yysetdict(NULL); } ; fromto: from srcobject to dstobject { yyexpectaddr = 0; yycont = NULL; } | to dstobject { yyexpectaddr = 0; yycont = NULL; } | from srcobject { yyexpectaddr = 0; yycont = NULL; } ; from: IPFY_FROM { setipftype(); if (fr == NULL) fr = frc; yyexpectaddr = 1; if (yydebug) printf("set yyexpectaddr\n"); yycont = &yyexpectaddr; yysetdict(addrwords); resetaddr(); } ; to: IPFY_TO { if (fr == NULL) fr = frc; yyexpectaddr = 1; if (yydebug) printf("set yyexpectaddr\n"); yycont = &yyexpectaddr; yysetdict(addrwords); resetaddr(); } ; with: | andwith withlist ; andwith: IPFY_WITH { nowith = 0; setipftype(); } | IPFY_AND { nowith = 0; setipftype(); } ; flags: | startflags flagset { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) } | startflags flagset '/' flagset { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) } | startflags '/' flagset { DOALL(fr->fr_tcpf = 0; fr->fr_tcpfm = $3;) } | startflags YY_NUMBER { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) } | startflags '/' YY_NUMBER { DOALL(fr->fr_tcpf = 0; fr->fr_tcpfm = $3;) } | startflags YY_NUMBER '/' YY_NUMBER { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) } | startflags flagset '/' YY_NUMBER { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) } | startflags YY_NUMBER '/' flagset { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) } ; startflags: IPFY_FLAGS { if (frc->fr_type != FR_T_IPF) yyerror("flags with non-ipf type rule"); if (frc->fr_proto != IPPROTO_TCP) yyerror("flags with non-TCP rule"); } ; flagset: YY_STR { $$ = tcpflags($1); free($1); } | YY_HEX { $$ = $1; } ; srcobject: { yyresetdict(); } fromport | srcaddr srcport | '!' srcaddr srcport { DOALL(fr->fr_flags |= FR_NOTSRCIP;) } ; srcaddr: addr { build_srcaddr_af(fr, &$1); } | lstart srcaddrlist lend ; srcaddrlist: addr { build_srcaddr_af(fr, &$1); } | srcaddrlist lmore addr { build_srcaddr_af(fr, &$3); } ; srcport: | portcomp { DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1;) } | portrange { DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1; \ fr->fr_stop = $1.p2;) } | porteq lstart srcportlist lend { yyresetdict(); } ; fromport: portcomp { DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1;) } | portrange { DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1; \ fr->fr_stop = $1.p2;) } | porteq lstart srcportlist lend { yyresetdict(); } ; srcportlist: portnum { DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $1;) } | portnum ':' portnum { DOREM(fr->fr_scmp = FR_INCRANGE; fr->fr_sport = $1; \ fr->fr_stop = $3;) } | portnum YY_RANGE_IN portnum { DOREM(fr->fr_scmp = FR_INRANGE; fr->fr_sport = $1; \ fr->fr_stop = $3;) } | srcportlist lmore portnum { DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $3;) } | srcportlist lmore portnum ':' portnum { DOREM(fr->fr_scmp = FR_INCRANGE; fr->fr_sport = $3; \ fr->fr_stop = $5;) } | srcportlist lmore portnum YY_RANGE_IN portnum { DOREM(fr->fr_scmp = FR_INRANGE; fr->fr_sport = $3; \ fr->fr_stop = $5;) } ; dstobject: { yyresetdict(); } toport | dstaddr dstport | '!' dstaddr dstport { DOALL(fr->fr_flags |= FR_NOTDSTIP;) } ; dstaddr: addr { if (($1.f != AF_UNSPEC) && (frc->fr_family != AF_UNSPEC) && ($1.f != frc->fr_family)) yyerror("1.src/dst address family mismatch"); build_dstaddr_af(fr, &$1); } | lstart dstaddrlist lend ; dstaddrlist: addr { if (($1.f != AF_UNSPEC) && (frc->fr_family != AF_UNSPEC) && ($1.f != frc->fr_family)) yyerror("2.src/dst address family mismatch"); build_dstaddr_af(fr, &$1); } | dstaddrlist lmore addr { if (($3.f != AF_UNSPEC) && (frc->fr_family != AF_UNSPEC) && ($3.f != frc->fr_family)) yyerror("3.src/dst address family mismatch"); build_dstaddr_af(fr, &$3); } ; dstport: | portcomp { DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1;) } | portrange { DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1; \ fr->fr_dtop = $1.p2;) } | porteq lstart dstportlist lend { yyresetdict(); } ; toport: portcomp { DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1;) } | portrange { DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1; \ fr->fr_dtop = $1.p2;) } | porteq lstart dstportlist lend { yyresetdict(); } ; dstportlist: portnum { DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $1;) } | portnum ':' portnum { DOREM(fr->fr_dcmp = FR_INCRANGE; fr->fr_dport = $1; \ fr->fr_dtop = $3;) } | portnum YY_RANGE_IN portnum { DOREM(fr->fr_dcmp = FR_INRANGE; fr->fr_dport = $1; \ fr->fr_dtop = $3;) } | dstportlist lmore portnum { DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $3;) } | dstportlist lmore portnum ':' portnum { DOREM(fr->fr_dcmp = FR_INCRANGE; fr->fr_dport = $3; \ fr->fr_dtop = $5;) } | dstportlist lmore portnum YY_RANGE_IN portnum { DOREM(fr->fr_dcmp = FR_INRANGE; fr->fr_dport = $3; \ fr->fr_dtop = $5;) } ; addr: pool '/' YY_NUMBER { pooled = 1; yyexpectaddr = 0; $$.type = FRI_LOOKUP; $$.v = 0; $$.ifpos = -1; $$.f = AF_UNSPEC; $$.a.iplookuptype = IPLT_POOL; $$.a.iplookupsubtype = 0; $$.a.iplookupnum = $3; } | pool '/' YY_STR { pooled = 1; $$.ifpos = -1; $$.f = AF_UNSPEC; $$.type = FRI_LOOKUP; $$.a.iplookuptype = IPLT_POOL; $$.a.iplookupsubtype = 1; $$.a.iplookupname = addname(&fr, $3); } | pool '=' '(' { yyexpectaddr = 1; pooled = 1; } poollist ')' { yyexpectaddr = 0; $$.v = 0; $$.ifpos = -1; $$.f = AF_UNSPEC; $$.type = FRI_LOOKUP; $$.a.iplookuptype = IPLT_POOL; $$.a.iplookupsubtype = 0; $$.a.iplookupnum = makepool($5); } | hash '/' YY_NUMBER { hashed = 1; yyexpectaddr = 0; $$.v = 0; $$.ifpos = -1; $$.f = AF_UNSPEC; $$.type = FRI_LOOKUP; $$.a.iplookuptype = IPLT_HASH; $$.a.iplookupsubtype = 0; $$.a.iplookupnum = $3; } | hash '/' YY_STR { hashed = 1; $$.type = FRI_LOOKUP; $$.v = 0; $$.ifpos = -1; $$.f = AF_UNSPEC; $$.a.iplookuptype = IPLT_HASH; $$.a.iplookupsubtype = 1; $$.a.iplookupname = addname(&fr, $3); } | hash '=' '(' { hashed = 1; yyexpectaddr = 1; } addrlist ')' { yyexpectaddr = 0; $$.v = 0; $$.ifpos = -1; $$.f = AF_UNSPEC; $$.type = FRI_LOOKUP; $$.a.iplookuptype = IPLT_HASH; $$.a.iplookupsubtype = 0; $$.a.iplookupnum = makehash($5); } | ipaddr { $$ = $1; yyexpectaddr = 0; } ; ipaddr: IPFY_ANY { memset(&($$), 0, sizeof($$)); $$.type = FRI_NORMAL; $$.ifpos = -1; yyexpectaddr = 0; } | hostname { memset(&($$), 0, sizeof($$)); $$.a = $1.adr; $$.f = $1.f; if ($1.f == AF_INET6) fill6bits(128, $$.m.i6); else if ($1.f == AF_INET) fill6bits(32, $$.m.i6); $$.v = ftov($1.f); $$.ifpos = dynamic; $$.type = FRI_NORMAL; } | hostname { yyresetdict(); } maskspace { yysetdict(maskwords); yyexpectaddr = 2; } ipmask { memset(&($$), 0, sizeof($$)); ntomask($1.f, $5, $$.m.i6); $$.a = $1.adr; $$.a.i6[0] &= $$.m.i6[0]; $$.a.i6[1] &= $$.m.i6[1]; $$.a.i6[2] &= $$.m.i6[2]; $$.a.i6[3] &= $$.m.i6[3]; $$.f = $1.f; $$.v = ftov($1.f); $$.type = ifpflag; $$.ifpos = dynamic; if (ifpflag != 0 && $$.v == 0) { if (frc->fr_family == AF_INET6){ $$.v = 6; $$.f = AF_INET6; } else { $$.v = 4; $$.f = AF_INET; } } yyresetdict(); yyexpectaddr = 0; } | '(' YY_STR ')' { memset(&($$), 0, sizeof($$)); $$.type = FRI_DYNAMIC; ifpflag = FRI_DYNAMIC; $$.ifpos = addname(&fr, $2); $$.lif = 0; } | '(' YY_STR ')' '/' { ifpflag = FRI_DYNAMIC; yysetdict(maskwords); } maskopts { memset(&($$), 0, sizeof($$)); $$.type = ifpflag; $$.ifpos = addname(&fr, $2); $$.lif = 0; if (frc->fr_family == AF_UNSPEC) frc->fr_family = AF_INET; if (ifpflag == FRI_DYNAMIC) { ntomask(frc->fr_family, $6, $$.m.i6); } yyresetdict(); yyexpectaddr = 0; } | '(' YY_STR ':' YY_NUMBER ')' '/' { ifpflag = FRI_DYNAMIC; yysetdict(maskwords); } maskopts { memset(&($$), 0, sizeof($$)); $$.type = ifpflag; $$.ifpos = addname(&fr, $2); $$.lif = $4; if (frc->fr_family == AF_UNSPEC) frc->fr_family = AF_INET; if (ifpflag == FRI_DYNAMIC) { ntomask(frc->fr_family, $8, $$.m.i6); } yyresetdict(); yyexpectaddr = 0; } ; maskspace: '/' | IPFY_MASK ; ipmask: ipv4 { $$ = count4bits($1.s_addr); } | YY_HEX { $$ = count4bits(htonl($1)); } | YY_NUMBER { $$ = $1; } | YY_IPV6 { $$ = count6bits($1.i6); } | maskopts { $$ = $1; } ; maskopts: IPFY_BROADCAST { if (ifpflag == FRI_DYNAMIC) { ifpflag = FRI_BROADCAST; } else { YYERROR; } $$ = 0; } | IPFY_NETWORK { if (ifpflag == FRI_DYNAMIC) { ifpflag = FRI_NETWORK; } else { YYERROR; } $$ = 0; } | IPFY_NETMASKED { if (ifpflag == FRI_DYNAMIC) { ifpflag = FRI_NETMASKED; } else { YYERROR; } $$ = 0; } | IPFY_PEER { if (ifpflag == FRI_DYNAMIC) { ifpflag = FRI_PEERADDR; } else { YYERROR; } $$ = 0; } | YY_NUMBER { $$ = $1; } ; hostname: ipv4 { memset(&($$), 0, sizeof($$)); $$.adr.in4 = $1; if (frc->fr_family == AF_INET6) YYERROR; $$.f = AF_INET; yyexpectaddr = 2; } | YY_NUMBER { memset(&($$), 0, sizeof($$)); if (frc->fr_family == AF_INET6) YYERROR; $$.adr.in4_addr = $1; $$.f = AF_INET; yyexpectaddr = 2; } | YY_HEX { memset(&($$), 0, sizeof($$)); if (frc->fr_family == AF_INET6) YYERROR; $$.adr.in4_addr = $1; $$.f = AF_INET; yyexpectaddr = 2; } | YY_STR { memset(&($$), 0, sizeof($$)); if (lookuphost($1, &$$.adr) == 0) $$.f = AF_INET; free($1); yyexpectaddr = 2; } | YY_IPV6 { memset(&($$), 0, sizeof($$)); if (frc->fr_family == AF_INET) YYERROR; $$.adr = $1; $$.f = AF_INET6; yyexpectaddr = 2; } ; addrlist: ipaddr { $$ = newalist(NULL); $$->al_family = $1.f; $$->al_i6addr = $1.a; $$->al_i6mask = $1.m; } | ipaddr ',' { yyexpectaddr = 1; } addrlist { $$ = newalist($4); $$->al_family = $1.f; $$->al_i6addr = $1.a; $$->al_i6mask = $1.m; } ; pool: IPFY_POOL { yyexpectaddr = 0; yycont = NULL; yyresetdict(); } ; hash: IPFY_HASH { yyexpectaddr = 0; yycont = NULL; yyresetdict(); } ; poollist: ipaddr { $$ = newalist(NULL); $$->al_family = $1.f; $$->al_i6addr = $1.a; $$->al_i6mask = $1.m; } | '!' ipaddr { $$ = newalist(NULL); $$->al_not = 1; $$->al_family = $2.f; $$->al_i6addr = $2.a; $$->al_i6mask = $2.m; } | poollist ',' ipaddr { $$ = newalist($1); $$->al_family = $3.f; $$->al_i6addr = $3.a; $$->al_i6mask = $3.m; } | poollist ',' '!' ipaddr { $$ = newalist($1); $$->al_not = 1; $$->al_family = $4.f; $$->al_i6addr = $4.a; $$->al_i6mask = $4.m; } ; port: IPFY_PORT { yyexpectaddr = 0; yycont = NULL; if (frc->fr_proto != 0 && frc->fr_proto != IPPROTO_UDP && frc->fr_proto != IPPROTO_TCP) yyerror("port use incorrect"); } ; portc: port compare { $$ = $2; yysetdict(NULL); } | porteq { $$ = $1; } ; porteq: port '=' { $$ = FR_EQUAL; yysetdict(NULL); } ; portr: IPFY_PORT { yyexpectaddr = 0; yycont = NULL; yysetdict(NULL); } ; portcomp: portc portnum { $$.pc = $1; $$.p1 = $2; yyresetdict(); } ; portrange: portr portnum range portnum { $$.p1 = $2; $$.pc = $3; $$.p2 = $4; yyresetdict(); } ; icmp: | itype icode ; itype: seticmptype icmptype { DOALL(fr->fr_icmp = htons($2 << 8); fr->fr_icmpm = htons(0xff00);); yyresetdict(); } | seticmptype lstart typelist lend { yyresetdict(); } ; seticmptype: IPFY_ICMPTYPE { if (frc->fr_family == AF_UNSPEC) frc->fr_family = AF_INET; if (frc->fr_family == AF_INET && frc->fr_type == FR_T_IPF && frc->fr_proto != IPPROTO_ICMP) { yyerror("proto not icmp"); } if (frc->fr_family == AF_INET6 && frc->fr_type == FR_T_IPF && frc->fr_proto != IPPROTO_ICMPV6) { yyerror("proto not ipv6-icmp"); } setipftype(); DOALL(if (fr->fr_family == AF_INET) { \ fr->fr_ip.fi_v = 4; \ fr->fr_mip.fi_v = 0xf; \ } if (fr->fr_family == AF_INET6) { \ fr->fr_ip.fi_v = 6; \ fr->fr_mip.fi_v = 0xf; \ } ) yysetdict(NULL); } ; icode: | seticmpcode icmpcode { DOALL(fr->fr_icmp |= htons($2); fr->fr_icmpm |= htons(0xff);); yyresetdict(); } | seticmpcode lstart codelist lend { yyresetdict(); } ; seticmpcode: IPFY_ICMPCODE { yysetdict(icmpcodewords); } ; typelist: icmptype { DOREM(fr->fr_icmp = htons($1 << 8); fr->fr_icmpm = htons(0xff00);) } | typelist lmore icmptype { DOREM(fr->fr_icmp = htons($3 << 8); fr->fr_icmpm = htons(0xff00);) } ; codelist: icmpcode { DOREM(fr->fr_icmp |= htons($1); fr->fr_icmpm |= htons(0xff);) } | codelist lmore icmpcode { DOREM(fr->fr_icmp &= htons(0xff00); fr->fr_icmp |= htons($3); \ fr->fr_icmpm |= htons(0xff);) } ; age: | IPFY_AGE YY_NUMBER { DOALL(fr->fr_age[0] = $2; \ fr->fr_age[1] = $2;) } | IPFY_AGE YY_NUMBER '/' YY_NUMBER { DOALL(fr->fr_age[0] = $2; \ fr->fr_age[1] = $4;) } ; keep: | IPFY_KEEP keepstate keep | IPFY_KEEP keepfrag keep ; keepstate: IPFY_STATE stateoptlist { DOALL(fr->fr_flags |= FR_KEEPSTATE;)} ; keepfrag: IPFY_FRAGS fragoptlist { DOALL(fr->fr_flags |= FR_KEEPFRAG;) } | IPFY_FRAG fragoptlist { DOALL(fr->fr_flags |= FR_KEEPFRAG;) } ; fragoptlist: | '(' fragopts ')' ; fragopts: fragopt lanother fragopts | fragopt ; fragopt: IPFY_STRICT { DOALL(fr->fr_flags |= FR_FRSTRICT;) } ; stateoptlist: | '(' stateopts ')' ; stateopts: stateopt lanother stateopts | stateopt ; stateopt: IPFY_LIMIT YY_NUMBER { DOALL(fr->fr_statemax = $2;) } | IPFY_STRICT { DOALL(if (fr->fr_proto != IPPROTO_TCP) { \ YYERROR; \ } else if (fr->fr_flags & FR_STLOOSE) {\ YYERROR; \ } else \ fr->fr_flags |= FR_STSTRICT;) } | IPFY_LOOSE { DOALL(if (fr->fr_proto != IPPROTO_TCP) { \ YYERROR; \ } else if (fr->fr_flags & FR_STSTRICT){\ YYERROR; \ } else \ fr->fr_flags |= FR_STLOOSE;) } | IPFY_NEWISN { DOALL(if (fr->fr_proto != IPPROTO_TCP) { \ YYERROR; \ } else \ fr->fr_flags |= FR_NEWISN;) } | IPFY_NOICMPERR { DOALL(fr->fr_flags |= FR_NOICMPERR;) } | IPFY_SYNC { DOALL(fr->fr_flags |= FR_STATESYNC;) } | IPFY_AGE YY_NUMBER { DOALL(fr->fr_age[0] = $2; \ fr->fr_age[1] = $2;) } | IPFY_AGE YY_NUMBER '/' YY_NUMBER { DOALL(fr->fr_age[0] = $2; \ fr->fr_age[1] = $4;) } | IPFY_ICMPHEAD groupname { DOALL(seticmphead(&fr, $2);) free($2); } | IPFY_NOLOG { DOALL(fr->fr_nostatelog = 1;) } | IPFY_RPC { DOALL(fr->fr_rpc = 1;) } | IPFY_RPC IPFY_IN YY_STR { DOALL(fr->fr_rpc = 1;) } | IPFY_MAX_SRCS YY_NUMBER { DOALL(fr->fr_srctrack.ht_max_nodes = $2;) } | IPFY_MAX_PER_SRC YY_NUMBER { DOALL(fr->fr_srctrack.ht_max_per_node = $2; \ fr->fr_srctrack.ht_netmask = \ fr->fr_family == AF_INET ? 32: 128;) } | IPFY_MAX_PER_SRC YY_NUMBER '/' YY_NUMBER { DOALL(fr->fr_srctrack.ht_max_per_node = $2; \ fr->fr_srctrack.ht_netmask = $4;) } ; portnum: servicename { if (getport(frc, $1, &($$), NULL) == -1) yyerror("service unknown"); $$ = ntohs($$); free($1); } | YY_NUMBER { if ($1 > 65535) /* Unsigned */ yyerror("invalid port number"); else $$ = $1; } ; withlist: withopt { nowith = 0; } | withlist withopt { nowith = 0; } | withlist ',' withopt { nowith = 0; } ; withopt: opttype { DOALL(fr->fr_flx |= $1; fr->fr_mflx |= $1;) } | notwith opttype { DOALL(fr->fr_mflx |= $2;) } | ipopt ipopts { yyresetdict(); } | notwith ipopt ipopts { yyresetdict(); } | startv6hdr ipv6hdrs { yyresetdict(); } ; ipopt: IPFY_OPT { yysetdict(ipv4optwords); } ; startv6hdr: IPFY_V6HDR { if (frc->fr_family != AF_INET6) yyerror("only available with IPv6"); yysetdict(ipv6optwords); } ; notwith: IPFY_NOT { nowith = 1; } | IPFY_NO { nowith = 1; } ; opttype: IPFY_IPOPTS { $$ = FI_OPTIONS; } | IPFY_SHORT { $$ = FI_SHORT; } | IPFY_NAT { $$ = FI_NATED; } | IPFY_BAD { $$ = FI_BAD; } | IPFY_BADNAT { $$ = FI_BADNAT; } | IPFY_BADSRC { $$ = FI_BADSRC; } | IPFY_LOWTTL { $$ = FI_LOWTTL; } | IPFY_FRAG { $$ = FI_FRAG; } | IPFY_FRAGBODY { $$ = FI_FRAGBODY; } | IPFY_FRAGS { $$ = FI_FRAG; } | IPFY_MBCAST { $$ = FI_MBCAST; } | IPFY_MULTICAST { $$ = FI_MULTICAST; } | IPFY_BROADCAST { $$ = FI_BROADCAST; } | IPFY_STATE { $$ = FI_STATE; } | IPFY_OOW { $$ = FI_OOW; } | IPFY_AH { $$ = FI_AH; } | IPFY_V6HDRS { $$ = FI_V6EXTHDR; } ; ipopts: optlist { DOALL(fr->fr_mip.fi_optmsk |= $1; if (fr->fr_family == AF_UNSPEC) { fr->fr_family = AF_INET; fr->fr_ip.fi_v = 4; fr->fr_mip.fi_v = 0xf; } else if (fr->fr_family != AF_INET) { YYERROR; } if (!nowith) fr->fr_ip.fi_optmsk |= $1;) } ; optlist: opt { $$ |= $1; } | optlist ',' opt { $$ |= $1 | $3; } ; ipv6hdrs: ipv6hdrlist { DOALL(fr->fr_mip.fi_optmsk |= $1; if (!nowith) fr->fr_ip.fi_optmsk |= $1;) } ; ipv6hdrlist: ipv6hdr { $$ |= $1; } | ipv6hdrlist ',' ipv6hdr { $$ |= $1 | $3; } ; secname: seclevel { $$ |= $1; } | secname ',' seclevel { $$ |= $1 | $3; } ; seclevel: IPFY_SEC_UNC { $$ = secbit(IPSO_CLASS_UNCL); } | IPFY_SEC_CONF { $$ = secbit(IPSO_CLASS_CONF); } | IPFY_SEC_RSV1 { $$ = secbit(IPSO_CLASS_RES1); } | IPFY_SEC_RSV2 { $$ = secbit(IPSO_CLASS_RES2); } | IPFY_SEC_RSV3 { $$ = secbit(IPSO_CLASS_RES3); } | IPFY_SEC_RSV4 { $$ = secbit(IPSO_CLASS_RES4); } | IPFY_SEC_SEC { $$ = secbit(IPSO_CLASS_SECR); } | IPFY_SEC_TS { $$ = secbit(IPSO_CLASS_TOPS); } ; icmptype: YY_NUMBER { $$ = $1; } | YY_STR { $$ = geticmptype(frc->fr_family, $1); if ($$ == -1) yyerror("unrecognised icmp type"); } ; icmpcode: YY_NUMBER { $$ = $1; } | IPFY_ICMPC_NETUNR { $$ = ICMP_UNREACH_NET; } | IPFY_ICMPC_HSTUNR { $$ = ICMP_UNREACH_HOST; } | IPFY_ICMPC_PROUNR { $$ = ICMP_UNREACH_PROTOCOL; } | IPFY_ICMPC_PORUNR { $$ = ICMP_UNREACH_PORT; } | IPFY_ICMPC_NEEDF { $$ = ICMP_UNREACH_NEEDFRAG; } | IPFY_ICMPC_SRCFAIL { $$ = ICMP_UNREACH_SRCFAIL; } | IPFY_ICMPC_NETUNK { $$ = ICMP_UNREACH_NET_UNKNOWN; } | IPFY_ICMPC_HSTUNK { $$ = ICMP_UNREACH_HOST_UNKNOWN; } | IPFY_ICMPC_ISOLATE { $$ = ICMP_UNREACH_ISOLATED; } | IPFY_ICMPC_NETPRO { $$ = ICMP_UNREACH_NET_PROHIB; } | IPFY_ICMPC_HSTPRO { $$ = ICMP_UNREACH_HOST_PROHIB; } | IPFY_ICMPC_NETTOS { $$ = ICMP_UNREACH_TOSNET; } | IPFY_ICMPC_HSTTOS { $$ = ICMP_UNREACH_TOSHOST; } | IPFY_ICMPC_FLTPRO { $$ = ICMP_UNREACH_ADMIN_PROHIBIT; } | IPFY_ICMPC_HSTPRE { $$ = 14; } | IPFY_ICMPC_CUTPRE { $$ = 15; } ; opt: IPFY_IPOPT_NOP { $$ = getoptbyvalue(IPOPT_NOP); } | IPFY_IPOPT_RR { $$ = getoptbyvalue(IPOPT_RR); } | IPFY_IPOPT_ZSU { $$ = getoptbyvalue(IPOPT_ZSU); } | IPFY_IPOPT_MTUP { $$ = getoptbyvalue(IPOPT_MTUP); } | IPFY_IPOPT_MTUR { $$ = getoptbyvalue(IPOPT_MTUR); } | IPFY_IPOPT_ENCODE { $$ = getoptbyvalue(IPOPT_ENCODE); } | IPFY_IPOPT_TS { $$ = getoptbyvalue(IPOPT_TS); } | IPFY_IPOPT_TR { $$ = getoptbyvalue(IPOPT_TR); } | IPFY_IPOPT_SEC { $$ = getoptbyvalue(IPOPT_SECURITY); } | IPFY_IPOPT_LSRR { $$ = getoptbyvalue(IPOPT_LSRR); } | IPFY_IPOPT_ESEC { $$ = getoptbyvalue(IPOPT_E_SEC); } | IPFY_IPOPT_CIPSO { $$ = getoptbyvalue(IPOPT_CIPSO); } | IPFY_IPOPT_CIPSO doi { $$ = getoptbyvalue(IPOPT_CIPSO); } | IPFY_IPOPT_SATID { $$ = getoptbyvalue(IPOPT_SATID); } | IPFY_IPOPT_SSRR { $$ = getoptbyvalue(IPOPT_SSRR); } | IPFY_IPOPT_ADDEXT { $$ = getoptbyvalue(IPOPT_ADDEXT); } | IPFY_IPOPT_VISA { $$ = getoptbyvalue(IPOPT_VISA); } | IPFY_IPOPT_IMITD { $$ = getoptbyvalue(IPOPT_IMITD); } | IPFY_IPOPT_EIP { $$ = getoptbyvalue(IPOPT_EIP); } | IPFY_IPOPT_FINN { $$ = getoptbyvalue(IPOPT_FINN); } | IPFY_IPOPT_DPS { $$ = getoptbyvalue(IPOPT_DPS); } | IPFY_IPOPT_SDB { $$ = getoptbyvalue(IPOPT_SDB); } | IPFY_IPOPT_NSAPA { $$ = getoptbyvalue(IPOPT_NSAPA); } | IPFY_IPOPT_RTRALRT { $$ = getoptbyvalue(IPOPT_RTRALRT); } | IPFY_IPOPT_UMP { $$ = getoptbyvalue(IPOPT_UMP); } | setsecclass secname { DOALL(fr->fr_mip.fi_secmsk |= $2; if (fr->fr_family == AF_UNSPEC) { fr->fr_family = AF_INET; fr->fr_ip.fi_v = 4; fr->fr_mip.fi_v = 0xf; } else if (fr->fr_family != AF_INET) { YYERROR; } if (!nowith) fr->fr_ip.fi_secmsk |= $2;) $$ = 0; yyresetdict(); } ; setsecclass: IPFY_SECCLASS { yysetdict(ipv4secwords); } ; doi: IPFY_DOI YY_NUMBER { DOALL(fr->fr_doimask = 0xffffffff; \ if (!nowith) \ fr->fr_doi = $2;) } | IPFY_DOI YY_HEX { DOALL(fr->fr_doimask = 0xffffffff; \ if (!nowith) \ fr->fr_doi = $2;) } ; ipv6hdr: IPFY_AH { $$ = getv6optbyvalue(IPPROTO_AH); } | IPFY_IPV6OPT_DSTOPTS { $$ = getv6optbyvalue(IPPROTO_DSTOPTS); } | IPFY_IPV6OPT_ESP { $$ = getv6optbyvalue(IPPROTO_ESP); } | IPFY_IPV6OPT_HOPOPTS { $$ = getv6optbyvalue(IPPROTO_HOPOPTS); } | IPFY_IPV6OPT_IPV6 { $$ = getv6optbyvalue(IPPROTO_IPV6); } | IPFY_IPV6OPT_NONE { $$ = getv6optbyvalue(IPPROTO_NONE); } | IPFY_IPV6OPT_ROUTING { $$ = getv6optbyvalue(IPPROTO_ROUTING); } | IPFY_IPV6OPT_FRAG { $$ = getv6optbyvalue(IPPROTO_FRAGMENT); } | IPFY_IPV6OPT_MOBILITY { $$ = getv6optbyvalue(IPPROTO_MOBILITY); } ; level: IPFY_LEVEL { setsyslog(); } ; loglevel: priority { fr->fr_loglevel = LOG_LOCAL0|$1; } | facility '.' priority { fr->fr_loglevel = $1 | $3; } ; facility: IPFY_FAC_KERN { $$ = LOG_KERN; } | IPFY_FAC_USER { $$ = LOG_USER; } | IPFY_FAC_MAIL { $$ = LOG_MAIL; } | IPFY_FAC_DAEMON { $$ = LOG_DAEMON; } | IPFY_FAC_AUTH { $$ = LOG_AUTH; } | IPFY_FAC_SYSLOG { $$ = LOG_SYSLOG; } | IPFY_FAC_LPR { $$ = LOG_LPR; } | IPFY_FAC_NEWS { $$ = LOG_NEWS; } | IPFY_FAC_UUCP { $$ = LOG_UUCP; } | IPFY_FAC_CRON { $$ = LOG_CRON; } | IPFY_FAC_FTP { $$ = LOG_FTP; } | IPFY_FAC_AUTHPRIV { $$ = LOG_AUTHPRIV; } | IPFY_FAC_AUDIT { $$ = LOG_AUDIT; } | IPFY_FAC_LFMT { $$ = LOG_LFMT; } | IPFY_FAC_LOCAL0 { $$ = LOG_LOCAL0; } | IPFY_FAC_LOCAL1 { $$ = LOG_LOCAL1; } | IPFY_FAC_LOCAL2 { $$ = LOG_LOCAL2; } | IPFY_FAC_LOCAL3 { $$ = LOG_LOCAL3; } | IPFY_FAC_LOCAL4 { $$ = LOG_LOCAL4; } | IPFY_FAC_LOCAL5 { $$ = LOG_LOCAL5; } | IPFY_FAC_LOCAL6 { $$ = LOG_LOCAL6; } | IPFY_FAC_LOCAL7 { $$ = LOG_LOCAL7; } | IPFY_FAC_SECURITY { $$ = LOG_SECURITY; } ; priority: IPFY_PRI_EMERG { $$ = LOG_EMERG; } | IPFY_PRI_ALERT { $$ = LOG_ALERT; } | IPFY_PRI_CRIT { $$ = LOG_CRIT; } | IPFY_PRI_ERR { $$ = LOG_ERR; } | IPFY_PRI_WARN { $$ = LOG_WARNING; } | IPFY_PRI_NOTICE { $$ = LOG_NOTICE; } | IPFY_PRI_INFO { $$ = LOG_INFO; } | IPFY_PRI_DEBUG { $$ = LOG_DEBUG; } ; compare: YY_CMP_EQ { $$ = FR_EQUAL; } | YY_CMP_NE { $$ = FR_NEQUAL; } | YY_CMP_LT { $$ = FR_LESST; } | YY_CMP_LE { $$ = FR_LESSTE; } | YY_CMP_GT { $$ = FR_GREATERT; } | YY_CMP_GE { $$ = FR_GREATERTE; } ; range: YY_RANGE_IN { $$ = FR_INRANGE; } | YY_RANGE_OUT { $$ = FR_OUTRANGE; } | ':' { $$ = FR_INCRANGE; } ; servicename: YY_STR { $$ = $1; } ; interfacename: name { $$ = $1; } | name ':' YY_NUMBER { $$ = $1; fprintf(stderr, "%d: Logical interface %s:%d unsupported, " "use the physical interface %s instead.\n", yylineNum, $1, $3, $1); } ; name: YY_STR { $$ = $1; } | '-' { $$ = strdup("-"); } ; ipv4_16: YY_NUMBER '.' YY_NUMBER { if ($1 > 255 || $3 > 255) { yyerror("Invalid octet string for IP address"); return 0; } $$.s_addr = ($1 << 24) | ($3 << 16); $$.s_addr = htonl($$.s_addr); } ; ipv4_24: ipv4_16 '.' YY_NUMBER { if ($3 > 255) { yyerror("Invalid octet string for IP address"); return 0; } $$.s_addr |= htonl($3 << 8); } ; ipv4: ipv4_24 '.' YY_NUMBER { if ($3 > 255) { yyerror("Invalid octet string for IP address"); return 0; } $$.s_addr |= htonl($3); } | ipv4_24 | ipv4_16 ; %% static struct wordtab ipfwords[] = { { "age", IPFY_AGE }, { "ah", IPFY_AH }, { "all", IPFY_ALL }, { "and", IPFY_AND }, { "auth", IPFY_AUTH }, { "bad", IPFY_BAD }, { "bad-nat", IPFY_BADNAT }, { "bad-src", IPFY_BADSRC }, { "bcast", IPFY_BROADCAST }, { "block", IPFY_BLOCK }, { "body", IPFY_BODY }, { "bpf-v4", IPFY_BPFV4 }, #ifdef USE_INET6 { "bpf-v6", IPFY_BPFV6 }, #endif { "call", IPFY_CALL }, { "code", IPFY_ICMPCODE }, { "comment", IPFY_COMMENT }, { "count", IPFY_COUNT }, { "decapsulate", IPFY_DECAPS }, { "dstlist", IPFY_DSTLIST }, { "doi", IPFY_DOI }, { "dup-to", IPFY_DUPTO }, { "eq", YY_CMP_EQ }, { "esp", IPFY_ESP }, { "exp", IPFY_IPFEXPR }, { "family", IPFY_FAMILY }, { "fastroute", IPFY_FROUTE }, { "first", IPFY_FIRST }, { "flags", IPFY_FLAGS }, { "frag", IPFY_FRAG }, { "frag-body", IPFY_FRAGBODY }, { "frags", IPFY_FRAGS }, { "from", IPFY_FROM }, { "ge", YY_CMP_GE }, { "group", IPFY_GROUP }, { "gt", YY_CMP_GT }, { "head", IPFY_HEAD }, { "icmp", IPFY_ICMP }, { "icmp-head", IPFY_ICMPHEAD }, { "icmp-type", IPFY_ICMPTYPE }, { "in", IPFY_IN }, { "in-via", IPFY_INVIA }, { "inet", IPFY_INET }, { "inet6", IPFY_INET6 }, { "ipopt", IPFY_IPOPTS }, { "ipopts", IPFY_IPOPTS }, { "keep", IPFY_KEEP }, { "l5-as", IPFY_L5AS }, { "le", YY_CMP_LE }, { "level", IPFY_LEVEL }, { "limit", IPFY_LIMIT }, { "log", IPFY_LOG }, { "loose", IPFY_LOOSE }, { "lowttl", IPFY_LOWTTL }, { "lt", YY_CMP_LT }, { "mask", IPFY_MASK }, { "match-tag", IPFY_MATCHTAG }, { "max-per-src", IPFY_MAX_PER_SRC }, { "max-srcs", IPFY_MAX_SRCS }, { "mbcast", IPFY_MBCAST }, { "mcast", IPFY_MULTICAST }, { "multicast", IPFY_MULTICAST }, { "nat", IPFY_NAT }, { "ne", YY_CMP_NE }, { "net", IPFY_NETWORK }, { "newisn", IPFY_NEWISN }, { "no", IPFY_NO }, { "no-icmp-err", IPFY_NOICMPERR }, { "nolog", IPFY_NOLOG }, { "nomatch", IPFY_NOMATCH }, { "now", IPFY_NOW }, { "not", IPFY_NOT }, { "oow", IPFY_OOW }, { "on", IPFY_ON }, { "opt", IPFY_OPT }, { "or-block", IPFY_ORBLOCK }, { "out", IPFY_OUT }, { "out-via", IPFY_OUTVIA }, { "pass", IPFY_PASS }, { "port", IPFY_PORT }, { "pps", IPFY_PPS }, { "preauth", IPFY_PREAUTH }, { "proto", IPFY_PROTO }, { "quick", IPFY_QUICK }, { "reply-to", IPFY_REPLY_TO }, { "return-icmp", IPFY_RETICMP }, { "return-icmp-as-dest", IPFY_RETICMPASDST }, { "return-rst", IPFY_RETRST }, { "route-to", IPFY_ROUTETO }, { "rule-ttl", IPFY_RULETTL }, { "rpc", IPFY_RPC }, { "sec-class", IPFY_SECCLASS }, { "set", IPFY_SET }, { "set-tag", IPFY_SETTAG }, { "skip", IPFY_SKIP }, { "short", IPFY_SHORT }, { "state", IPFY_STATE }, { "state-age", IPFY_AGE }, { "strict", IPFY_STRICT }, { "sync", IPFY_SYNC }, { "tcp", IPFY_TCP }, { "tcp-udp", IPFY_TCPUDP }, { "tos", IPFY_TOS }, { "to", IPFY_TO }, { "ttl", IPFY_TTL }, { "udp", IPFY_UDP }, { "v6hdr", IPFY_V6HDR }, { "v6hdrs", IPFY_V6HDRS }, { "with", IPFY_WITH }, { NULL, 0 } }; static struct wordtab addrwords[] = { { "any", IPFY_ANY }, { "hash", IPFY_HASH }, { "pool", IPFY_POOL }, { NULL, 0 } }; static struct wordtab maskwords[] = { { "broadcast", IPFY_BROADCAST }, { "netmasked", IPFY_NETMASKED }, { "network", IPFY_NETWORK }, { "peer", IPFY_PEER }, { NULL, 0 } }; static struct wordtab icmpcodewords[] = { { "cutoff-preced", IPFY_ICMPC_CUTPRE }, { "filter-prohib", IPFY_ICMPC_FLTPRO }, { "isolate", IPFY_ICMPC_ISOLATE }, { "needfrag", IPFY_ICMPC_NEEDF }, { "net-prohib", IPFY_ICMPC_NETPRO }, { "net-tos", IPFY_ICMPC_NETTOS }, { "host-preced", IPFY_ICMPC_HSTPRE }, { "host-prohib", IPFY_ICMPC_HSTPRO }, { "host-tos", IPFY_ICMPC_HSTTOS }, { "host-unk", IPFY_ICMPC_HSTUNK }, { "host-unr", IPFY_ICMPC_HSTUNR }, { "net-unk", IPFY_ICMPC_NETUNK }, { "net-unr", IPFY_ICMPC_NETUNR }, { "port-unr", IPFY_ICMPC_PORUNR }, { "proto-unr", IPFY_ICMPC_PROUNR }, { "srcfail", IPFY_ICMPC_SRCFAIL }, { NULL, 0 }, }; static struct wordtab ipv4optwords[] = { { "addext", IPFY_IPOPT_ADDEXT }, { "cipso", IPFY_IPOPT_CIPSO }, { "dps", IPFY_IPOPT_DPS }, { "e-sec", IPFY_IPOPT_ESEC }, { "eip", IPFY_IPOPT_EIP }, { "encode", IPFY_IPOPT_ENCODE }, { "finn", IPFY_IPOPT_FINN }, { "imitd", IPFY_IPOPT_IMITD }, { "lsrr", IPFY_IPOPT_LSRR }, { "mtup", IPFY_IPOPT_MTUP }, { "mtur", IPFY_IPOPT_MTUR }, { "nop", IPFY_IPOPT_NOP }, { "nsapa", IPFY_IPOPT_NSAPA }, { "rr", IPFY_IPOPT_RR }, { "rtralrt", IPFY_IPOPT_RTRALRT }, { "satid", IPFY_IPOPT_SATID }, { "sdb", IPFY_IPOPT_SDB }, { "sec", IPFY_IPOPT_SEC }, { "ssrr", IPFY_IPOPT_SSRR }, { "tr", IPFY_IPOPT_TR }, { "ts", IPFY_IPOPT_TS }, { "ump", IPFY_IPOPT_UMP }, { "visa", IPFY_IPOPT_VISA }, { "zsu", IPFY_IPOPT_ZSU }, { NULL, 0 }, }; static struct wordtab ipv4secwords[] = { { "confid", IPFY_SEC_CONF }, { "reserv-1", IPFY_SEC_RSV1 }, { "reserv-2", IPFY_SEC_RSV2 }, { "reserv-3", IPFY_SEC_RSV3 }, { "reserv-4", IPFY_SEC_RSV4 }, { "secret", IPFY_SEC_SEC }, { "topsecret", IPFY_SEC_TS }, { "unclass", IPFY_SEC_UNC }, { NULL, 0 }, }; static struct wordtab ipv6optwords[] = { { "dstopts", IPFY_IPV6OPT_DSTOPTS }, { "esp", IPFY_IPV6OPT_ESP }, { "frag", IPFY_IPV6OPT_FRAG }, { "hopopts", IPFY_IPV6OPT_HOPOPTS }, { "ipv6", IPFY_IPV6OPT_IPV6 }, { "mobility", IPFY_IPV6OPT_MOBILITY }, { "none", IPFY_IPV6OPT_NONE }, { "routing", IPFY_IPV6OPT_ROUTING }, { NULL, 0 }, }; static struct wordtab logwords[] = { { "kern", IPFY_FAC_KERN }, { "user", IPFY_FAC_USER }, { "mail", IPFY_FAC_MAIL }, { "daemon", IPFY_FAC_DAEMON }, { "auth", IPFY_FAC_AUTH }, { "syslog", IPFY_FAC_SYSLOG }, { "lpr", IPFY_FAC_LPR }, { "news", IPFY_FAC_NEWS }, { "uucp", IPFY_FAC_UUCP }, { "cron", IPFY_FAC_CRON }, { "ftp", IPFY_FAC_FTP }, { "authpriv", IPFY_FAC_AUTHPRIV }, { "audit", IPFY_FAC_AUDIT }, { "logalert", IPFY_FAC_LFMT }, { "console", IPFY_FAC_CONSOLE }, { "security", IPFY_FAC_SECURITY }, { "local0", IPFY_FAC_LOCAL0 }, { "local1", IPFY_FAC_LOCAL1 }, { "local2", IPFY_FAC_LOCAL2 }, { "local3", IPFY_FAC_LOCAL3 }, { "local4", IPFY_FAC_LOCAL4 }, { "local5", IPFY_FAC_LOCAL5 }, { "local6", IPFY_FAC_LOCAL6 }, { "local7", IPFY_FAC_LOCAL7 }, { "emerg", IPFY_PRI_EMERG }, { "alert", IPFY_PRI_ALERT }, { "crit", IPFY_PRI_CRIT }, { "err", IPFY_PRI_ERR }, { "warn", IPFY_PRI_WARN }, { "notice", IPFY_PRI_NOTICE }, { "info", IPFY_PRI_INFO }, { "debug", IPFY_PRI_DEBUG }, { NULL, 0 }, }; -int ipf_parsefile(fd, addfunc, iocfuncs, filename) -int fd; -addfunc_t addfunc; -ioctlfunc_t *iocfuncs; -char *filename; +int +ipf_parsefile(int fd, addfunc_t addfunc, ioctlfunc_t *iocfuncs, char *filename) { FILE *fp = NULL; char *s; yylineNum = 1; yysettab(ipfwords); s = getenv("YYDEBUG"); if (s != NULL) yydebug = atoi(s); else yydebug = 0; if (strcmp(filename, "-")) { fp = fopen(filename, "r"); if (fp == NULL) { fprintf(stderr, "fopen(%s) failed: %s\n", filename, STRERROR(errno)); return -1; } } else fp = stdin; while (ipf_parsesome(fd, addfunc, iocfuncs, fp) == 1) ; if (fp != NULL) fclose(fp); return 0; } -int ipf_parsesome(fd, addfunc, iocfuncs, fp) -int fd; -addfunc_t addfunc; -ioctlfunc_t *iocfuncs; -FILE *fp; +int +ipf_parsesome(int fd, addfunc_t addfunc, ioctlfunc_t *iocfuncs, FILE *fp) { char *s; int i; ipffd = fd; for (i = 0; i <= IPL_LOGMAX; i++) ipfioctls[i] = iocfuncs[i]; ipfaddfunc = addfunc; if (feof(fp)) return 0; i = fgetc(fp); if (i == EOF) return 0; if (ungetc(i, fp) == 0) return 0; if (feof(fp)) return 0; s = getenv("YYDEBUG"); if (s != NULL) yydebug = atoi(s); else yydebug = 0; yyin = fp; yyparse(); return 1; } -static void newrule() +static void +newrule(void) { frentry_t *frn; frn = allocfr(); for (fr = frtop; fr != NULL && fr->fr_next != NULL; fr = fr->fr_next) ; if (fr != NULL) { fr->fr_next = frn; frn->fr_pnext = &fr->fr_next; } if (frtop == NULL) { frtop = frn; frn->fr_pnext = &frtop; } fr = frn; frc = frn; fr->fr_loglevel = 0xffff; fr->fr_isc = (void *)-1; fr->fr_logtag = FR_NOLOGTAG; fr->fr_type = FR_T_NONE; fr->fr_flineno = yylineNum; if (use_inet6 == 1) fr->fr_family = AF_INET6; else if (use_inet6 == -1) fr->fr_family = AF_INET; nrules = 1; } -static void setipftype() +static void +setipftype(void) { for (fr = frc; fr != NULL; fr = fr->fr_next) { if (fr->fr_type == FR_T_NONE) { fr->fr_type = FR_T_IPF; fr->fr_data = (void *)calloc(sizeof(fripf_t), 1); fr->fr_dsize = sizeof(fripf_t); fr->fr_family = frc->fr_family; if (fr->fr_family == AF_INET) { fr->fr_ip.fi_v = 4; } else if (fr->fr_family == AF_INET6) { fr->fr_ip.fi_v = 6; } fr->fr_mip.fi_v = 0xf; fr->fr_ipf->fri_sifpidx = -1; fr->fr_ipf->fri_difpidx = -1; } if (fr->fr_type != FR_T_IPF) { fprintf(stderr, "IPF Type not set\n"); } } } -static frentry_t *addrule() +static frentry_t * +addrule(void) { frentry_t *f, *f1, *f2; int count; for (f2 = frc; f2->fr_next != NULL; f2 = f2->fr_next) ; count = nrules; f = f2; for (f1 = frc; count > 0; count--, f1 = f1->fr_next) { f->fr_next = allocfr(); if (f->fr_next == NULL) return NULL; f->fr_next->fr_pnext = &f->fr_next; added++; f = f->fr_next; *f = *f1; f->fr_next = NULL; if (f->fr_caddr != NULL) { f->fr_caddr = malloc(f->fr_dsize); bcopy(f1->fr_caddr, f->fr_caddr, f->fr_dsize); } } return f2->fr_next; } static int -lookuphost(name, addrp) - char *name; - i6addr_t *addrp; +lookuphost(char *name, i6addr_t *addrp) { int i; hashed = 0; pooled = 0; dynamic = -1; for (i = 0; i < 4; i++) { if (fr->fr_ifnames[i] == -1) continue; if (strcmp(name, fr->fr_names + fr->fr_ifnames[i]) == 0) { ifpflag = FRI_DYNAMIC; dynamic = addname(&fr, name); return 1; } } if (gethost(AF_INET, name, addrp) == -1) { fprintf(stderr, "unknown name \"%s\"\n", name); return -1; } return 0; } -static void dobpf(v, phrase) -int v; -char *phrase; +static void +dobpf(int v, char *phrase) { #ifdef IPFILTER_BPF struct bpf_program bpf; struct pcap *p; #endif fakebpf_t *fb; u_32_t l; char *s; int i; for (fr = frc; fr != NULL; fr = fr->fr_next) { if (fr->fr_type != FR_T_NONE) { fprintf(stderr, "cannot mix IPF and BPF matching\n"); return; } fr->fr_family = vtof(v); fr->fr_type = FR_T_BPFOPC; if (!strncmp(phrase, "0x", 2)) { fb = malloc(sizeof(fakebpf_t)); for (i = 0, s = strtok(phrase, " \r\n\t"); s != NULL; s = strtok(NULL, " \r\n\t"), i++) { fb = reallocarray(fb, i / 4 + 1, sizeof(*fb)); if (fb == NULL) { warnx("memory allocation error at %d in %s in %s", __LINE__, __FUNCTION__, __FILE__); abort(); } l = (u_32_t)strtol(s, NULL, 0); switch (i & 3) { case 0 : fb[i / 4].fb_c = l & 0xffff; break; case 1 : fb[i / 4].fb_t = l & 0xff; break; case 2 : fb[i / 4].fb_f = l & 0xff; break; case 3 : fb[i / 4].fb_k = l; break; } } if ((i & 3) != 0) { fprintf(stderr, "Odd number of bytes in BPF code\n"); exit(1); } i--; fr->fr_dsize = (i / 4 + 1) * sizeof(*fb); fr->fr_data = fb; return; } #ifdef IPFILTER_BPF bzero((char *)&bpf, sizeof(bpf)); p = pcap_open_dead(DLT_RAW, 1); if (!p) { fprintf(stderr, "pcap_open_dead failed\n"); return; } if (pcap_compile(p, &bpf, phrase, 1, 0xffffffff)) { pcap_perror(p, "ipf"); pcap_close(p); fprintf(stderr, "pcap parsing failed (%s)\n", phrase); return; } pcap_close(p); fr->fr_dsize = bpf.bf_len * sizeof(struct bpf_insn); fr->fr_data = malloc(fr->fr_dsize); bcopy((char *)bpf.bf_insns, fr->fr_data, fr->fr_dsize); if (!bpf_validate(fr->fr_data, bpf.bf_len)) { fprintf(stderr, "BPF validation failed\n"); return; } #endif } #ifdef IPFILTER_BPF if (opts & OPT_DEBUG) bpf_dump(&bpf, 0); #else fprintf(stderr, "BPF filter expressions not supported\n"); exit(1); #endif } -static void resetaddr() +static void +resetaddr(void) { hashed = 0; pooled = 0; dynamic = -1; } -static alist_t *newalist(ptr) -alist_t *ptr; +static alist_t * +newalist(alist_t *ptr) { alist_t *al; al = malloc(sizeof(*al)); if (al == NULL) return NULL; al->al_not = 0; al->al_next = ptr; return al; } static int -makepool(list) - alist_t *list; +makepool(alist_t *list) { ip_pool_node_t *n, *top; ip_pool_t pool; alist_t *a; int num; if (list == NULL) return 0; top = calloc(1, sizeof(*top)); if (top == NULL) return 0; for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) { if (use_inet6 == 1) { #ifdef USE_INET6 n->ipn_addr.adf_family = AF_INET6; n->ipn_addr.adf_addr = a->al_i6addr; n->ipn_addr.adf_len = offsetof(addrfamily_t, adf_addr) + 16; n->ipn_mask.adf_family = AF_INET6; n->ipn_mask.adf_addr = a->al_i6mask; n->ipn_mask.adf_len = offsetof(addrfamily_t, adf_addr) + 16; #endif } else { n->ipn_addr.adf_family = AF_INET; n->ipn_addr.adf_addr.in4.s_addr = a->al_1; n->ipn_addr.adf_len = offsetof(addrfamily_t, adf_addr) + 4; n->ipn_mask.adf_family = AF_INET; n->ipn_mask.adf_addr.in4.s_addr = a->al_2; n->ipn_mask.adf_len = offsetof(addrfamily_t, adf_addr) + 4; } n->ipn_info = a->al_not; if (a->al_next != NULL) { n->ipn_next = calloc(1, sizeof(*n)); n = n->ipn_next; } } bzero((char *)&pool, sizeof(pool)); pool.ipo_unit = IPL_LOGIPF; pool.ipo_list = top; num = load_pool(&pool, ipfioctls[IPL_LOGLOOKUP]); while ((n = top) != NULL) { top = n->ipn_next; free(n); } return num; } -static u_int makehash(list) -alist_t *list; +static u_int +makehash(alist_t *list) { iphtent_t *n, *top; iphtable_t iph; alist_t *a; int num; if (list == NULL) return 0; top = calloc(1, sizeof(*top)); if (top == NULL) return 0; for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) { if (a->al_family == AF_INET6) { n->ipe_family = AF_INET6; n->ipe_addr = a->al_i6addr; n->ipe_mask = a->al_i6mask; } else { n->ipe_family = AF_INET; n->ipe_addr.in4_addr = a->al_1; n->ipe_mask.in4_addr = a->al_2; } n->ipe_value = 0; if (a->al_next != NULL) { n->ipe_next = calloc(1, sizeof(*n)); n = n->ipe_next; } } bzero((char *)&iph, sizeof(iph)); iph.iph_unit = IPL_LOGIPF; iph.iph_type = IPHASH_LOOKUP; *iph.iph_name = '\0'; if (load_hash(&iph, top, ipfioctls[IPL_LOGLOOKUP]) == 0) sscanf(iph.iph_name, "%u", &num); else num = 0; while ((n = top) != NULL) { top = n->ipe_next; free(n); } return num; } -int ipf_addrule(fd, ioctlfunc, ptr) -int fd; -ioctlfunc_t ioctlfunc; -void *ptr; +int +ipf_addrule(int fd, ioctlfunc_t ioctlfunc, void *ptr) { ioctlcmd_t add, del; frentry_t *fr; ipfobj_t obj; if (ptr == NULL) return 0; fr = ptr; add = 0; del = 0; bzero((char *)&obj, sizeof(obj)); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_size = fr->fr_size; obj.ipfo_type = IPFOBJ_FRENTRY; obj.ipfo_ptr = ptr; if ((opts & OPT_DONOTHING) != 0) fd = -1; if (opts & OPT_ZERORULEST) { add = SIOCZRLST; } else if (opts & OPT_INACTIVE) { add = (u_int)fr->fr_hits ? SIOCINIFR : SIOCADIFR; del = SIOCRMIFR; } else { add = (u_int)fr->fr_hits ? SIOCINAFR : SIOCADAFR; del = SIOCRMAFR; } if ((opts & OPT_OUTQUE) != 0) fr->fr_flags |= FR_OUTQUE; if (fr->fr_hits) fr->fr_hits--; if ((opts & OPT_VERBOSE) != 0) printfr(fr, ioctlfunc); if ((opts & OPT_DEBUG) != 0) { binprint(fr, sizeof(*fr)); if (fr->fr_data != NULL) binprint(fr->fr_data, fr->fr_dsize); } if ((opts & OPT_ZERORULEST) != 0) { if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { if ((opts & OPT_DONOTHING) == 0) { char msg[80]; snprintf(msg, sizeof(msg), "%d:ioctl(zero rule)", fr->fr_flineno); return ipf_perror_fd(fd, ioctlfunc, msg); } } else { #ifdef USE_QUAD_T printf("hits %qd bytes %qd ", (long long)fr->fr_hits, (long long)fr->fr_bytes); #else printf("hits %ld bytes %ld ", fr->fr_hits, fr->fr_bytes); #endif printfr(fr, ioctlfunc); } } else if ((opts & OPT_REMOVE) != 0) { if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) { if ((opts & OPT_DONOTHING) == 0) { char msg[80]; snprintf(msg, sizeof(msg), "%d:ioctl(delete rule)", fr->fr_flineno); return ipf_perror_fd(fd, ioctlfunc, msg); } } } else { if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { if ((opts & OPT_DONOTHING) == 0) { char msg[80]; snprintf(msg, sizeof(msg), "%d:ioctl(add/insert rule)", fr->fr_flineno); return ipf_perror_fd(fd, ioctlfunc, msg); } } } return 0; } -static void setsyslog() +static void +setsyslog(void) { yysetdict(logwords); yybreakondot = 1; } -static void unsetsyslog() +static void +unsetsyslog(void) { yyresetdict(); yybreakondot = 0; } -static void fillgroup(fr) -frentry_t *fr; +static void +fillgroup(frentry_t *fr) { frentry_t *f; for (f = frold; f != NULL; f = f->fr_next) { if (f->fr_grhead == -1 && fr->fr_group == -1) break; if (f->fr_grhead == -1 || fr->fr_group == -1) continue; if (strcmp(f->fr_names + f->fr_grhead, fr->fr_names + fr->fr_group) == 0) break; } if (f == NULL) return; /* * Only copy down matching fields if the rules are of the same type * and are of ipf type. The only fields that are copied are those * that impact the rule parsing itself, eg. need for knowing what the * protocol should be for rules with port comparisons in them. */ if (f->fr_type != fr->fr_type || f->fr_type != FR_T_IPF) return; if (fr->fr_family == 0 && f->fr_family != 0) fr->fr_family = f->fr_family; if (fr->fr_mproto == 0 && f->fr_mproto != 0) fr->fr_mproto = f->fr_mproto; if (fr->fr_proto == 0 && f->fr_proto != 0) fr->fr_proto = f->fr_proto; if ((fr->fr_mproto == 0) && ((fr->fr_flx & FI_TCPUDP) == 0) && ((f->fr_flx & FI_TCPUDP) != 0)) { fr->fr_flx |= FI_TCPUDP; fr->fr_mflx |= FI_TCPUDP; } } -static void doipfexpr(line) -char *line; +static void +doipfexpr(char *line) { int *array; char *error; array = parseipfexpr(line, &error); if (array == NULL) { fprintf(stderr, "%s:", error); yyerror("error parsing ipf matching expression"); return; } fr->fr_type = FR_T_IPFEXPR; fr->fr_data = array; fr->fr_dsize = array[0] * sizeof(*array); } -static void do_tuneint(varname, value) -char *varname; -int value; +static void +do_tuneint(char *varname, int value) { char buffer[80]; strncpy(buffer, varname, 60); buffer[59] = '\0'; strcat(buffer, "="); snprintf(buffer, sizeof(buffer), "%u", value); ipf_dotuning(ipffd, buffer, ioctl); } -static void do_tunestr(varname, value) -char *varname, *value; +static void +do_tunestr(char *varname, char *value) { if (!strcasecmp(value, "true")) { do_tuneint(varname, 1); } else if (!strcasecmp(value, "false")) { do_tuneint(varname, 0); } else { yyerror("did not find true/false where expected"); } } -static void setifname(frp, idx, name) -frentry_t **frp; -int idx; -char *name; +static void +setifname(frentry_t **frp, int idx, char *name) { int pos; pos = addname(frp, name); if (pos == -1) return; (*frp)->fr_ifnames[idx] = pos; } -static int addname(frp, name) -frentry_t **frp; -char *name; +static int +addname(frentry_t **frp, char *name) { frentry_t *f; int nlen; int pos; nlen = strlen(name) + 1; f = realloc(*frp, (*frp)->fr_size + nlen); if (*frp == frc) frc = f; *frp = f; if (f == NULL) return -1; if (f->fr_pnext != NULL) *f->fr_pnext = f; f->fr_size += nlen; pos = f->fr_namelen; f->fr_namelen += nlen; strcpy(f->fr_names + pos, name); f->fr_names[f->fr_namelen] = '\0'; return pos; } -static frentry_t *allocfr() +static frentry_t * +allocfr(void) { frentry_t *fr; fr = calloc(1, sizeof(*fr)); if (fr != NULL) { fr->fr_size = sizeof(*fr); fr->fr_comment = -1; fr->fr_group = -1; fr->fr_grhead = -1; fr->fr_icmphead = -1; fr->fr_ifnames[0] = -1; fr->fr_ifnames[1] = -1; fr->fr_ifnames[2] = -1; fr->fr_ifnames[3] = -1; fr->fr_tif.fd_name = -1; fr->fr_rif.fd_name = -1; fr->fr_dif.fd_name = -1; } return fr; } -static void setgroup(frp, name) -frentry_t **frp; -char *name; +static void +setgroup(frentry_t **frp, char *name) { int pos; pos = addname(frp, name); if (pos == -1) return; (*frp)->fr_group = pos; } -static void setgrhead(frp, name) -frentry_t **frp; -char *name; +static void +setgrhead(frentry_t **frp, char *name) { int pos; pos = addname(frp, name); if (pos == -1) return; (*frp)->fr_grhead = pos; } -static void seticmphead(frp, name) -frentry_t **frp; -char *name; +static void +seticmphead(frentry_t **frp, char *name) { int pos; pos = addname(frp, name); if (pos == -1) return; (*frp)->fr_icmphead = pos; } static void -build_dstaddr_af(fp, ptr) - frentry_t *fp; - void *ptr; +build_dstaddr_af(frentry_t *fp, void *ptr) { struct ipp_s *ipp = ptr; frentry_t *f = fp; if (f->fr_family != AF_UNSPEC && ipp->f == AF_UNSPEC) { ipp->f = f->fr_family; ipp->v = f->fr_ip.fi_v; } if (ipp->f == AF_INET) ipp->v = 4; else if (ipp->f == AF_INET6) ipp->v = 6; for (; f != NULL; f = f->fr_next) { f->fr_ip.fi_dst = ipp->a; f->fr_mip.fi_dst = ipp->m; f->fr_family = ipp->f; f->fr_ip.fi_v = ipp->v; f->fr_mip.fi_v = 0xf; f->fr_datype = ipp->type; if (ipp->ifpos != -1) f->fr_ipf->fri_difpidx = ipp->ifpos; } fr = NULL; } static void -build_srcaddr_af(fp, ptr) - frentry_t *fp; - void *ptr; +build_srcaddr_af(frentry_t *fp, void *ptr) { struct ipp_s *ipp = ptr; frentry_t *f = fp; if (f->fr_family != AF_UNSPEC && ipp->f == AF_UNSPEC) { ipp->f = f->fr_family; ipp->v = f->fr_ip.fi_v; } if (ipp->f == AF_INET) ipp->v = 4; else if (ipp->f == AF_INET6) ipp->v = 6; for (; f != NULL; f = f->fr_next) { f->fr_ip.fi_src = ipp->a; f->fr_mip.fi_src = ipp->m; f->fr_family = ipp->f; f->fr_ip.fi_v = ipp->v; f->fr_mip.fi_v = 0xf; f->fr_satype = ipp->type; f->fr_ipf->fri_sifpidx = ipp->ifpos; } fr = NULL; } diff --git a/sbin/ipf/common/lexer.c b/sbin/ipf/common/lexer.c index 2dc2c3e8fe8c..bb401612ad9d 100644 --- a/sbin/ipf/common/lexer.c +++ b/sbin/ipf/common/lexer.c @@ -1,735 +1,737 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include #include "ipf.h" #ifdef IPFILTER_SCAN # include "netinet/ip_scan.h" #endif #include #include #ifdef TEST_LEXER # define NO_YACC union { int num; char *str; struct in_addr ipa; i6addr_t ip6; } yylval; #endif #include "lexer.h" #include "y.tab.h" FILE *yyin; #define ishex(c) (ISDIGIT(c) || ((c) >= 'a' && (c) <= 'f') || \ ((c) >= 'A' && (c) <= 'F')) #define TOOLONG -3 extern int string_start; extern int string_end; extern char *string_val; extern int pos; extern int yydebug; char *yystr = NULL; int yytext[YYBUFSIZ+1]; char yychars[YYBUFSIZ+1]; int yylineNum = 1; int yypos = 0; int yylast = -1; int yydictfixed = 0; int yyexpectaddr = 0; int yybreakondot = 0; int yyvarnext = 0; int yytokentype = 0; wordtab_t *yywordtab = NULL; int yysavedepth = 0; wordtab_t *yysavewords[30]; static wordtab_t *yyfindkey(char *); static int yygetc(int); static void yyunputc(int); static int yyswallow(int); static char *yytexttostr(int, int); static void yystrtotext(char *); static char *yytexttochar(void); -static int yygetc(docont) - int docont; +static int +yygetc(int docont) { int c; if (yypos < yylast) { c = yytext[yypos++]; if (c == '\n') yylineNum++; return c; } if (yypos == YYBUFSIZ) return TOOLONG; if (pos >= string_start && pos <= string_end) { c = string_val[pos - string_start]; yypos++; } else { c = fgetc(yyin); if (docont && (c == '\\')) { c = fgetc(yyin); if (c == '\n') { yylineNum++; c = fgetc(yyin); } } } if (c == '\n') yylineNum++; yytext[yypos++] = c; yylast = yypos; yytext[yypos] = '\0'; return c; } -static void yyunputc(c) - int c; +static void +yyunputc(int c) { if (c == '\n') yylineNum--; yytext[--yypos] = c; } -static int yyswallow(last) - int last; +static int +yyswallow(int last) { int c; while (((c = yygetc(0)) > '\0') && (c != last)) ; if (c != EOF) yyunputc(c); if (c == last) return 0; return -1; } -static char *yytexttochar() +static char * +yytexttochar(void) { int i; for (i = 0; i < yypos; i++) yychars[i] = (char)(yytext[i] & 0xff); yychars[i] = '\0'; return yychars; } -static void yystrtotext(str) - char *str; +static void +yystrtotext(char *str) { int len; char *s; len = strlen(str); if (len > YYBUFSIZ) len = YYBUFSIZ; for (s = str; *s != '\0' && len > 0; s++, len--) yytext[yylast++] = *s; yytext[yylast] = '\0'; } -static char *yytexttostr(offset, max) - int offset, max; +static char * +yytexttostr(int offset, int max) { char *str; int i; if ((yytext[offset] == '\'' || yytext[offset] == '"') && (yytext[offset] == yytext[offset + max - 1])) { offset++; max--; } if (max > yylast) max = yylast; str = malloc(max + 1); if (str != NULL) { for (i = offset; i < max; i++) str[i - offset] = (char)(yytext[i] & 0xff); str[i - offset] = '\0'; } return str; } -int yylex() +int +yylex(void) { static int prior = 0; static int priornum = 0; int c, n, isbuilding, rval, lnext, nokey = 0; char *name; int triedv6 = 0; isbuilding = 0; lnext = 0; rval = 0; if (yystr != NULL) { free(yystr); yystr = NULL; } nextchar: c = yygetc(0); if (yydebug > 1) printf("yygetc = (%x) %c [%*.*s]\n", c, c, yypos, yypos, yytexttochar()); switch (c) { case '\n' : lnext = 0; nokey = 0; case '\t' : case '\r' : case ' ' : if (isbuilding == 1) { yyunputc(c); goto done; } if (yylast > yypos) { bcopy(yytext + yypos, yytext, sizeof(yytext[0]) * (yylast - yypos + 1)); } yylast -= yypos; if (yyexpectaddr == 2) yyexpectaddr = 0; yypos = 0; lnext = 0; nokey = 0; goto nextchar; case '\\' : if (lnext == 0) { lnext = 1; if (yylast == yypos) { yylast--; yypos--; } else yypos--; if (yypos == 0) nokey = 1; goto nextchar; } break; } if (lnext == 1) { lnext = 0; if ((isbuilding == 0) && !ISALNUM(c)) { prior = c; return c; } goto nextchar; } switch (c) { case '#' : if (isbuilding == 1) { yyunputc(c); goto done; } yyswallow('\n'); rval = YY_COMMENT; goto done; case '$' : if (isbuilding == 1) { yyunputc(c); goto done; } n = yygetc(0); if (n == '{') { if (yyswallow('}') == -1) { rval = -2; goto done; } (void) yygetc(0); } else { if (!ISALPHA(n)) { yyunputc(n); break; } do { n = yygetc(1); } while (ISALPHA(n) || ISDIGIT(n) || n == '_'); yyunputc(n); } name = yytexttostr(1, yypos); /* skip $ */ if (name != NULL) { string_val = get_variable(name, NULL, yylineNum); free(name); if (string_val != NULL) { name = yytexttostr(yypos, yylast); if (name != NULL) { yypos = 0; yylast = 0; yystrtotext(string_val); yystrtotext(name); free(string_val); free(name); goto nextchar; } free(string_val); } } break; case '\'': case '"' : if (isbuilding == 1) { goto done; } do { n = yygetc(1); if (n == EOF || n == TOOLONG) { rval = -2; goto done; } if (n == '\n') { yyunputc(' '); yypos++; } } while (n != c); rval = YY_STR; goto done; /* NOTREACHED */ case EOF : yylineNum = 1; yypos = 0; yylast = -1; yyexpectaddr = 0; yybreakondot = 0; yyvarnext = 0; yytokentype = 0; if (yydebug) fprintf(stderr, "reset at EOF\n"); prior = 0; return 0; } if (strchr("=,/;{}()@", c) != NULL) { if (isbuilding == 1) { yyunputc(c); goto done; } rval = c; goto done; } else if (c == '.') { if (isbuilding == 0) { rval = c; goto done; } if (yybreakondot != 0) { yyunputc(c); goto done; } } switch (c) { case '-' : n = yygetc(0); if (n == '>') { isbuilding = 1; goto done; } yyunputc(n); if (yyexpectaddr) { if (isbuilding == 1) yyunputc(c); else rval = '-'; goto done; } if (isbuilding == 1) break; rval = '-'; goto done; case '!' : if (isbuilding == 1) { yyunputc(c); goto done; } n = yygetc(0); if (n == '=') { rval = YY_CMP_NE; goto done; } yyunputc(n); rval = '!'; goto done; case '<' : if (yyexpectaddr) break; if (isbuilding == 1) { yyunputc(c); goto done; } n = yygetc(0); if (n == '=') { rval = YY_CMP_LE; goto done; } if (n == '>') { rval = YY_RANGE_OUT; goto done; } yyunputc(n); rval = YY_CMP_LT; goto done; case '>' : if (yyexpectaddr) break; if (isbuilding == 1) { yyunputc(c); goto done; } n = yygetc(0); if (n == '=') { rval = YY_CMP_GE; goto done; } if (n == '<') { rval = YY_RANGE_IN; goto done; } yyunputc(n); rval = YY_CMP_GT; goto done; } /* * Now for the reason this is here...IPv6 address parsing. * The longest string we can expect is of this form: * 0000:0000:0000:0000:0000:0000:000.000.000.000 * not: * 0000:0000:0000:0000:0000:0000:0000:0000 */ #ifdef USE_INET6 if (yyexpectaddr != 0 && isbuilding == 0 && (ishex(c) || isdigit(c) || c == ':')) { char ipv6buf[45 + 1], *s, oc; int start; buildipv6: start = yypos; s = ipv6buf; oc = c; if (prior == YY_NUMBER && c == ':') { snprintf(s, sizeof(s), "%d", priornum); s += strlen(s); } /* * Perhaps we should implement stricter controls on what we * swallow up here, but surely it would just be duplicating * the code in inet_pton() anyway. */ do { *s++ = c; c = yygetc(1); } while ((ishex(c) || c == ':' || c == '.') && (s - ipv6buf < 46)); yyunputc(c); *s = '\0'; if (inet_pton(AF_INET6, ipv6buf, &yylval.ip6) == 1) { rval = YY_IPV6; yyexpectaddr = 0; goto done; } yypos = start; c = oc; } #endif if ((c == ':') && (rval != YY_IPV6) && (triedv6 == 0)) { #ifdef USE_INET6 yystr = yytexttostr(0, yypos - 1); if (yystr != NULL) { char *s; for (s = yystr; *s && ishex(*s); s++) ; if (!*s && *yystr) { isbuilding = 0; c = *yystr; free(yystr); triedv6 = 1; yypos = 1; goto buildipv6; } free(yystr); } #endif if (isbuilding == 1) { yyunputc(c); goto done; } rval = ':'; goto done; } if (isbuilding == 0 && c == '0') { n = yygetc(0); if (n == 'x') { do { n = yygetc(1); } while (ishex(n)); yyunputc(n); rval = YY_HEX; goto done; } yyunputc(n); } /* * No negative numbers with leading - sign.. */ if (isbuilding == 0 && ISDIGIT(c)) { do { n = yygetc(1); } while (ISDIGIT(n)); yyunputc(n); rval = YY_NUMBER; goto done; } isbuilding = 1; goto nextchar; done: yystr = yytexttostr(0, yypos); if (yydebug) printf("isbuilding %d yyvarnext %d nokey %d fixed %d addr %d\n", isbuilding, yyvarnext, nokey, yydictfixed, yyexpectaddr); if (isbuilding == 1) { wordtab_t *w; w = NULL; isbuilding = 0; if ((yyvarnext == 0) && (nokey == 0)) { w = yyfindkey(yystr); if (w == NULL && yywordtab != NULL && !yydictfixed) { yyresetdict(); w = yyfindkey(yystr); } } else yyvarnext = 0; if (w != NULL) rval = w->w_value; else rval = YY_STR; } if (rval == YY_STR) { if (yysavedepth > 0 && !yydictfixed) yyresetdict(); if (yyexpectaddr != 0) yyexpectaddr = 0; } yytokentype = rval; if (yydebug) printf("lexed(%s) %d,%d,%d [%d,%d,%d] => %d @%d\n", yystr, isbuilding, yyexpectaddr, yysavedepth, string_start, string_end, pos, rval, yysavedepth); switch (rval) { case YY_NUMBER : sscanf(yystr, "%u", &yylval.num); break; case YY_HEX : sscanf(yystr, "0x%x", (u_int *)&yylval.num); break; case YY_STR : yylval.str = strdup(yystr); break; default : break; } if (yylast > 0) { bcopy(yytext + yypos, yytext, sizeof(yytext[0]) * (yylast - yypos + 1)); yylast -= yypos; yypos = 0; } if (rval == YY_NUMBER) priornum = yylval.num; prior = rval; return rval; } static wordtab_t *yyfindkey(key) char *key; { wordtab_t *w; if (yywordtab == NULL) return NULL; for (w = yywordtab; w->w_word != 0; w++) if (strcasecmp(key, w->w_word) == 0) return w; return NULL; } -char *yykeytostr(num) - int num; +char * +yykeytostr(int num) { wordtab_t *w; if (yywordtab == NULL) return ""; for (w = yywordtab; w->w_word; w++) if (w->w_value == num) return w->w_word; return ""; } -wordtab_t *yysettab(words) - wordtab_t *words; +wordtab_t * +yysettab(wordtab_t *words) { wordtab_t *save; save = yywordtab; yywordtab = words; return save; } -void yyerror(msg) - char *msg; +void +yyerror(char *msg) { char *txt, letter[2]; int freetxt = 0; if (yytokentype < 256) { letter[0] = yytokentype; letter[1] = '\0'; txt = letter; } else if (yytokentype == YY_STR || yytokentype == YY_HEX || yytokentype == YY_NUMBER) { if (yystr == NULL) { txt = yytexttostr(yypos, YYBUFSIZ); freetxt = 1; } else txt = yystr; } else { txt = yykeytostr(yytokentype); } fprintf(stderr, "%s error at \"%s\", line %d\n", msg, txt, yylineNum); if (freetxt == 1) free(txt); exit(1); } -void yysetfixeddict(newdict) - wordtab_t *newdict; +void +yysetfixeddict(wordtab_t *newdict) { if (yydebug) printf("yysetfixeddict(%lx)\n", (u_long)newdict); if (yysavedepth == sizeof(yysavewords)/sizeof(yysavewords[0])) { fprintf(stderr, "%d: at maximum dictionary depth\n", yylineNum); return; } yysavewords[yysavedepth++] = yysettab(newdict); if (yydebug) printf("yysavedepth++ => %d\n", yysavedepth); yydictfixed = 1; } -void yysetdict(newdict) - wordtab_t *newdict; +void +yysetdict(wordtab_t *newdict) { if (yydebug) printf("yysetdict(%lx)\n", (u_long)newdict); if (yysavedepth == sizeof(yysavewords)/sizeof(yysavewords[0])) { fprintf(stderr, "%d: at maximum dictionary depth\n", yylineNum); return; } yysavewords[yysavedepth++] = yysettab(newdict); if (yydebug) printf("yysavedepth++ => %d\n", yysavedepth); } -void yyresetdict() +void +yyresetdict(void) { if (yydebug) printf("yyresetdict(%d)\n", yysavedepth); if (yysavedepth > 0) { yysettab(yysavewords[--yysavedepth]); if (yydebug) printf("yysavedepth-- => %d\n", yysavedepth); } yydictfixed = 0; } #ifdef TEST_LEXER -int main(argc, argv) - int argc; - char *argv[]; +int +main(int argc, char *argv[]) { int n; yyin = stdin; while ((n = yylex()) != 0) printf("%d.n = %d [%s] %d %d\n", yylineNum, n, yystr, yypos, yylast); } #endif diff --git a/sbin/ipf/ipf/ipf.c b/sbin/ipf/ipf/ipf.c index 406737e25d8e..3567a82484fb 100644 --- a/sbin/ipf/ipf/ipf.c +++ b/sbin/ipf/ipf/ipf.c @@ -1,577 +1,578 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" #include #include #include #include "netinet/ipl.h" #if !defined(lint) static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #if !defined(__SVR4) && defined(__GNUC__) extern char *index(const char *, int); #endif extern char *optarg; extern int optind; extern frentry_t *frtop; void ipf_frsync(void); void zerostats(void); int main(int, char *[]); int opts = 0; int outputc = 0; int use_inet6 = 0; int exitstatus = 0; static void procfile(char *); static void flushfilter(char *, int *); static void set_state(u_int); static void showstats(friostat_t *); static void packetlogon(char *); static void swapactive(void); static int opendevice(char *, int); static void closedevice(void); static char *ipfname = IPL_NAME; static void usage(void); static int showversion(void); static int get_flags(void); static int ipf_interceptadd(int, ioctlfunc_t, void *); static int fd = -1; static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ioctl, ioctl, ioctl, ioctl, ioctl, ioctl, ioctl, ioctl }; /* XXX The following was added to satisfy a rescue/rescue/ build XXX requirement. */ int nohdrfields; static void usage() { fprintf(stderr, "usage: ipf [-6AdDEInoPrRsvVyzZ] %s %s %s\n", "[-l block|pass|nomatch|state|nat]", "[-cc] [-F i|o|a|s|S|u]", "[-f filename] [-T ]"); exit(1); } -int main(argc,argv) - int argc; - char *argv[]; +int +main(int argc, char *argv[]) { int c, *filter = NULL; if (argc < 2) usage(); assigndefined(getenv("IPF_PREDEFINED")); while ((c = getopt(argc, argv, "46Ac:dDEf:F:Il:m:noPrRsT:vVyzZ")) != -1) { switch (c) { case '?' : usage(); break; case '4' : use_inet6 = -1; break; case '6' : use_inet6 = 1; break; case 'A' : opts &= ~OPT_INACTIVE; break; case 'c' : if (strcmp(optarg, "c") == 0) outputc = 1; break; case 'E' : set_state((u_int)1); break; case 'D' : set_state((u_int)0); break; case 'd' : opts ^= OPT_DEBUG; break; case 'f' : procfile(optarg); break; case 'F' : flushfilter(optarg, filter); break; case 'I' : opts ^= OPT_INACTIVE; break; case 'l' : packetlogon(optarg); break; case 'm' : filter = parseipfexpr(optarg, NULL); break; case 'n' : opts ^= OPT_DONOTHING|OPT_DONTOPEN; break; case 'o' : break; case 'P' : ipfname = IPAUTH_NAME; break; case 'R' : opts ^= OPT_NORESOLVE; break; case 'r' : opts ^= OPT_REMOVE; break; case 's' : swapactive(); break; case 'T' : if (opendevice(ipfname, 1) >= 0) ipf_dotuning(fd, optarg, ioctl); break; case 'v' : opts += OPT_VERBOSE; break; case 'V' : if (showversion()) exit(1); break; case 'y' : ipf_frsync(); break; case 'z' : opts ^= OPT_ZERORULEST; break; case 'Z' : zerostats(); break; } } if (optind < 2) usage(); if (fd != -1) (void) close(fd); return(exitstatus); /* NOTREACHED */ } -static int opendevice(ipfdev, check) - char *ipfdev; - int check; +static int +opendevice(char *ipfdev, int check) { if (opts & OPT_DONOTHING) return -2; if (check && checkrev(ipfname) == -1) { fprintf(stderr, "User/kernel version check failed\n"); return -2; } if (!ipfdev) ipfdev = ipfname; if (fd == -1) if ((fd = open(ipfdev, O_RDWR)) == -1) if ((fd = open(ipfdev, O_RDONLY)) == -1) ipferror(fd, "open device"); return fd; } -static void closedevice() +static void +closedevice(void) { close(fd); fd = -1; } -static int get_flags() +static int +get_flags(void) { int i = 0; if ((opendevice(ipfname, 1) != -2) && (ioctl(fd, SIOCGETFF, &i) == -1)) { ipferror(fd, "SIOCGETFF"); return 0; } return i; } -static void set_state(enable) - u_int enable; +static void +set_state(u_int enable) { if (opendevice(ipfname, 0) != -2) { if (ioctl(fd, SIOCFRENB, &enable) == -1) { if (errno == EBUSY) { fprintf(stderr, "IP FIlter: already initialized\n"); } else { ipferror(fd, "SIOCFRENB"); } } } return; } -static void procfile(file) - char *file; +static void +procfile(char *file) { (void) opendevice(ipfname, 1); initparse(); ipf_parsefile(fd, ipf_interceptadd, iocfunctions, file); if (outputc) { printC(0); printC(1); emit(-1, -1, NULL, NULL); } } -static int ipf_interceptadd(fd, ioctlfunc, ptr) - int fd; - ioctlfunc_t ioctlfunc; - void *ptr; +static int +ipf_interceptadd(int fd, ioctlfunc_t ioctlfunc, void *ptr) { if (outputc) printc(ptr); if (ipf_addrule(fd, ioctlfunc, ptr) != 0) exitstatus = 1; return 0; } -static void packetlogon(opt) - char *opt; +static void +packetlogon(char *opt) { int flag, xfd, logopt, change = 0; flag = get_flags(); if (flag != 0) { if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) printf("log flag is currently %#x\n", flag); } flag &= ~(FF_LOGPASS|FF_LOGNOMATCH|FF_LOGBLOCK); if (strstr(opt, "pass")) { flag |= FF_LOGPASS; if (opts & OPT_VERBOSE) printf("set log flag: pass\n"); change = 1; } if (strstr(opt, "nomatch")) { flag |= FF_LOGNOMATCH; if (opts & OPT_VERBOSE) printf("set log flag: nomatch\n"); change = 1; } if (strstr(opt, "block") || strchr(opt, 'd')) { flag |= FF_LOGBLOCK; if (opts & OPT_VERBOSE) printf("set log flag: block\n"); change = 1; } if (strstr(opt, "none")) { if (opts & OPT_VERBOSE) printf("disable all log flags\n"); change = 1; } if (change == 1) { if (opendevice(ipfname, 1) != -2 && (ioctl(fd, SIOCSETFF, &flag) != 0)) ipferror(fd, "ioctl(SIOCSETFF)"); } if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { flag = get_flags(); printf("log flags are now %#x\n", flag); } if (strstr(opt, "state")) { if (opts & OPT_VERBOSE) printf("set state log flag\n"); xfd = open(IPSTATE_NAME, O_RDWR); if (xfd >= 0) { logopt = 0; if (ioctl(xfd, SIOCGETLG, &logopt)) ipferror(fd, "ioctl(SIOCGETLG)"); else { logopt = 1 - logopt; if (ioctl(xfd, SIOCSETLG, &logopt)) ipferror(xfd, "ioctl(SIOCSETLG)"); } close(xfd); } } if (strstr(opt, "nat")) { if (opts & OPT_VERBOSE) printf("set nat log flag\n"); xfd = open(IPNAT_NAME, O_RDWR); if (xfd >= 0) { logopt = 0; if (ioctl(xfd, SIOCGETLG, &logopt)) ipferror(xfd, "ioctl(SIOCGETLG)"); else { logopt = 1 - logopt; if (ioctl(xfd, SIOCSETLG, &logopt)) ipferror(xfd, "ioctl(SIOCSETLG)"); } close(xfd); } } } -static void flushfilter(arg, filter) - char *arg; - int *filter; +static void +flushfilter(char *arg, int *filter) { int fl = 0, rem; if (!arg || !*arg) return; if (!strcmp(arg, "s") || !strcmp(arg, "S") || ISDIGIT(*arg)) { if (*arg == 'S') fl = 0; else if (*arg == 's') fl = 1; else fl = atoi(arg); rem = fl; closedevice(); if (opendevice(IPSTATE_NAME, 1) == -2) exit(1); if (!(opts & OPT_DONOTHING)) { if (use_inet6) { fprintf(stderr, "IPv6 rules are no longer seperate\n"); } else if (filter != NULL) { ipfobj_t obj; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_size = filter[0] * sizeof(int); obj.ipfo_type = IPFOBJ_IPFEXPR; obj.ipfo_ptr = filter; if (ioctl(fd, SIOCMATCHFLUSH, &obj) == -1) { ipferror(fd, "ioctl(SIOCMATCHFLUSH)"); fl = -1; } else { fl = obj.ipfo_retval; } } else { if (ioctl(fd, SIOCIPFFL, &fl) == -1) { ipferror(fd, "ioctl(SIOCIPFFL)"); exit(1); } } } if ((opts & (OPT_DONOTHING|OPT_DEBUG)) == OPT_DEBUG) { printf("remove flags %s (%d)\n", arg, rem); } if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { printf("%d state entries removed\n", fl); } closedevice(); return; } else if (strchr(arg, 'i') || strchr(arg, 'I')) fl = FR_INQUE; else if (strchr(arg, 'o') || strchr(arg, 'O')) fl = FR_OUTQUE; else if (strchr(arg, 'a') || strchr(arg, 'A')) fl = FR_OUTQUE|FR_INQUE; else { fprintf(stderr, "Incorrect flush argument: %s\n", arg); usage(); } if (opts & OPT_INACTIVE) fl |= FR_INACTIVE; rem = fl; if (opendevice(ipfname, 1) == -2) exit(1); if (!(opts & OPT_DONOTHING)) { if (use_inet6) { if (ioctl(fd, SIOCIPFL6, &fl) == -1) { ipferror(fd, "ioctl(SIOCIPFL6)"); exit(1); } } else { if (ioctl(fd, SIOCIPFFL, &fl) == -1) { ipferror(fd, "ioctl(SIOCIPFFL)"); exit(1); } } } if ((opts & (OPT_DONOTHING|OPT_DEBUG)) == OPT_DEBUG) { printf("remove flags %s%s (%d)\n", (rem & FR_INQUE) ? "I" : "", (rem & FR_OUTQUE) ? "O" : "", rem); } if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { printf("%d filter rules removed\n", fl); } return; } -static void swapactive() +static void +swapactive(void) { int in = 2; if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCSWAPA, &in) == -1) ipferror(fd, "ioctl(SIOCSWAPA)"); else printf("Set %d now inactive\n", in); } -void ipf_frsync() +void +ipf_frsync(void) { int frsyn = 0; if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCFRSYN, &frsyn) == -1) ipferror(fd, "SIOCFRSYN"); else printf("filter sync'd\n"); } -void zerostats() +void +zerostats(void) { ipfobj_t obj; friostat_t fio; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_IPFSTAT; obj.ipfo_size = sizeof(fio); obj.ipfo_ptr = &fio; obj.ipfo_offset = 0; if (opendevice(ipfname, 1) != -2) { if (ioctl(fd, SIOCFRZST, &obj) == -1) { ipferror(fd, "ioctl(SIOCFRZST)"); exit(-1); } showstats(&fio); } } /* * read the kernel stats for packets blocked and passed */ -static void showstats(fp) - friostat_t *fp; +static void +showstats(friostat_t *fp) { printf("bad packets:\t\tin %lu\tout %lu\n", fp->f_st[0].fr_bad, fp->f_st[1].fr_bad); printf(" input packets:\t\tblocked %lu passed %lu nomatch %lu", fp->f_st[0].fr_block, fp->f_st[0].fr_pass, fp->f_st[0].fr_nom); printf(" counted %lu\n", fp->f_st[0].fr_acct); printf("output packets:\t\tblocked %lu passed %lu nomatch %lu", fp->f_st[1].fr_block, fp->f_st[1].fr_pass, fp->f_st[1].fr_nom); printf(" counted %lu\n", fp->f_st[0].fr_acct); printf(" input packets logged:\tblocked %lu passed %lu\n", fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl); printf("output packets logged:\tblocked %lu passed %lu\n", fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl); } -static int showversion() +static int +showversion(void) { struct friostat fio; ipfobj_t ipfo; u_32_t flags; char *s; int vfd; bzero((caddr_t)&ipfo, sizeof(ipfo)); ipfo.ipfo_rev = IPFILTER_VERSION; ipfo.ipfo_size = sizeof(fio); ipfo.ipfo_ptr = (void *)&fio; ipfo.ipfo_type = IPFOBJ_IPFSTAT; printf("ipf: %s (%d)\n", IPL_VERSION, (int)sizeof(frentry_t)); if ((vfd = open(ipfname, O_RDONLY)) == -1) { perror("open device"); return 1; } if (ioctl(vfd, SIOCGETFS, &ipfo)) { ipferror(vfd, "ioctl(SIOCGETFS)"); close(vfd); return 1; } close(vfd); flags = get_flags(); printf("Kernel: %-*.*s\n", (int)sizeof(fio.f_version), (int)sizeof(fio.f_version), fio.f_version); printf("Running: %s\n", (fio.f_running > 0) ? "yes" : "no"); printf("Log Flags: %#x = ", flags); s = ""; if (flags & FF_LOGPASS) { printf("pass"); s = ", "; } if (flags & FF_LOGBLOCK) { printf("%sblock", s); s = ", "; } if (flags & FF_LOGNOMATCH) { printf("%snomatch", s); s = ", "; } if (flags & FF_BLOCKNONIP) { printf("%snonip", s); s = ", "; } if (!*s) printf("none set"); putchar('\n'); printf("Default: "); if (FR_ISPASS(fio.f_defpass)) s = "pass"; else if (FR_ISBLOCK(fio.f_defpass)) s = "block"; else s = "nomatch -> block"; printf("%s all, Logging: %savailable\n", s, fio.f_logging ? "" : "un"); printf("Active list: %d\n", fio.f_active); printf("Feature mask: %#x\n", fio.f_features); return 0; } diff --git a/sbin/ipf/ipf/ipfcomp.c b/sbin/ipf/ipf/ipfcomp.c index 5bbb35c610fa..105ff2b852e8 100644 --- a/sbin/ipf/ipf/ipfcomp.c +++ b/sbin/ipf/ipf/ipfcomp.c @@ -1,1372 +1,1355 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include "ipf.h" typedef struct { int c; int e; int n; int p; int s; } mc_t; static char *portcmp[] = { "*", "==", "!=", "<", ">", "<=", ">=", "**", "***" }; static int count = 0; int intcmp(const void *, const void *); static void indent(FILE *, int); static void printeq(FILE *, char *, int, int, int); static void printipeq(FILE *, char *, int, int, int); static void addrule(FILE *, frentry_t *); static void printhooks(FILE *, int, int, frgroup_t *); static void emitheader(frgroup_t *, u_int, u_int); static void emitGroup(int, int, void *, frentry_t *, char *, u_int, u_int); static void emittail(void); static void printCgroup(int, frentry_t *, mc_t *, char *); #define FRC_IFN 0 #define FRC_V 1 #define FRC_P 2 #define FRC_FL 3 #define FRC_TOS 4 #define FRC_TTL 5 #define FRC_SRC 6 #define FRC_DST 7 #define FRC_TCP 8 #define FRC_SP 9 #define FRC_DP 10 #define FRC_OPT 11 #define FRC_SEC 12 #define FRC_ATH 13 #define FRC_ICT 14 #define FRC_ICC 15 #define FRC_MAX 16 static FILE *cfile = NULL; /* * This is called once per filter rule being loaded to emit data structures * required. */ -void printc(fr) - frentry_t *fr; +void +printc(frentry_t *fr) { u_long *ulp; char *and; FILE *fp; int i; if (fr->fr_family == 6) return; if ((fr->fr_type != FR_T_IPF) && (fr->fr_type != FR_T_NONE)) return; if ((fr->fr_type == FR_T_IPF) && ((fr->fr_datype != FRI_NORMAL) || (fr->fr_satype != FRI_NORMAL))) return; if (cfile == NULL) cfile = fopen("ip_rules.c", "w"); if (cfile == NULL) return; fp = cfile; if (count == 0) { fprintf(fp, "/*\n"); fprintf(fp, "* Copyright (C) 2012 by Darren Reed.\n"); fprintf(fp, "*\n"); fprintf(fp, "* Redistribution and use in source and binary forms are permitted\n"); fprintf(fp, "* provided that this notice is preserved and due credit is given\n"); fprintf(fp, "* to the original author and the contributors.\n"); fprintf(fp, "*/\n\n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#if (__FreeBSD_version >= 40000)\n"); fprintf(fp, "# if defined(_KERNEL)\n"); fprintf(fp, "# include \n"); fprintf(fp, "# else\n"); fprintf(fp, "# include \n"); fprintf(fp, "# endif\n"); fprintf(fp, "#endif\n"); fprintf(fp, "#if (__NetBSD_Version__ >= 399000000)\n"); fprintf(fp, "#else\n"); fprintf(fp, "# if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__sgi)\n"); fprintf(fp, "# include \n"); fprintf(fp, "# endif\n"); fprintf(fp, "#endif\n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux)\n"); fprintf(fp, "# include \n"); fprintf(fp, "#endif\n"); fprintf(fp, "#if defined(__FreeBSD__) && (__FreeBSD_version > 220000)\n"); fprintf(fp, "# include \n"); fprintf(fp, "#else\n"); fprintf(fp, "# include \n"); fprintf(fp, "#endif /* FreeBSD */\n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \"netinet/ip_compat.h\"\n"); fprintf(fp, "#include \"netinet/ip_fil.h\"\n\n"); fprintf(fp, "#include \"netinet/ip_rules.h\"\n\n"); fprintf(fp, "#ifndef _KERNEL\n"); fprintf(fp, "# include \n"); fprintf(fp, "#endif /* _KERNEL */\n"); fprintf(fp, "\n"); fprintf(fp, "#ifdef IPFILTER_COMPILED\n"); fprintf(fp, "\n"); fprintf(fp, "extern ipf_main_softc_t ipfmain;\n"); fprintf(fp, "\n"); } addrule(fp, fr); fr->fr_type |= FR_T_BUILTIN; and = ""; fr->fr_ref = 1; i = sizeof(*fr); if (i & -(1 - sizeof(*ulp))) i += sizeof(u_long); for (i /= sizeof(u_long), ulp = (u_long *)fr; i > 0; i--) { fprintf(fp, "%s%#lx", and, *ulp++); and = ", "; } fprintf(fp, "\n};\n"); fr->fr_type &= ~FR_T_BUILTIN; count++; fflush(fp); } static frgroup_t *groups = NULL; -static void addrule(fp, fr) - FILE *fp; - frentry_t *fr; +static void +addrule(FILE *fp, frentry_t *fr) { frentry_t *f, **fpp; frgroup_t *g; u_long *ulp; char *ghead; char *gname; char *and; int i; f = (frentry_t *)malloc(sizeof(*f)); bcopy((char *)fr, (char *)f, sizeof(*fr)); if (fr->fr_ipf) { f->fr_ipf = (fripf_t *)malloc(sizeof(*f->fr_ipf)); bcopy((char *)fr->fr_ipf, (char *)f->fr_ipf, sizeof(*fr->fr_ipf)); } f->fr_next = NULL; gname = FR_NAME(fr, fr_group); for (g = groups; g != NULL; g = g->fg_next) if ((strncmp(g->fg_name, gname, FR_GROUPLEN) == 0) && (g->fg_flags == (f->fr_flags & FR_INOUT))) break; if (g == NULL) { g = (frgroup_t *)calloc(1, sizeof(*g)); g->fg_next = groups; groups = g; g->fg_head = f; strncpy(g->fg_name, gname, FR_GROUPLEN); g->fg_ref = 0; g->fg_flags = f->fr_flags & FR_INOUT; } for (fpp = &g->fg_start; *fpp != NULL; ) fpp = &((*fpp)->fr_next); *fpp = f; if (fr->fr_dsize > 0) { fprintf(fp, "\ static u_long ipf%s_rule_data_%s_%u[] = {\n", f->fr_flags & FR_INQUE ? "in" : "out", g->fg_name, g->fg_ref); and = ""; i = fr->fr_dsize; ulp = fr->fr_data; for (i /= sizeof(u_long); i > 0; i--) { fprintf(fp, "%s%#lx", and, *ulp++); and = ", "; } fprintf(fp, "\n};\n"); } fprintf(fp, "\nstatic u_long %s_rule_%s_%d[] = {\n", f->fr_flags & FR_INQUE ? "in" : "out", g->fg_name, g->fg_ref); g->fg_ref++; if (f->fr_grhead != -1) { ghead = FR_NAME(f, fr_grhead); for (g = groups; g != NULL; g = g->fg_next) if ((strncmp(g->fg_name, ghead, FR_GROUPLEN) == 0) && g->fg_flags == (f->fr_flags & FR_INOUT)) break; if (g == NULL) { g = (frgroup_t *)calloc(1, sizeof(*g)); g->fg_next = groups; groups = g; g->fg_head = f; strncpy(g->fg_name, ghead, FR_GROUPLEN); g->fg_ref = 0; g->fg_flags = f->fr_flags & FR_INOUT; } } } -int intcmp(c1, c2) - const void *c1, *c2; +int +intcmp(const void *c1, const void *c2) { const mc_t *i1 = (const mc_t *)c1, *i2 = (const mc_t *)c2; if (i1->n == i2->n) { return i1->c - i2->c; } return i2->n - i1->n; } -static void indent(fp, in) - FILE *fp; - int in; +static void +indent(FILE *fp, int in) { for (; in; in--) fputc('\t', fp); } -static void printeq(fp, var, m, max, v) - FILE *fp; - char *var; - int m, max, v; +static void +printeq(FILE *fp, char *var, int m, int max, int v) { if (m == max) fprintf(fp, "%s == %#x) {\n", var, v); else fprintf(fp, "(%s & %#x) == %#x) {\n", var, m, v); } /* * Parameters: var - IP# being compared * fl - 0 for positive match, 1 for negative match * m - netmask * v - required address */ -static void printipeq(fp, var, fl, m, v) - FILE *fp; - char *var; - int fl, m, v; +static void +printipeq(FILE *fp, char *var, int fl, int m, int v) { if (m == 0xffffffff) fprintf(fp, "%s ", var); else fprintf(fp, "(%s & %#x) ", var, m); fprintf(fp, "%c", fl ? '!' : '='); fprintf(fp, "= %#x) {\n", v); } -void emit(num, dir, v, fr) - int num, dir; - void *v; - frentry_t *fr; +void +emit(int num, int dir, void *v, frentry_t *fr) { u_int incnt, outcnt; frgroup_t *g; frentry_t *f; for (g = groups; g != NULL; g = g->fg_next) { if (dir == 0 || dir == -1) { if ((g->fg_flags & FR_INQUE) == 0) continue; for (incnt = 0, f = g->fg_start; f != NULL; f = f->fr_next) incnt++; emitGroup(num, dir, v, fr, g->fg_name, incnt, 0); } if (dir == 1 || dir == -1) { if ((g->fg_flags & FR_OUTQUE) == 0) continue; for (outcnt = 0, f = g->fg_start; f != NULL; f = f->fr_next) outcnt++; emitGroup(num, dir, v, fr, g->fg_name, 0, outcnt); } } if (num == -1 && dir == -1) { for (g = groups; g != NULL; g = g->fg_next) { if ((g->fg_flags & FR_INQUE) != 0) { for (incnt = 0, f = g->fg_start; f != NULL; f = f->fr_next) incnt++; if (incnt > 0) emitheader(g, incnt, 0); } if ((g->fg_flags & FR_OUTQUE) != 0) { for (outcnt = 0, f = g->fg_start; f != NULL; f = f->fr_next) outcnt++; if (outcnt > 0) emitheader(g, 0, outcnt); } } emittail(); fprintf(cfile, "#endif /* IPFILTER_COMPILED */\n"); } } -static void emitheader(grp, incount, outcount) - frgroup_t *grp; - u_int incount, outcount; +static void +emitheader(frgroup_t *grp, u_int incount, u_int outcount) { static FILE *fph = NULL; frgroup_t *g; if (fph == NULL) { fph = fopen("ip_rules.h", "w"); if (fph == NULL) return; fprintf(fph, "extern int ipfrule_add(void));\n"); fprintf(fph, "extern int ipfrule_remove(void));\n"); } printhooks(cfile, incount, outcount, grp); if (incount) { fprintf(fph, "\n\ extern frentry_t *ipfrule_match_in_%s(fr_info_t *, u_32_t *));\n\ extern frentry_t *ipf_rules_in_%s[%d];\n", grp->fg_name, grp->fg_name, incount); for (g = groups; g != grp; g = g->fg_next) if ((strncmp(g->fg_name, grp->fg_name, FR_GROUPLEN) == 0) && g->fg_flags == grp->fg_flags) break; if (g == grp) { fprintf(fph, "\n\ extern int ipfrule_add_in_%s(void));\n\ extern int ipfrule_remove_in_%s(void));\n", grp->fg_name, grp->fg_name); } } if (outcount) { fprintf(fph, "\n\ extern frentry_t *ipfrule_match_out_%s(fr_info_t *, u_32_t *));\n\ extern frentry_t *ipf_rules_out_%s[%d];\n", grp->fg_name, grp->fg_name, outcount); for (g = groups; g != grp; g = g->fg_next) if ((strncmp(g->fg_name, grp->fg_name, FR_GROUPLEN) == 0) && g->fg_flags == grp->fg_flags) break; if (g == grp) { fprintf(fph, "\n\ extern int ipfrule_add_out_%s(void));\n\ extern int ipfrule_remove_out_%s(void));\n", grp->fg_name, grp->fg_name); } } } -static void emittail() +static void +emittail(void) { frgroup_t *g; fprintf(cfile, "\n\ int ipfrule_add()\n\ {\n\ int err;\n\ \n"); for (g = groups; g != NULL; g = g->fg_next) fprintf(cfile, "\ err = ipfrule_add_%s_%s();\n\ if (err != 0)\n\ return err;\n", (g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name); fprintf(cfile, "\ return 0;\n"); fprintf(cfile, "}\n\ \n"); fprintf(cfile, "\n\ int ipfrule_remove()\n\ {\n\ int err;\n\ \n"); for (g = groups; g != NULL; g = g->fg_next) fprintf(cfile, "\ err = ipfrule_remove_%s_%s();\n\ if (err != 0)\n\ return err;\n", (g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name); fprintf(cfile, "\ return 0;\n"); fprintf(cfile, "}\n"); } -static void emitGroup(num, dir, v, fr, group, incount, outcount) - int num, dir; - void *v; - frentry_t *fr; - char *group; - u_int incount, outcount; +static void +emitGroup(int num, int dir, void *v, frentry_t *fr, char *group, + u_int incount, u_int outcount) { static FILE *fp = NULL; static int header[2] = { 0, 0 }; static char egroup[FR_GROUPLEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; static int openfunc = 0; static mc_t *n = NULL; static int sin = 0; frentry_t *f; frgroup_t *g; fripf_t *ipf; int i, in, j; mc_t *m = v; if (fp == NULL) fp = cfile; if (fp == NULL) return; if (strncmp(egroup, group, FR_GROUPLEN)) { for (sin--; sin > 0; sin--) { indent(fp, sin); fprintf(fp, "}\n"); } if (openfunc == 1) { fprintf(fp, "\treturn fr;\n}\n"); openfunc = 0; if (n != NULL) { free(n); n = NULL; } } sin = 0; header[0] = 0; header[1] = 0; strncpy(egroup, group, FR_GROUPLEN); } else if (openfunc == 1 && num < 0) { if (n != NULL) { free(n); n = NULL; } for (sin--; sin > 0; sin--) { indent(fp, sin); fprintf(fp, "}\n"); } if (openfunc == 1) { fprintf(fp, "\treturn fr;\n}\n"); openfunc = 0; } } if (dir == -1) return; for (g = groups; g != NULL; g = g->fg_next) { if (dir == 0 && (g->fg_flags & FR_INQUE) == 0) continue; else if (dir == 1 && (g->fg_flags & FR_OUTQUE) == 0) continue; if (strncmp(g->fg_name, group, FR_GROUPLEN) != 0) continue; break; } /* * Output the array of pointers to rules for this group. */ if (g != NULL && num == -2 && dir == 0 && header[0] == 0 && incount != 0) { fprintf(fp, "\nfrentry_t *ipf_rules_in_%s[%d] = {", group, incount); for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { if ((f->fr_flags & FR_INQUE) == 0) continue; if ((i & 1) == 0) { fprintf(fp, "\n\t"); } fprintf(fp, "(frentry_t *)&in_rule_%s_%d", FR_NAME(f, fr_group), i); if (i + 1 < incount) fprintf(fp, ", "); i++; } fprintf(fp, "\n};\n"); } if (g != NULL && num == -2 && dir == 1 && header[0] == 0 && outcount != 0) { fprintf(fp, "\nfrentry_t *ipf_rules_out_%s[%d] = {", group, outcount); for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { if ((f->fr_flags & FR_OUTQUE) == 0) continue; if ((i & 1) == 0) { fprintf(fp, "\n\t"); } fprintf(fp, "(frentry_t *)&out_rule_%s_%d", FR_NAME(f, fr_group), i); if (i + 1 < outcount) fprintf(fp, ", "); i++; } fprintf(fp, "\n};\n"); fp = NULL; } if (num < 0) return; in = 0; ipf = fr->fr_ipf; /* * If the function header has not been printed then print it now. */ if (g != NULL && header[dir] == 0) { int pdst = 0, psrc = 0; openfunc = 1; fprintf(fp, "\nfrentry_t *ipfrule_match_%s_%s(fin, passp)\n", (dir == 0) ? "in" : "out", group); fprintf(fp, "fr_info_t *fin;\n"); fprintf(fp, "u_32_t *passp;\n"); fprintf(fp, "{\n"); fprintf(fp, "\tfrentry_t *fr = NULL;\n"); /* * Print out any variables that need to be declared. */ for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { if (incount + outcount > m[FRC_SRC].e + 1) psrc = 1; if (incount + outcount > m[FRC_DST].e + 1) pdst = 1; } if (psrc == 1) fprintf(fp, "\tu_32_t src = ntohl(%s);\n", "fin->fin_fi.fi_saddr"); if (pdst == 1) fprintf(fp, "\tu_32_t dst = ntohl(%s);\n", "fin->fin_fi.fi_daddr"); } for (i = 0; i < FRC_MAX; i++) { switch(m[i].c) { case FRC_IFN : if (fr->fr_ifnames[0] != -1) m[i].s = 1; break; case FRC_V : if (ipf != NULL && ipf->fri_mip.fi_v != 0) m[i].s = 1; break; case FRC_FL : if (ipf != NULL && ipf->fri_mip.fi_flx != 0) m[i].s = 1; break; case FRC_P : if (ipf != NULL && ipf->fri_mip.fi_p != 0) m[i].s = 1; break; case FRC_TTL : if (ipf != NULL && ipf->fri_mip.fi_ttl != 0) m[i].s = 1; break; case FRC_TOS : if (ipf != NULL && ipf->fri_mip.fi_tos != 0) m[i].s = 1; break; case FRC_TCP : if (ipf == NULL) break; if ((ipf->fri_ip.fi_p == IPPROTO_TCP) && fr->fr_tcpfm != 0) m[i].s = 1; break; case FRC_SP : if (ipf == NULL) break; if (fr->fr_scmp == FR_INRANGE) m[i].s = 1; else if (fr->fr_scmp == FR_OUTRANGE) m[i].s = 1; else if (fr->fr_scmp != 0) m[i].s = 1; break; case FRC_DP : if (ipf == NULL) break; if (fr->fr_dcmp == FR_INRANGE) m[i].s = 1; else if (fr->fr_dcmp == FR_OUTRANGE) m[i].s = 1; else if (fr->fr_dcmp != 0) m[i].s = 1; break; case FRC_SRC : if (ipf == NULL) break; if (fr->fr_satype == FRI_LOOKUP) { ; } else if ((fr->fr_smask != 0) || (fr->fr_flags & FR_NOTSRCIP) != 0) m[i].s = 1; break; case FRC_DST : if (ipf == NULL) break; if (fr->fr_datype == FRI_LOOKUP) { ; } else if ((fr->fr_dmask != 0) || (fr->fr_flags & FR_NOTDSTIP) != 0) m[i].s = 1; break; case FRC_OPT : if (ipf == NULL) break; if (fr->fr_optmask != 0) m[i].s = 1; break; case FRC_SEC : if (ipf == NULL) break; if (fr->fr_secmask != 0) m[i].s = 1; break; case FRC_ATH : if (ipf == NULL) break; if (fr->fr_authmask != 0) m[i].s = 1; break; case FRC_ICT : if (ipf == NULL) break; if ((fr->fr_icmpm & 0xff00) != 0) m[i].s = 1; break; case FRC_ICC : if (ipf == NULL) break; if ((fr->fr_icmpm & 0xff) != 0) m[i].s = 1; break; } } if (!header[dir]) { fprintf(fp, "\n"); header[dir] = 1; sin = 0; } qsort(m, FRC_MAX, sizeof(mc_t), intcmp); if (n) { /* * Calculate the indentation interval upto the last common * common comparison being made. */ for (i = 0, in = 1; i < FRC_MAX; i++) { if (n[i].c != m[i].c) break; if (n[i].s != m[i].s) break; if (n[i].s) { if (n[i].n && (n[i].n > n[i].e)) { m[i].p++; in += m[i].p; break; } if (n[i].e > 0) { in++; } else break; } } if (sin != in) { for (j = sin - 1; j >= in; j--) { indent(fp, j); fprintf(fp, "}\n"); } } } else { in = 1; i = 0; } /* * print out C code that implements a filter rule. */ for (; i < FRC_MAX; i++) { switch(m[i].c) { case FRC_IFN : if (m[i].s) { indent(fp, in); fprintf(fp, "if (fin->fin_ifp == "); fprintf(fp, "ipf_rules_%s_%s[%d]->fr_ifa) {\n", dir ? "out" : "in", group, num); in++; } break; case FRC_V : if (m[i].s) { indent(fp, in); fprintf(fp, "if (fin->fin_v == %d) {\n", ipf->fri_ip.fi_v); in++; } break; case FRC_FL : if (m[i].s) { indent(fp, in); fprintf(fp, "if ("); printeq(fp, "fin->fin_flx", ipf->fri_mip.fi_flx, 0xf, ipf->fri_ip.fi_flx); in++; } break; case FRC_P : if (m[i].s) { indent(fp, in); fprintf(fp, "if (fin->fin_p == %d) {\n", ipf->fri_ip.fi_p); in++; } break; case FRC_TTL : if (m[i].s) { indent(fp, in); fprintf(fp, "if ("); printeq(fp, "fin->fin_ttl", ipf->fri_mip.fi_ttl, 0xff, ipf->fri_ip.fi_ttl); in++; } break; case FRC_TOS : if (m[i].s) { indent(fp, in); fprintf(fp, "if (fin->fin_tos"); printeq(fp, "fin->fin_tos", ipf->fri_mip.fi_tos, 0xff, ipf->fri_ip.fi_tos); in++; } break; case FRC_TCP : if (m[i].s) { indent(fp, in); fprintf(fp, "if ("); printeq(fp, "fin->fin_tcpf", fr->fr_tcpfm, 0xff, fr->fr_tcpf); in++; } break; case FRC_SP : if (!m[i].s) break; if (fr->fr_scmp == FR_INRANGE) { indent(fp, in); fprintf(fp, "if ((fin->fin_data[0] > %d) && ", fr->fr_sport); fprintf(fp, "(fin->fin_data[0] < %d)", fr->fr_stop); fprintf(fp, ") {\n"); in++; } else if (fr->fr_scmp == FR_OUTRANGE) { indent(fp, in); fprintf(fp, "if ((fin->fin_data[0] < %d) || ", fr->fr_sport); fprintf(fp, "(fin->fin_data[0] > %d)", fr->fr_stop); fprintf(fp, ") {\n"); in++; } else if (fr->fr_scmp) { indent(fp, in); fprintf(fp, "if (fin->fin_data[0] %s %d)", portcmp[fr->fr_scmp], fr->fr_sport); fprintf(fp, " {\n"); in++; } break; case FRC_DP : if (!m[i].s) break; if (fr->fr_dcmp == FR_INRANGE) { indent(fp, in); fprintf(fp, "if ((fin->fin_data[1] > %d) && ", fr->fr_dport); fprintf(fp, "(fin->fin_data[1] < %d)", fr->fr_dtop); fprintf(fp, ") {\n"); in++; } else if (fr->fr_dcmp == FR_OUTRANGE) { indent(fp, in); fprintf(fp, "if ((fin->fin_data[1] < %d) || ", fr->fr_dport); fprintf(fp, "(fin->fin_data[1] > %d)", fr->fr_dtop); fprintf(fp, ") {\n"); in++; } else if (fr->fr_dcmp) { indent(fp, in); fprintf(fp, "if (fin->fin_data[1] %s %d)", portcmp[fr->fr_dcmp], fr->fr_dport); fprintf(fp, " {\n"); in++; } break; case FRC_SRC : if (!m[i].s) break; if (fr->fr_satype == FRI_LOOKUP) { ; } else if ((fr->fr_smask != 0) || (fr->fr_flags & FR_NOTSRCIP) != 0) { indent(fp, in); fprintf(fp, "if ("); printipeq(fp, "src", fr->fr_flags & FR_NOTSRCIP, fr->fr_smask, fr->fr_saddr); in++; } break; case FRC_DST : if (!m[i].s) break; if (fr->fr_datype == FRI_LOOKUP) { ; } else if ((fr->fr_dmask != 0) || (fr->fr_flags & FR_NOTDSTIP) != 0) { indent(fp, in); fprintf(fp, "if ("); printipeq(fp, "dst", fr->fr_flags & FR_NOTDSTIP, fr->fr_dmask, fr->fr_daddr); in++; } break; case FRC_OPT : if (m[i].s) { indent(fp, in); fprintf(fp, "if ("); printeq(fp, "fin->fin_fi.fi_optmsk", fr->fr_optmask, 0xffffffff, fr->fr_optbits); in++; } break; case FRC_SEC : if (m[i].s) { indent(fp, in); fprintf(fp, "if ("); printeq(fp, "fin->fin_fi.fi_secmsk", fr->fr_secmask, 0xffff, fr->fr_secbits); in++; } break; case FRC_ATH : if (m[i].s) { indent(fp, in); fprintf(fp, "if ("); printeq(fp, "fin->fin_fi.fi_authmsk", fr->fr_authmask, 0xffff, fr->fr_authbits); in++; } break; case FRC_ICT : if (m[i].s) { indent(fp, in); fprintf(fp, "if ("); printeq(fp, "fin->fin_data[0]", fr->fr_icmpm & 0xff00, 0xffff, fr->fr_icmp & 0xff00); in++; } break; case FRC_ICC : if (m[i].s) { indent(fp, in); fprintf(fp, "if ("); printeq(fp, "fin->fin_data[0]", fr->fr_icmpm & 0xff, 0xffff, fr->fr_icmp & 0xff); in++; } break; } } indent(fp, in); if (fr->fr_flags & FR_QUICK) { fprintf(fp, "return (frentry_t *)&%s_rule_%s_%d;\n", fr->fr_flags & FR_INQUE ? "in" : "out", FR_NAME(fr, fr_group), num); } else { fprintf(fp, "fr = (frentry_t *)&%s_rule_%s_%d;\n", fr->fr_flags & FR_INQUE ? "in" : "out", FR_NAME(fr, fr_group), num); } if (n == NULL) n = (mc_t *)malloc(sizeof(*n) * FRC_MAX); bcopy((char *)m, (char *)n, sizeof(*n) * FRC_MAX); sin = in; } -void printC(dir) - int dir; +void +printC(int dir) { static mc_t *m = NULL; frgroup_t *g; if (m == NULL) m = (mc_t *)calloc(FRC_MAX, sizeof(*m)); for (g = groups; g != NULL; g = g->fg_next) { if ((dir == 0) && ((g->fg_flags & FR_INQUE) != 0)) printCgroup(dir, g->fg_start, m, g->fg_name); if ((dir == 1) && ((g->fg_flags & FR_OUTQUE) != 0)) printCgroup(dir, g->fg_start, m, g->fg_name); } emit(-1, dir, m, NULL); } /* * Now print out code to implement all of the rules. */ -static void printCgroup(dir, top, m, group) - int dir; - frentry_t *top; - mc_t *m; - char *group; +static void +printCgroup(int dir, frentry_t *top, mc_t *m, char *group) { frentry_t *fr, *fr1; int i, n, rn; u_int count; for (count = 0, fr1 = top; fr1 != NULL; fr1 = fr1->fr_next) { if ((dir == 0) && ((fr1->fr_flags & FR_INQUE) != 0)) count++; else if ((dir == 1) && ((fr1->fr_flags & FR_OUTQUE) != 0)) count++; } if (dir == 0) emitGroup(-2, dir, m, fr1, group, count, 0); else if (dir == 1) emitGroup(-2, dir, m, fr1, group, 0, count); /* * Before printing each rule, check to see how many of its fields are * matched by subsequent rules. */ for (fr1 = top, rn = 0; fr1 != NULL; fr1 = fr1->fr_next, rn++) { if (!dir && !(fr1->fr_flags & FR_INQUE)) continue; if (dir && !(fr1->fr_flags & FR_OUTQUE)) continue; n = 0xfffffff; for (i = 0; i < FRC_MAX; i++) m[i].e = 0; qsort(m, FRC_MAX, sizeof(mc_t), intcmp); for (i = 0; i < FRC_MAX; i++) { m[i].c = i; m[i].e = 0; m[i].n = 0; m[i].s = 0; } for (fr = fr1->fr_next; fr; fr = fr->fr_next) { if (!dir && !(fr->fr_flags & FR_INQUE)) continue; if (dir && !(fr->fr_flags & FR_OUTQUE)) continue; if ((n & 0x0001) && !strcmp(fr1->fr_names + fr1->fr_ifnames[0], fr->fr_names + fr->fr_ifnames[0])) { m[FRC_IFN].e++; m[FRC_IFN].n++; } else n &= ~0x0001; if ((n & 0x0002) && (fr1->fr_family == fr->fr_family)) { m[FRC_V].e++; m[FRC_V].n++; } else n &= ~0x0002; if ((n & 0x0004) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && (fr1->fr_mip.fi_flx == fr->fr_mip.fi_flx) && (fr1->fr_ip.fi_flx == fr->fr_ip.fi_flx)) { m[FRC_FL].e++; m[FRC_FL].n++; } else n &= ~0x0004; if ((n & 0x0008) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && (fr1->fr_proto == fr->fr_proto)) { m[FRC_P].e++; m[FRC_P].n++; } else n &= ~0x0008; if ((n & 0x0010) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && (fr1->fr_ttl == fr->fr_ttl)) { m[FRC_TTL].e++; m[FRC_TTL].n++; } else n &= ~0x0010; if ((n & 0x0020) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && (fr1->fr_tos == fr->fr_tos)) { m[FRC_TOS].e++; m[FRC_TOS].n++; } else n &= ~0x0020; if ((n & 0x0040) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && ((fr1->fr_tcpfm == fr->fr_tcpfm) && (fr1->fr_tcpf == fr->fr_tcpf))) { m[FRC_TCP].e++; m[FRC_TCP].n++; } else n &= ~0x0040; if ((n & 0x0080) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && ((fr1->fr_scmp == fr->fr_scmp) && (fr1->fr_stop == fr->fr_stop) && (fr1->fr_sport == fr->fr_sport))) { m[FRC_SP].e++; m[FRC_SP].n++; } else n &= ~0x0080; if ((n & 0x0100) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && ((fr1->fr_dcmp == fr->fr_dcmp) && (fr1->fr_dtop == fr->fr_dtop) && (fr1->fr_dport == fr->fr_dport))) { m[FRC_DP].e++; m[FRC_DP].n++; } else n &= ~0x0100; if ((n & 0x0200) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && ((fr1->fr_satype == FRI_LOOKUP) && (fr->fr_satype == FRI_LOOKUP) && (fr1->fr_srcnum == fr->fr_srcnum))) { m[FRC_SRC].e++; m[FRC_SRC].n++; } else if ((n & 0x0200) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && (((fr1->fr_flags & FR_NOTSRCIP) == (fr->fr_flags & FR_NOTSRCIP)))) { if ((fr1->fr_smask == fr->fr_smask) && (fr1->fr_saddr == fr->fr_saddr)) m[FRC_SRC].e++; else n &= ~0x0200; if (fr1->fr_smask && (fr1->fr_saddr & fr1->fr_smask) == (fr->fr_saddr & fr1->fr_smask)) { m[FRC_SRC].n++; n |= 0x0200; } } else { n &= ~0x0200; } if ((n & 0x0400) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && ((fr1->fr_datype == FRI_LOOKUP) && (fr->fr_datype == FRI_LOOKUP) && (fr1->fr_dstnum == fr->fr_dstnum))) { m[FRC_DST].e++; m[FRC_DST].n++; } else if ((n & 0x0400) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && (((fr1->fr_flags & FR_NOTDSTIP) == (fr->fr_flags & FR_NOTDSTIP)))) { if ((fr1->fr_dmask == fr->fr_dmask) && (fr1->fr_daddr == fr->fr_daddr)) m[FRC_DST].e++; else n &= ~0x0400; if (fr1->fr_dmask && (fr1->fr_daddr & fr1->fr_dmask) == (fr->fr_daddr & fr1->fr_dmask)) { m[FRC_DST].n++; n |= 0x0400; } } else { n &= ~0x0400; } if ((n & 0x0800) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && (fr1->fr_optmask == fr->fr_optmask) && (fr1->fr_optbits == fr->fr_optbits)) { m[FRC_OPT].e++; m[FRC_OPT].n++; } else n &= ~0x0800; if ((n & 0x1000) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && (fr1->fr_secmask == fr->fr_secmask) && (fr1->fr_secbits == fr->fr_secbits)) { m[FRC_SEC].e++; m[FRC_SEC].n++; } else n &= ~0x1000; if ((n & 0x10000) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && (fr1->fr_authmask == fr->fr_authmask) && (fr1->fr_authbits == fr->fr_authbits)) { m[FRC_ATH].e++; m[FRC_ATH].n++; } else n &= ~0x10000; if ((n & 0x20000) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && ((fr1->fr_icmpm & 0xff00) == (fr->fr_icmpm & 0xff00)) && ((fr1->fr_icmp & 0xff00) == (fr->fr_icmp & 0xff00))) { m[FRC_ICT].e++; m[FRC_ICT].n++; } else n &= ~0x20000; if ((n & 0x40000) && (fr->fr_type == fr1->fr_type) && (fr->fr_type == FR_T_IPF) && ((fr1->fr_icmpm & 0xff) == (fr->fr_icmpm & 0xff)) && ((fr1->fr_icmp & 0xff) == (fr->fr_icmp & 0xff))) { m[FRC_ICC].e++; m[FRC_ICC].n++; } else n &= ~0x40000; } /*msort(m);*/ if (dir == 0) emitGroup(rn, dir, m, fr1, group, count, 0); else if (dir == 1) emitGroup(rn, dir, m, fr1, group, 0, count); } } -static void printhooks(fp, in, out, grp) - FILE *fp; - int in; - int out; - frgroup_t *grp; +static void +printhooks(FILE *fp, int in, int out, frgroup_t *grp) { frentry_t *fr; char *group; int dogrp, i; char *instr; group = grp->fg_name; dogrp = 0; if (in && out) { fprintf(stderr, "printhooks called with both in and out set\n"); exit(1); } if (in) { instr = "in"; } else if (out) { instr = "out"; } else { instr = "???"; } fprintf(fp, "static frentry_t ipfrule_%s_%s;\n", instr, group); fprintf(fp, "\ \n\ int ipfrule_add_%s_%s()\n", instr, group); fprintf(fp, "\ {\n\ int i, j, err = 0, max;\n\ frentry_t *fp;\n"); if (dogrp) fprintf(fp, "\ frgroup_t *fg;\n"); fprintf(fp, "\n"); for (i = 0, fr = grp->fg_start; fr != NULL; i++, fr = fr->fr_next) if (fr->fr_dsize > 0) { fprintf(fp, "\ ipf_rules_%s_%s[%d]->fr_data = &ipf%s_rule_data_%s_%u;\n", instr, grp->fg_name, i, instr, grp->fg_name, i); } fprintf(fp, "\ max = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *);\n\ for (i = 0; i < max; i++) {\n\ fp = ipf_rules_%s_%s[i];\n\ fp->fr_next = NULL;\n", instr, group, instr, group); fprintf(fp, "\ for (j = i + 1; j < max; j++)\n\ if (strncmp(fp->fr_names + fp->fr_group,\n\ ipf_rules_%s_%s[j]->fr_names +\n\ ipf_rules_%s_%s[j]->fr_group,\n\ FR_GROUPLEN) == 0) {\n\ if (ipf_rules_%s_%s[j] != NULL)\n\ ipf_rules_%s_%s[j]->fr_pnext =\n\ &fp->fr_next;\n\ fp->fr_pnext = &ipf_rules_%s_%s[j];\n\ fp->fr_next = ipf_rules_%s_%s[j];\n\ break;\n\ }\n", instr, group, instr, group, instr, group, instr, group, instr, group, instr, group); if (dogrp) fprintf(fp, "\ \n\ if (fp->fr_grhead != -1) {\n\ fg = fr_addgroup(fp->fr_names + fp->fr_grhead,\n\ fp, FR_INQUE, IPL_LOGIPF, 0);\n\ if (fg != NULL)\n\ fp->fr_grp = &fg->fg_start;\n\ }\n"); fprintf(fp, "\ }\n\ \n\ fp = &ipfrule_%s_%s;\n", instr, group); fprintf(fp, "\ bzero((char *)fp, sizeof(*fp));\n\ fp->fr_type = FR_T_CALLFUNC_BUILTIN;\n\ fp->fr_flags = FR_%sQUE|FR_NOMATCH;\n\ fp->fr_data = (void *)ipf_rules_%s_%s[0];\n", (in != 0) ? "IN" : "OUT", instr, group); fprintf(fp, "\ fp->fr_dsize = sizeof(ipf_rules_%s_%s[0]);\n", instr, group); fprintf(fp, "\ fp->fr_family = AF_INET;\n\ fp->fr_func = (ipfunc_t)ipfrule_match_%s_%s;\n\ err = frrequest(&ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp,\n\ ipfmain.ipf_active, 0);\n", instr, group); fprintf(fp, "\treturn err;\n}\n"); fprintf(fp, "\n\n\ int ipfrule_remove_%s_%s()\n", instr, group); fprintf(fp, "\ {\n\ int err = 0, i;\n\ frentry_t *fp;\n\ \n\ /*\n\ * Try to remove the %sbound rule.\n", instr); fprintf(fp, "\ */\n\ if (ipfrule_%s_%s.fr_ref > 0) {\n", instr, group); fprintf(fp, "\ err = EBUSY;\n\ } else {\n"); fprintf(fp, "\ i = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *) - 1;\n\ for (; i >= 0; i--) {\n\ fp = ipf_rules_%s_%s[i];\n\ if (fp->fr_ref > 1) {\n\ err = EBUSY;\n\ break;\n\ }\n\ }\n\ }\n\ if (err == 0)\n\ err = frrequest(&ipfmain, IPL_LOGIPF, SIOCDELFR,\n\ (caddr_t)&ipfrule_%s_%s,\n\ ipfmain.ipf_active, 0);\n", instr, group, instr, group, instr, group); fprintf(fp, "\ if (err)\n\ return err;\n\ \n\n"); fprintf(fp, "\treturn err;\n}\n"); } diff --git a/sbin/ipf/ipfs/ipfs.c b/sbin/ipf/ipfs/ipfs.c index e9a535977bd9..680d2659ca51 100644 --- a/sbin/ipf/ipfs/ipfs.c +++ b/sbin/ipf/ipfs/ipfs.c @@ -1,872 +1,855 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include #include #include #include #include #if !defined(__SVR4) && !defined(__GNUC__) #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipf.h" #include "netinet/ipl.h" #if !defined(lint) static const char rcsid[] = "@(#)$Id$"; #endif #ifndef IPF_SAVEDIR # define IPF_SAVEDIR "/var/db/ipf" #endif #ifndef IPF_NATFILE # define IPF_NATFILE "ipnat.ipf" #endif #ifndef IPF_STATEFILE # define IPF_STATEFILE "ipstate.ipf" #endif #if !defined(__SVR4) && defined(__GNUC__) extern char *index(const char *, int); #endif extern char *optarg; extern int optind; int main(int, char *[]); void usage(void); int changestateif(char *, char *); int changenatif(char *, char *); int readstate(int, char *); int readnat(int, char *); int writestate(int, char *); int opendevice(char *); void closedevice(int); int setlock(int, int); int writeall(char *); int readall(char *); int writenat(int, char *); int opts = 0; char *progname; void usage() { fprintf(stderr, "usage: %s [-nv] -l\n", progname); fprintf(stderr, "usage: %s [-nv] -u\n", progname); fprintf(stderr, "usage: %s [-nv] [-d ] -R\n", progname); fprintf(stderr, "usage: %s [-nv] [-d ] -W\n", progname); fprintf(stderr, "usage: %s [-nNSv] [-f ] -r\n", progname); fprintf(stderr, "usage: %s [-nNSv] [-f ] -w\n", progname); fprintf(stderr, "usage: %s [-nNSv] -f -i ,\n", progname); exit(1); } /* * Change interface names in state information saved out to disk. */ -int changestateif(ifs, fname) - char *ifs, *fname; +int changestateif(char *ifs, char *fname) { int fd, olen, nlen, rw; ipstate_save_t ips; off_t pos; char *s; s = strchr(ifs, ','); if (!s) usage(); *s++ = '\0'; nlen = strlen(s); olen = strlen(ifs); if (nlen >= sizeof(ips.ips_is.is_ifname) || olen >= sizeof(ips.ips_is.is_ifname)) usage(); fd = open(fname, O_RDWR); if (fd == -1) { perror("open"); exit(1); } for (pos = 0; read(fd, &ips, sizeof(ips)) == sizeof(ips); ) { rw = 0; if (!strncmp(ips.ips_is.is_ifname[0], ifs, olen + 1)) { strcpy(ips.ips_is.is_ifname[0], s); rw = 1; } if (!strncmp(ips.ips_is.is_ifname[1], ifs, olen + 1)) { strcpy(ips.ips_is.is_ifname[1], s); rw = 1; } if (!strncmp(ips.ips_is.is_ifname[2], ifs, olen + 1)) { strcpy(ips.ips_is.is_ifname[2], s); rw = 1; } if (!strncmp(ips.ips_is.is_ifname[3], ifs, olen + 1)) { strcpy(ips.ips_is.is_ifname[3], s); rw = 1; } if (rw == 1) { if (lseek(fd, pos, SEEK_SET) != pos) { perror("lseek"); exit(1); } if (write(fd, &ips, sizeof(ips)) != sizeof(ips)) { perror("write"); exit(1); } } pos = lseek(fd, 0, SEEK_CUR); } close(fd); return 0; } /* * Change interface names in NAT information saved out to disk. */ -int changenatif(ifs, fname) - char *ifs, *fname; +int changenatif(char *ifs, char *fname) { int fd, olen, nlen, rw; nat_save_t ipn; nat_t *nat; off_t pos; char *s; s = strchr(ifs, ','); if (!s) usage(); *s++ = '\0'; nlen = strlen(s); olen = strlen(ifs); nat = &ipn.ipn_nat; if (nlen >= sizeof(nat->nat_ifnames[0]) || olen >= sizeof(nat->nat_ifnames[0])) usage(); fd = open(fname, O_RDWR); if (fd == -1) { perror("open"); exit(1); } for (pos = 0; read(fd, &ipn, sizeof(ipn)) == sizeof(ipn); ) { rw = 0; if (!strncmp(nat->nat_ifnames[0], ifs, olen + 1)) { strcpy(nat->nat_ifnames[0], s); rw = 1; } if (!strncmp(nat->nat_ifnames[1], ifs, olen + 1)) { strcpy(nat->nat_ifnames[1], s); rw = 1; } if (rw == 1) { if (lseek(fd, pos, SEEK_SET) != pos) { perror("lseek"); exit(1); } if (write(fd, &ipn, sizeof(ipn)) != sizeof(ipn)) { perror("write"); exit(1); } } pos = lseek(fd, 0, SEEK_CUR); } close(fd); return 0; } -int main(argc,argv) - int argc; - char *argv[]; +int main(int argc, char *argv[]) { int c, lock = -1, devfd = -1, err = 0, rw = -1, ns = -1, set = 0; char *dirname = NULL, *filename = NULL, *ifs = NULL; progname = argv[0]; while ((c = getopt(argc, argv, "d:f:i:lNnSRruvWw")) != -1) switch (c) { case 'd' : if ((set == 0) && !dirname && !filename) dirname = optarg; else usage(); break; case 'f' : if ((set != 0) && !dirname && !filename) filename = optarg; else usage(); break; case 'i' : ifs = optarg; set = 1; break; case 'l' : if (filename || dirname || set) usage(); lock = 1; set = 1; break; case 'n' : opts |= OPT_DONOTHING; break; case 'N' : if ((ns >= 0) || dirname || (rw != -1) || set) usage(); ns = 0; set = 1; break; case 'r' : if (dirname || (rw != -1) || (ns == -1)) usage(); rw = 0; set = 1; break; case 'R' : rw = 2; set = 1; break; case 'S' : if ((ns >= 0) || dirname || (rw != -1) || set) usage(); ns = 1; set = 1; break; case 'u' : if (filename || dirname || set) usage(); lock = 0; set = 1; break; case 'v' : opts |= OPT_VERBOSE; break; case 'w' : if (dirname || (rw != -1) || (ns == -1)) usage(); rw = 1; set = 1; break; case 'W' : rw = 3; set = 1; break; case '?' : default : usage(); } if (ifs) { if (!filename || ns < 0) usage(); if (ns == 0) return changenatif(ifs, filename); else return changestateif(ifs, filename); } if ((ns >= 0) || (lock >= 0)) { if (lock >= 0) devfd = opendevice(NULL); else if (ns >= 0) { if (ns == 1) devfd = opendevice(IPSTATE_NAME); else if (ns == 0) devfd = opendevice(IPNAT_NAME); } if (devfd == -1) exit(1); } if (lock >= 0) err = setlock(devfd, lock); else if (rw >= 0) { if (rw & 1) { /* WRITE */ if (rw & 2) err = writeall(dirname); else { if (ns == 0) err = writenat(devfd, filename); else if (ns == 1) err = writestate(devfd, filename); } } else { if (rw & 2) err = readall(dirname); else { if (ns == 0) err = readnat(devfd, filename); else if (ns == 1) err = readstate(devfd, filename); } } } return err; } -int opendevice(ipfdev) - char *ipfdev; +int opendevice(char *ipfdev) { int fd = -1; if (opts & OPT_DONOTHING) return -2; if (!ipfdev) ipfdev = IPL_NAME; if ((fd = open(ipfdev, O_RDWR)) == -1) if ((fd = open(ipfdev, O_RDONLY)) == -1) perror("open device"); return fd; } -void closedevice(fd) - int fd; +void closedevice(int fd) { close(fd); } -int setlock(fd, lock) - int fd, lock; +int setlock(int fd, int lock) { if (opts & OPT_VERBOSE) printf("Turn lock %s\n", lock ? "on" : "off"); if (!(opts & OPT_DONOTHING)) { if (ioctl(fd, SIOCSTLCK, &lock) == -1) { perror("SIOCSTLCK"); return 1; } if (opts & OPT_VERBOSE) printf("Lock now %s\n", lock ? "on" : "off"); } return 0; } -int writestate(fd, file) - int fd; - char *file; +int writestate(int fd, char *file) { ipstate_save_t ips, *ipsp; ipfobj_t obj; int wfd = -1; if (!file) file = IPF_STATEFILE; wfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600); if (wfd == -1) { fprintf(stderr, "%s ", file); perror("state:open"); return 1; } ipsp = &ips; bzero((char *)&obj, sizeof(obj)); bzero((char *)ipsp, sizeof(ips)); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_size = sizeof(*ipsp); obj.ipfo_type = IPFOBJ_STATESAVE; obj.ipfo_ptr = ipsp; do { if (opts & OPT_VERBOSE) printf("Getting state from addr %p\n", ips.ips_next); if (ioctl(fd, SIOCSTGET, &obj)) { if (errno == ENOENT) break; perror("state:SIOCSTGET"); close(wfd); return 1; } if (opts & OPT_VERBOSE) printf("Got state next %p\n", ips.ips_next); if (write(wfd, ipsp, sizeof(ips)) != sizeof(ips)) { perror("state:write"); close(wfd); return 1; } } while (ips.ips_next != NULL); close(wfd); return 0; } -int readstate(fd, file) - int fd; - char *file; +int readstate(int fd, char *file) { ipstate_save_t ips, *is, *ipshead = NULL, *is1, *ipstail = NULL; int sfd = -1, i; ipfobj_t obj; if (!file) file = IPF_STATEFILE; sfd = open(file, O_RDONLY, 0600); if (sfd == -1) { fprintf(stderr, "%s ", file); perror("open"); return 1; } bzero((char *)&ips, sizeof(ips)); /* * 1. Read all state information in. */ do { i = read(sfd, &ips, sizeof(ips)); if (i == -1) { perror("read"); goto freeipshead; } if (i == 0) break; if (i != sizeof(ips)) { fprintf(stderr, "state:incomplete read: %d != %d\n", i, (int)sizeof(ips)); goto freeipshead; } is = (ipstate_save_t *)malloc(sizeof(*is)); if (is == NULL) { fprintf(stderr, "malloc failed\n"); goto freeipshead; } bcopy((char *)&ips, (char *)is, sizeof(ips)); /* * Check to see if this is the first state entry that will * reference a particular rule and if so, flag it as such * else just adjust the rule pointer to become a pointer to * the other. We do this so we have a means later for tracking * who is referencing us when we get back the real pointer * in is_rule after doing the ioctl. */ for (is1 = ipshead; is1 != NULL; is1 = is1->ips_next) if (is1->ips_rule == is->ips_rule) break; if (is1 == NULL) is->ips_is.is_flags |= SI_NEWFR; else is->ips_rule = (void *)&is1->ips_rule; /* * Use a tail-queue type list (add things to the end).. */ is->ips_next = NULL; if (!ipshead) ipshead = is; if (ipstail) ipstail->ips_next = is; ipstail = is; } while (1); close(sfd); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_size = sizeof(*is); obj.ipfo_type = IPFOBJ_STATESAVE; while ((is = ipshead) != NULL) { if (opts & OPT_VERBOSE) printf("Loading new state table entry\n"); if (is->ips_is.is_flags & SI_NEWFR) { if (opts & OPT_VERBOSE) printf("Loading new filter rule\n"); } obj.ipfo_ptr = is; if (!(opts & OPT_DONOTHING)) if (ioctl(fd, SIOCSTPUT, &obj)) { perror("SIOCSTPUT"); goto freeipshead; } if (is->ips_is.is_flags & SI_NEWFR) { if (opts & OPT_VERBOSE) printf("Real rule addr %p\n", is->ips_rule); for (is1 = is->ips_next; is1; is1 = is1->ips_next) if (is1->ips_rule == (frentry_t *)&is->ips_rule) is1->ips_rule = is->ips_rule; } ipshead = is->ips_next; free(is); } return 0; freeipshead: while ((is = ipshead) != NULL) { ipshead = is->ips_next; free(is); } if (sfd != -1) close(sfd); return 1; } -int readnat(fd, file) - int fd; - char *file; +int readnat(int fd, char *file) { nat_save_t ipn, *in, *ipnhead = NULL, *in1, *ipntail = NULL; ipfobj_t obj; int nfd, i; nat_t *nat; char *s; int n; nfd = -1; in = NULL; ipnhead = NULL; ipntail = NULL; if (!file) file = IPF_NATFILE; nfd = open(file, O_RDONLY); if (nfd == -1) { fprintf(stderr, "%s ", file); perror("nat:open"); return 1; } bzero((char *)&ipn, sizeof(ipn)); /* * 1. Read all state information in. */ do { i = read(nfd, &ipn, sizeof(ipn)); if (i == -1) { perror("read"); goto freenathead; } if (i == 0) break; if (i != sizeof(ipn)) { fprintf(stderr, "nat:incomplete read: %d != %d\n", i, (int)sizeof(ipn)); goto freenathead; } in = (nat_save_t *)malloc(ipn.ipn_dsize); if (in == NULL) { fprintf(stderr, "nat:cannot malloc nat save atruct\n"); goto freenathead; } if (ipn.ipn_dsize > sizeof(ipn)) { n = ipn.ipn_dsize - sizeof(ipn); if (n > 0) { s = in->ipn_data + sizeof(in->ipn_data); i = read(nfd, s, n); if (i == 0) break; if (i != n) { fprintf(stderr, "nat:incomplete read: %d != %d\n", i, n); goto freenathead; } } } bcopy((char *)&ipn, (char *)in, sizeof(ipn)); /* * Check to see if this is the first NAT entry that will * reference a particular rule and if so, flag it as such * else just adjust the rule pointer to become a pointer to * the other. We do this so we have a means later for tracking * who is referencing us when we get back the real pointer * in is_rule after doing the ioctl. */ nat = &in->ipn_nat; if (nat->nat_fr != NULL) { for (in1 = ipnhead; in1 != NULL; in1 = in1->ipn_next) if (in1->ipn_rule == nat->nat_fr) break; if (in1 == NULL) nat->nat_flags |= SI_NEWFR; else nat->nat_fr = &in1->ipn_fr; } /* * Use a tail-queue type list (add things to the end).. */ in->ipn_next = NULL; if (!ipnhead) ipnhead = in; if (ipntail) ipntail->ipn_next = in; ipntail = in; } while (1); close(nfd); nfd = -1; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_NATSAVE; while ((in = ipnhead) != NULL) { if (opts & OPT_VERBOSE) printf("Loading new NAT table entry\n"); nat = &in->ipn_nat; if (nat->nat_flags & SI_NEWFR) { if (opts & OPT_VERBOSE) printf("Loading new filter rule\n"); } obj.ipfo_ptr = in; obj.ipfo_size = in->ipn_dsize; if (!(opts & OPT_DONOTHING)) if (ioctl(fd, SIOCSTPUT, &obj)) { fprintf(stderr, "in=%p:", in); perror("SIOCSTPUT"); return 1; } if (nat->nat_flags & SI_NEWFR) { if (opts & OPT_VERBOSE) printf("Real rule addr %p\n", nat->nat_fr); for (in1 = in->ipn_next; in1; in1 = in1->ipn_next) if (in1->ipn_rule == &in->ipn_fr) in1->ipn_rule = nat->nat_fr; } ipnhead = in->ipn_next; free(in); } return 0; freenathead: while ((in = ipnhead) != NULL) { ipnhead = in->ipn_next; free(in); } if (nfd != -1) close(nfd); return 1; } -int writenat(fd, file) - int fd; - char *file; +int writenat(int fd, char *file) { nat_save_t *ipnp = NULL, *next = NULL; ipfobj_t obj; int nfd = -1; natget_t ng; if (!file) file = IPF_NATFILE; nfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600); if (nfd == -1) { fprintf(stderr, "%s ", file); perror("nat:open"); return 1; } obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_NATSAVE; do { if (opts & OPT_VERBOSE) printf("Getting nat from addr %p\n", ipnp); ng.ng_ptr = next; ng.ng_sz = 0; if (ioctl(fd, SIOCSTGSZ, &ng)) { perror("nat:SIOCSTGSZ"); close(nfd); if (ipnp != NULL) free(ipnp); return 1; } if (opts & OPT_VERBOSE) printf("NAT size %d from %p\n", ng.ng_sz, ng.ng_ptr); if (ng.ng_sz == 0) break; if (!ipnp) ipnp = malloc(ng.ng_sz); else ipnp = realloc((char *)ipnp, ng.ng_sz); if (!ipnp) { fprintf(stderr, "malloc for %d bytes failed\n", ng.ng_sz); break; } bzero((char *)ipnp, ng.ng_sz); obj.ipfo_size = ng.ng_sz; obj.ipfo_ptr = ipnp; ipnp->ipn_dsize = ng.ng_sz; ipnp->ipn_next = next; if (ioctl(fd, SIOCSTGET, &obj)) { if (errno == ENOENT) break; perror("nat:SIOCSTGET"); close(nfd); free(ipnp); return 1; } if (opts & OPT_VERBOSE) printf("Got nat next %p ipn_dsize %d ng_sz %d\n", ipnp->ipn_next, ipnp->ipn_dsize, ng.ng_sz); if (write(nfd, ipnp, ipnp->ipn_dsize) != ipnp->ipn_dsize) { perror("nat:write"); close(nfd); free(ipnp); return 1; } next = ipnp->ipn_next; } while (ipnp && next); if (ipnp != NULL) free(ipnp); close(nfd); return 0; } -int writeall(dirname) - char *dirname; +int writeall(char *dirname) { int fd, devfd; if (!dirname) dirname = IPF_SAVEDIR; if (chdir(dirname)) { fprintf(stderr, "IPF_SAVEDIR=%s: ", dirname); perror("chdir(IPF_SAVEDIR)"); return 1; } fd = opendevice(NULL); if (fd == -1) return 1; if (setlock(fd, 1)) { close(fd); return 1; } devfd = opendevice(IPSTATE_NAME); if (devfd == -1) goto bad; if (writestate(devfd, NULL)) goto bad; close(devfd); devfd = opendevice(IPNAT_NAME); if (devfd == -1) goto bad; if (writenat(devfd, NULL)) goto bad; close(devfd); if (setlock(fd, 0)) { close(fd); return 1; } close(fd); return 0; bad: setlock(fd, 0); close(fd); return 1; } -int readall(dirname) - char *dirname; +int readall(char *dirname) { int fd, devfd; if (!dirname) dirname = IPF_SAVEDIR; if (chdir(dirname)) { perror("chdir(IPF_SAVEDIR)"); return 1; } fd = opendevice(NULL); if (fd == -1) return 1; if (setlock(fd, 1)) { close(fd); return 1; } devfd = opendevice(IPSTATE_NAME); if (devfd == -1) return 1; if (readstate(devfd, NULL)) return 1; close(devfd); devfd = opendevice(IPNAT_NAME); if (devfd == -1) return 1; if (readnat(devfd, NULL)) return 1; close(devfd); if (setlock(fd, 0)) { close(fd); return 1; } return 0; } diff --git a/sbin/ipf/ipfstat/ipfstat.c b/sbin/ipf/ipfstat/ipfstat.c index 4517d3e857b4..93345a79e007 100644 --- a/sbin/ipf/ipfstat/ipfstat.c +++ b/sbin/ipf/ipfstat/ipfstat.c @@ -1,2383 +1,2316 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include #include #include # include #include #if defined(sun) && defined(__SVR4) # include #endif #include "ipf.h" #include "netinet/ipl.h" #if defined(STATETOP) # if defined(sun) && defined(__SVR4) # include # endif # include # include # include # include # include # if SOLARIS || defined(__NetBSD__) # ifdef ERR # undef ERR # endif # include # else /* SOLARIS */ # include # endif /* SOLARIS */ #endif /* STATETOP */ #include "kmem.h" #if defined(__NetBSD__) # include #endif #if !defined(lint) static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif extern char *optarg; extern int optind; extern int opterr; #define PRINTF (void)printf #define FPRINTF (void)fprintf static char *filters[4] = { "ipfilter(in)", "ipfilter(out)", "ipacct(in)", "ipacct(out)" }; static int state_logging = -1; static wordtab_t *state_fields = NULL; int nohdrfields = 0; int opts = 0; #ifdef USE_INET6 int use_inet4 = 0; int use_inet6 = 0; #endif int live_kernel = 1; int state_fd = -1; int ipf_fd = -1; int auth_fd = -1; int nat_fd = -1; frgroup_t *grtop = NULL; frgroup_t *grtail = NULL; char *blockreasons[FRB_MAX_VALUE + 1] = { "packet blocked", "log rule failure", "pps rate exceeded", "jumbogram", "makefrip failed", "cannot add state", "IP ID update failed", "log-or-block failed", "decapsulate failure", "cannot create new auth entry", "packet queued for auth", "buffer coalesce failure", "buffer pullup failure", "auth feedback", "bad fragment", "IPv4 NAT failure", "IPv6 NAT failure" }; #ifdef STATETOP #define STSTRSIZE 80 #define STGROWSIZE 16 #define HOSTNMLEN 40 #define STSORT_PR 0 #define STSORT_PKTS 1 #define STSORT_BYTES 2 #define STSORT_TTL 3 #define STSORT_SRCIP 4 #define STSORT_SRCPT 5 #define STSORT_DSTIP 6 #define STSORT_DSTPT 7 #define STSORT_MAX STSORT_DSTPT #define STSORT_DEFAULT STSORT_BYTES typedef struct statetop { i6addr_t st_src; i6addr_t st_dst; u_short st_sport; u_short st_dport; u_char st_p; u_char st_v; u_char st_state[2]; U_QUAD_T st_pkts; U_QUAD_T st_bytes; u_long st_age; } statetop_t; #endif int main(int, char *[]); static int fetchfrag(int, int, ipfr_t *); static void showstats(friostat_t *, u_32_t); static void showfrstates(ipfrstat_t *, u_long); static void showlist(friostat_t *); static void showstatestats(ips_stat_t *); static void showipstates(ips_stat_t *, int *); static void showauthstates(ipf_authstat_t *); static void showtqtable_live(int); static void showgroups(friostat_t *); static void usage(char *); static int state_matcharray(ipstate_t *, int *); static int printlivelist(friostat_t *, int, int, frentry_t *, char *, char *); static void printdeadlist(friostat_t *, int, int, frentry_t *, char *, char *); static void printside(char *, ipf_statistics_t *); static void parse_ipportstr(const char *, i6addr_t *, int *); static void ipfstate_live(char *, friostat_t **, ips_stat_t **, ipfrstat_t **, ipf_authstat_t **, u_32_t *); static void ipfstate_dead(char *, friostat_t **, ips_stat_t **, ipfrstat_t **, ipf_authstat_t **, u_32_t *); static ipstate_t *fetchstate(ipstate_t *, ipstate_t *); #ifdef STATETOP static void topipstates(i6addr_t, i6addr_t, int, int, int, int, int, int, int *); static void sig_break(int); static void sig_resize(int); static char *getip(int, i6addr_t *); static char *ttl_to_string(long); static int sort_p(const void *, const void *); static int sort_pkts(const void *, const void *); static int sort_bytes(const void *, const void *); static int sort_ttl(const void *, const void *); static int sort_srcip(const void *, const void *); static int sort_srcpt(const void *, const void *); static int sort_dstip(const void *, const void *); static int sort_dstpt(const void *, const void *); #endif static void usage(name) char *name; { #ifdef USE_INET6 fprintf(stderr, "Usage: %s [-46aAdfghIilnoRsv]\n", name); #else fprintf(stderr, "Usage: %s [-4aAdfghIilnoRsv]\n", name); #endif fprintf(stderr, " %s [-M corefile] [-N symbol-list]\n", name); #ifdef STATETOP #ifdef USE_INET6 fprintf(stderr, " %s -t [-46C] ", name); #else fprintf(stderr, " %s -t [-4C] ", name); #endif #endif fprintf(stderr, "[-D destination address] [-P protocol] [-S source address] [-T refresh time]\n"); exit(1); } -int main(argc,argv) - int argc; - char *argv[]; +int main(int argc, char *argv[]) { ipf_authstat_t frauthst; ipf_authstat_t *frauthstp = &frauthst; friostat_t fio; friostat_t *fiop = &fio; ips_stat_t ipsst; ips_stat_t *ipsstp = &ipsst; ipfrstat_t ifrst; ipfrstat_t *ifrstp = &ifrst; char *options; char *kern = NULL; char *memf = NULL; int c; int myoptind; int *filter = NULL; int protocol = -1; /* -1 = wild card for any protocol */ int refreshtime = 1; /* default update time */ int sport = -1; /* -1 = wild card for any source port */ int dport = -1; /* -1 = wild card for any dest port */ int topclosed = 0; /* do not show closed tcp sessions */ i6addr_t saddr, daddr; u_32_t frf; #ifdef USE_INET6 options = "46aACdfghIilnostvD:m:M:N:O:P:RS:T:"; #else options = "4aACdfghIilnostvD:m:M:N:O:P:RS:T:"; #endif saddr.in4.s_addr = INADDR_ANY; /* default any v4 source addr */ daddr.in4.s_addr = INADDR_ANY; /* default any v4 dest addr */ #ifdef USE_INET6 saddr.in6 = in6addr_any; /* default any v6 source addr */ daddr.in6 = in6addr_any; /* default any v6 dest addr */ #endif /* Don't warn about invalid flags when we run getopt for the 1st time */ opterr = 0; /* * Parse these two arguments now lest there be any buffer overflows * in the parsing of the rest. */ myoptind = optind; while ((c = getopt(argc, argv, options)) != -1) { switch (c) { case 'M' : memf = optarg; live_kernel = 0; break; case 'N' : kern = optarg; live_kernel = 0; break; } } optind = myoptind; if (live_kernel == 1) { if ((state_fd = open(IPSTATE_NAME, O_RDONLY)) == -1) { perror("open(IPSTATE_NAME)"); exit(-1); } if ((auth_fd = open(IPAUTH_NAME, O_RDONLY)) == -1) { perror("open(IPAUTH_NAME)"); exit(-1); } if ((nat_fd = open(IPNAT_NAME, O_RDONLY)) == -1) { perror("open(IPAUTH_NAME)"); exit(-1); } if ((ipf_fd = open(IPL_NAME, O_RDONLY)) == -1) { fprintf(stderr, "open(%s)", IPL_NAME); perror(""); exit(-1); } } if (kern != NULL || memf != NULL) { (void)setgid(getgid()); (void)setuid(getuid()); } if (live_kernel == 1) { (void) checkrev(IPL_NAME); } else { if (openkmem(kern, memf) == -1) exit(-1); } (void)setgid(getgid()); (void)setuid(getuid()); opterr = 1; while ((c = getopt(argc, argv, options)) != -1) { switch (c) { #ifdef USE_INET6 case '4' : use_inet4 = 1; break; case '6' : use_inet6 = 1; break; #endif case 'a' : opts |= OPT_ACCNT|OPT_SHOWLIST; break; case 'A' : opts |= OPT_AUTHSTATS; break; case 'C' : topclosed = 1; break; case 'd' : opts |= OPT_DEBUG; break; case 'D' : parse_ipportstr(optarg, &daddr, &dport); break; case 'f' : opts |= OPT_FRSTATES; break; case 'g' : opts |= OPT_GROUPS; break; case 'h' : opts |= OPT_HITS; break; case 'i' : opts |= OPT_INQUE|OPT_SHOWLIST; break; case 'I' : opts |= OPT_INACTIVE; break; case 'l' : opts |= OPT_SHOWLIST; break; case 'm' : filter = parseipfexpr(optarg, NULL); if (filter == NULL) { fprintf(stderr, "Error parseing '%s'\n", optarg); exit(1); } break; case 'M' : break; case 'N' : break; case 'n' : opts |= OPT_SHOWLINENO; break; case 'o' : opts |= OPT_OUTQUE|OPT_SHOWLIST; break; case 'O' : state_fields = parsefields(statefields, optarg); break; case 'P' : protocol = getproto(optarg); if (protocol == -1) { fprintf(stderr, "%s: Invalid protocol: %s\n", argv[0], optarg); exit(-2); } break; case 'R' : opts |= OPT_NORESOLVE; break; case 's' : opts |= OPT_IPSTATES; break; case 'S' : parse_ipportstr(optarg, &saddr, &sport); break; case 't' : #ifdef STATETOP opts |= OPT_STATETOP; break; #else fprintf(stderr, "%s: state top facility not compiled in\n", argv[0]); exit(-2); #endif case 'T' : if (!sscanf(optarg, "%d", &refreshtime) || (refreshtime <= 0)) { fprintf(stderr, "%s: Invalid refreshtime < 1 : %s\n", argv[0], optarg); exit(-2); } break; case 'v' : opts |= OPT_VERBOSE; break; default : usage(argv[0]); break; } } #ifdef USE_INET6 if ((use_inet4 || use_inet6) && !(opts & (OPT_INQUE | OPT_OUTQUE | OPT_STATETOP))) { #ifdef STATETOP FPRINTF(stderr, "No -i, -o, or -t given with -4 or -6\n"); #else FPRINTF(stderr, "No -i or -o given with -4 or -6\n"); #endif exit(-2); } if (use_inet4 == 0 && use_inet6 == 0) use_inet4 = use_inet6 = 1; #endif if (live_kernel == 1) { bzero((char *)&fio, sizeof(fio)); bzero((char *)&ipsst, sizeof(ipsst)); bzero((char *)&ifrst, sizeof(ifrst)); ipfstate_live(IPL_NAME, &fiop, &ipsstp, &ifrstp, &frauthstp, &frf); } else { ipfstate_dead(kern, &fiop, &ipsstp, &ifrstp, &frauthstp, &frf); } if (opts & OPT_IPSTATES) { showipstates(ipsstp, filter); } else if (opts & OPT_SHOWLIST) { showlist(fiop); if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){ opts &= ~OPT_OUTQUE; showlist(fiop); } } else if (opts & OPT_FRSTATES) showfrstates(ifrstp, fiop->f_ticks); #ifdef STATETOP else if (opts & OPT_STATETOP) topipstates(saddr, daddr, sport, dport, protocol, #ifdef USE_INET6 use_inet6 && use_inet4 ? 0 : use_inet6 && !use_inet4 ? 6 : 4, #else 4, #endif #endif refreshtime, topclosed, filter); else if (opts & OPT_AUTHSTATS) showauthstates(frauthstp); else if (opts & OPT_GROUPS) showgroups(fiop); else showstats(fiop, frf); return 0; } /* * Fill in the stats structures from the live kernel, using a combination * of ioctl's and copying directly from kernel memory. */ -static void ipfstate_live(device, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp) - char *device; - friostat_t **fiopp; - ips_stat_t **ipsstpp; - ipfrstat_t **ifrstpp; - ipf_authstat_t **frauthstpp; - u_32_t *frfp; +static void ipfstate_live(char *device, friostat_t **fiopp, + ips_stat_t **ipsstpp, ipfrstat_t **ifrstpp, + ipf_authstat_t **frauthstpp, u_32_t *frfp) { ipfobj_t ipfo; if (checkrev(device) == -1) { fprintf(stderr, "User/kernel version check failed\n"); exit(1); } if ((opts & OPT_AUTHSTATS) == 0) { bzero((caddr_t)&ipfo, sizeof(ipfo)); ipfo.ipfo_rev = IPFILTER_VERSION; ipfo.ipfo_type = IPFOBJ_IPFSTAT; ipfo.ipfo_size = sizeof(friostat_t); ipfo.ipfo_ptr = (void *)*fiopp; if (ioctl(ipf_fd, SIOCGETFS, &ipfo) == -1) { ipferror(ipf_fd, "ioctl(ipf:SIOCGETFS)"); exit(-1); } if (ioctl(ipf_fd, SIOCGETFF, frfp) == -1) ipferror(ipf_fd, "ioctl(SIOCGETFF)"); } if ((opts & OPT_IPSTATES) != 0) { bzero((caddr_t)&ipfo, sizeof(ipfo)); ipfo.ipfo_rev = IPFILTER_VERSION; ipfo.ipfo_type = IPFOBJ_STATESTAT; ipfo.ipfo_size = sizeof(ips_stat_t); ipfo.ipfo_ptr = (void *)*ipsstpp; if ((ioctl(state_fd, SIOCGETFS, &ipfo) == -1)) { ipferror(state_fd, "ioctl(state:SIOCGETFS)"); exit(-1); } if (ioctl(state_fd, SIOCGETLG, &state_logging) == -1) { ipferror(state_fd, "ioctl(state:SIOCGETLG)"); exit(-1); } } if ((opts & OPT_FRSTATES) != 0) { bzero((caddr_t)&ipfo, sizeof(ipfo)); ipfo.ipfo_rev = IPFILTER_VERSION; ipfo.ipfo_type = IPFOBJ_FRAGSTAT; ipfo.ipfo_size = sizeof(ipfrstat_t); ipfo.ipfo_ptr = (void *)*ifrstpp; if (ioctl(ipf_fd, SIOCGFRST, &ipfo) == -1) { ipferror(ipf_fd, "ioctl(SIOCGFRST)"); exit(-1); } } if (opts & OPT_DEBUG) PRINTF("opts %#x name %s\n", opts, device); if ((opts & OPT_AUTHSTATS) != 0) { bzero((caddr_t)&ipfo, sizeof(ipfo)); ipfo.ipfo_rev = IPFILTER_VERSION; ipfo.ipfo_type = IPFOBJ_AUTHSTAT; ipfo.ipfo_size = sizeof(ipf_authstat_t); ipfo.ipfo_ptr = (void *)*frauthstpp; if (ioctl(auth_fd, SIOCATHST, &ipfo) == -1) { ipferror(auth_fd, "ioctl(SIOCATHST)"); exit(-1); } } } /* * Build up the stats structures from data held in the "core" memory. * This is mainly useful when looking at data in crash dumps and ioctl's * just won't work any more. */ -static void ipfstate_dead(kernel, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp) - char *kernel; - friostat_t **fiopp; - ips_stat_t **ipsstpp; - ipfrstat_t **ifrstpp; - ipf_authstat_t **frauthstpp; - u_32_t *frfp; +static void ipfstate_dead( char *kernel, friostat_t **fiopp, + ips_stat_t **ipsstpp, ipfrstat_t **ifrstpp, + ipf_authstat_t **frauthstpp, u_32_t *frfp) { static ipf_authstat_t frauthst, *frauthstp; static ipftq_t ipstcptab[IPF_TCP_NSTATES]; static ips_stat_t ipsst, *ipsstp; static ipfrstat_t ifrst, *ifrstp; static friostat_t fio, *fiop; int temp; void *rules[2][2]; struct nlist deadlist[44] = { { "ipf_auth_stats", 0, 0, 0, 0 }, /* 0 */ { "fae_list", 0, 0, 0, 0 }, { "ipauth", 0, 0, 0, 0 }, { "ipf_auth_list", 0, 0, 0, 0 }, { "ipf_auth_start", 0, 0, 0, 0 }, { "ipf_auth_end", 0, 0, 0, 0 }, /* 5 */ { "ipf_auth_next", 0, 0, 0, 0 }, { "ipf_auth", 0, 0, 0, 0 }, { "ipf_auth_used", 0, 0, 0, 0 }, { "ipf_auth_size", 0, 0, 0, 0 }, { "ipf_auth_defaultage", 0, 0, 0, 0 }, /* 10 */ { "ipf_auth_pkts", 0, 0, 0, 0 }, { "ipf_auth_lock", 0, 0, 0, 0 }, { "frstats", 0, 0, 0, 0 }, { "ips_stats", 0, 0, 0, 0 }, { "ips_num", 0, 0, 0, 0 }, /* 15 */ { "ips_wild", 0, 0, 0, 0 }, { "ips_list", 0, 0, 0, 0 }, { "ips_table", 0, 0, 0, 0 }, { "ipf_state_max", 0, 0, 0, 0 }, { "ipf_state_size", 0, 0, 0, 0 }, /* 20 */ { "ipf_state_doflush", 0, 0, 0, 0 }, { "ipf_state_lock", 0, 0, 0, 0 }, { "ipfr_heads", 0, 0, 0, 0 }, { "ipfr_nattab", 0, 0, 0, 0 }, { "ipfr_stats", 0, 0, 0, 0 }, /* 25 */ { "ipfr_inuse", 0, 0, 0, 0 }, { "ipf_ipfrttl", 0, 0, 0, 0 }, { "ipf_frag_lock", 0, 0, 0, 0 }, { "ipfr_timer_id", 0, 0, 0, 0 }, { "ipf_nat_lock", 0, 0, 0, 0 }, /* 30 */ { "ipf_rules", 0, 0, 0, 0 }, { "ipf_acct", 0, 0, 0, 0 }, { "ipl_frouteok", 0, 0, 0, 0 }, { "ipf_running", 0, 0, 0, 0 }, { "ipf_groups", 0, 0, 0, 0 }, /* 35 */ { "ipf_active", 0, 0, 0, 0 }, { "ipf_pass", 0, 0, 0, 0 }, { "ipf_flags", 0, 0, 0, 0 }, { "ipf_state_logging", 0, 0, 0, 0 }, { "ips_tqtqb", 0, 0, 0, 0 }, /* 40 */ { NULL, 0, 0, 0, 0 } }; frauthstp = &frauthst; ipsstp = &ipsst; ifrstp = &ifrst; fiop = &fio; *frfp = 0; *fiopp = fiop; *ipsstpp = ipsstp; *ifrstpp = ifrstp; *frauthstpp = frauthstp; bzero((char *)fiop, sizeof(*fiop)); bzero((char *)ipsstp, sizeof(*ipsstp)); bzero((char *)ifrstp, sizeof(*ifrstp)); bzero((char *)frauthstp, sizeof(*frauthstp)); if (nlist(kernel, deadlist) == -1) { fprintf(stderr, "nlist error\n"); return; } /* * This is for SIOCGETFF. */ kmemcpy((char *)frfp, (u_long)deadlist[40].n_value, sizeof(*frfp)); /* * f_locks is a combination of the lock variable from each part of * ipfilter (state, auth, nat, fragments). */ kmemcpy((char *)fiop, (u_long)deadlist[13].n_value, sizeof(*fiop)); kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[22].n_value, sizeof(fiop->f_locks[0])); kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[30].n_value, sizeof(fiop->f_locks[1])); kmemcpy((char *)&fiop->f_locks[2], (u_long)deadlist[28].n_value, sizeof(fiop->f_locks[2])); kmemcpy((char *)&fiop->f_locks[3], (u_long)deadlist[12].n_value, sizeof(fiop->f_locks[3])); /* * Get pointers to each list of rules (active, inactive, in, out) */ kmemcpy((char *)&rules, (u_long)deadlist[31].n_value, sizeof(rules)); fiop->f_fin[0] = rules[0][0]; fiop->f_fin[1] = rules[0][1]; fiop->f_fout[0] = rules[1][0]; fiop->f_fout[1] = rules[1][1]; /* * Now get accounting rules pointers. */ kmemcpy((char *)&rules, (u_long)deadlist[33].n_value, sizeof(rules)); fiop->f_acctin[0] = rules[0][0]; fiop->f_acctin[1] = rules[0][1]; fiop->f_acctout[0] = rules[1][0]; fiop->f_acctout[1] = rules[1][1]; /* * A collection of "global" variables used inside the kernel which * are all collected in friostat_t via ioctl. */ kmemcpy((char *)&fiop->f_froute, (u_long)deadlist[33].n_value, sizeof(fiop->f_froute)); kmemcpy((char *)&fiop->f_running, (u_long)deadlist[34].n_value, sizeof(fiop->f_running)); kmemcpy((char *)&fiop->f_groups, (u_long)deadlist[35].n_value, sizeof(fiop->f_groups)); kmemcpy((char *)&fiop->f_active, (u_long)deadlist[36].n_value, sizeof(fiop->f_active)); kmemcpy((char *)&fiop->f_defpass, (u_long)deadlist[37].n_value, sizeof(fiop->f_defpass)); /* * Build up the state information stats structure. */ kmemcpy((char *)ipsstp, (u_long)deadlist[14].n_value, sizeof(*ipsstp)); kmemcpy((char *)&temp, (u_long)deadlist[15].n_value, sizeof(temp)); kmemcpy((char *)ipstcptab, (u_long)deadlist[40].n_value, sizeof(ipstcptab)); ipsstp->iss_active = temp; ipsstp->iss_table = (void *)deadlist[18].n_value; ipsstp->iss_list = (void *)deadlist[17].n_value; ipsstp->iss_tcptab = ipstcptab; /* * Build up the authentiation information stats structure. */ kmemcpy((char *)frauthstp, (u_long)deadlist[0].n_value, sizeof(*frauthstp)); frauthstp->fas_faelist = (void *)deadlist[1].n_value; /* * Build up the fragment information stats structure. */ kmemcpy((char *)ifrstp, (u_long)deadlist[25].n_value, sizeof(*ifrstp)); ifrstp->ifs_table = (void *)deadlist[23].n_value; ifrstp->ifs_nattab = (void *)deadlist[24].n_value; kmemcpy((char *)&ifrstp->ifs_inuse, (u_long)deadlist[26].n_value, sizeof(ifrstp->ifs_inuse)); /* * Get logging on/off switches */ kmemcpy((char *)&state_logging, (u_long)deadlist[41].n_value, sizeof(state_logging)); } -static void printside(side, frs) - char *side; - ipf_statistics_t *frs; +static void printside(char *side, ipf_statistics_t *frs) { int i; PRINTF("%lu\t%s bad packets\n", frs->fr_bad, side); #ifdef USE_INET6 PRINTF("%lu\t%s IPv6 packets\n", frs->fr_ipv6, side); #endif PRINTF("%lu\t%s packets blocked\n", frs->fr_block, side); PRINTF("%lu\t%s packets passed\n", frs->fr_pass, side); PRINTF("%lu\t%s packets not matched\n", frs->fr_nom, side); PRINTF("%lu\t%s packets counted\n", frs->fr_acct, side); PRINTF("%lu\t%s packets short\n", frs->fr_short, side); PRINTF("%lu\t%s packets logged and blocked\n", frs->fr_bpkl, side); PRINTF("%lu\t%s packets logged and passed\n", frs->fr_ppkl, side); PRINTF("%lu\t%s fragment state kept\n", frs->fr_nfr, side); PRINTF("%lu\t%s fragment state lost\n", frs->fr_bnfr, side); PRINTF("%lu\t%s packet state kept\n", frs->fr_ads, side); PRINTF("%lu\t%s packet state lost\n", frs->fr_bads, side); PRINTF("%lu\t%s invalid source\n", frs->fr_v4_badsrc, side); PRINTF("%lu\t%s cache hits\n", frs->fr_chit, side); PRINTF("%lu\t%s cache misses\n", frs->fr_cmiss, side); PRINTF("%lu\t%s bad coalesces\n", frs->fr_badcoalesces, side); PRINTF("%lu\t%s pullups succeeded\n", frs->fr_pull[0], side); PRINTF("%lu\t%s pullups failed\n", frs->fr_pull[1], side); PRINTF("%lu\t%s TCP checksum failures\n", frs->fr_tcpbad, side); for (i = 0; i <= FRB_MAX_VALUE; i++) PRINTF("%lu\t%s block reason %s\n", frs->fr_blocked[i], side, blockreasons[i]); } /* * Display the kernel stats for packets blocked and passed and other * associated running totals which are kept. */ -static void showstats(fp, frf) - struct friostat *fp; - u_32_t frf; +static void showstats( struct friostat *fp, u_32_t frf) { printside("input", &fp->f_st[0]); printside("output", &fp->f_st[1]); PRINTF("%lu\tpackets logged\n", fp->f_log_ok); PRINTF("%lu\tlog failures\n", fp->f_log_fail); PRINTF("%lu\tred-black no memory\n", fp->f_rb_no_mem); PRINTF("%lu\tred-black node maximum\n", fp->f_rb_node_max); PRINTF("%lu\tICMP replies sent\n", fp->f_st[0].fr_ret); PRINTF("%lu\tTCP RSTs sent\n", fp->f_st[1].fr_ret); PRINTF("%lu\tfastroute successes\n", fp->f_froute[0]); PRINTF("%lu\tfastroute failures\n", fp->f_froute[1]); PRINTF("%u\tIPF Ticks\n", fp->f_ticks); PRINTF("%x\tPacket log flags set:\n", frf); if (frf & FF_LOGPASS) PRINTF("\tpackets passed through filter\n"); if (frf & FF_LOGBLOCK) PRINTF("\tpackets blocked by filter\n"); if (frf & FF_LOGNOMATCH) PRINTF("\tpackets not matched by filter\n"); if (!frf) PRINTF("\tnone\n"); } /* * Print out a list of rules from the kernel, starting at the one passed. */ static int -printlivelist(fiop, out, set, fp, group, comment) - struct friostat *fiop; - int out, set; - frentry_t *fp; - char *group, *comment; +printlivelist( struct friostat *fiop, int out, int set, frentry_t *fp, + char *group, char *comment) { struct frentry fb; ipfruleiter_t rule; frentry_t zero; frgroup_t *g; ipfobj_t obj; int rules; int num; rules = 0; rule.iri_inout = out; rule.iri_active = set; rule.iri_rule = &fb; rule.iri_nrules = 1; if (group != NULL) strncpy(rule.iri_group, group, FR_GROUPLEN); else rule.iri_group[0] = '\0'; bzero((char *)&zero, sizeof(zero)); bzero((char *)&obj, sizeof(obj)); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_IPFITER; obj.ipfo_size = sizeof(rule); obj.ipfo_ptr = &rule; while (rule.iri_rule != NULL) { u_long array[1000]; memset(array, 0xff, sizeof(array)); fp = (frentry_t *)array; rule.iri_rule = fp; if (ioctl(ipf_fd, SIOCIPFITER, &obj) == -1) { ipferror(ipf_fd, "ioctl(SIOCIPFITER)"); num = IPFGENITER_IPF; (void) ioctl(ipf_fd,SIOCIPFDELTOK, &num); return rules; } if (bcmp(fp, &zero, sizeof(zero)) == 0) break; if (rule.iri_rule == NULL) break; #ifdef USE_INET6 if (use_inet6 != 0 && use_inet4 == 0) { if (fp->fr_family != 0 && fp->fr_family != AF_INET6) continue; } else if (use_inet4 != 0 && use_inet6 == 0) { #endif if (fp->fr_family != 0 && fp->fr_family != AF_INET) continue; #ifdef USE_INET6 } else { if (fp->fr_family != 0 && fp->fr_family != AF_INET && fp->fr_family != AF_INET6) continue; } #endif if (fp->fr_data != NULL) fp->fr_data = (char *)fp + fp->fr_size; rules++; if (opts & (OPT_HITS|OPT_DEBUG)) #ifdef USE_QUAD_T PRINTF("%"PRIu64" ", (unsigned long long) fp->fr_hits); #else PRINTF("%lu ", fp->fr_hits); #endif if (opts & (OPT_ACCNT|OPT_DEBUG)) #ifdef USE_QUAD_T PRINTF("%"PRIu64" ", (unsigned long long) fp->fr_bytes); #else PRINTF("%lu ", fp->fr_bytes); #endif if (opts & OPT_SHOWLINENO) PRINTF("@%d ", rules); if (fp->fr_die != 0) fp->fr_die -= fiop->f_ticks; printfr(fp, ioctl); if (opts & OPT_DEBUG) { binprint(fp, fp->fr_size); if (fp->fr_data != NULL && fp->fr_dsize > 0) binprint(fp->fr_data, fp->fr_dsize); } if (fp->fr_grhead != -1) { for (g = grtop; g != NULL; g = g->fg_next) { if (!strncmp(fp->fr_names + fp->fr_grhead, g->fg_name, FR_GROUPLEN)) break; } if (g == NULL) { g = calloc(1, sizeof(*g)); if (g != NULL) { strncpy(g->fg_name, fp->fr_names + fp->fr_grhead, FR_GROUPLEN); if (grtop == NULL) { grtop = g; grtail = g; } else { grtail->fg_next = g; grtail = g; } } } } if (fp->fr_type == FR_T_CALLFUNC) { rules += printlivelist(fiop, out, set, fp->fr_data, group, "# callfunc: "); } } num = IPFGENITER_IPF; (void) ioctl(ipf_fd,SIOCIPFDELTOK, &num); return rules; } -static void printdeadlist(fiop, out, set, fp, group, comment) - friostat_t *fiop; - int out, set; - frentry_t *fp; - char *group, *comment; +static void printdeadlist(friostat_t *fiop, int out, int set, frentry_t *fp, + char *group, char *comment) { frgroup_t *grtop, *grtail, *g; struct frentry fb; char *data; u_32_t type; int n; fb.fr_next = fp; n = 0; grtop = NULL; grtail = NULL; for (n = 1; fp; fp = fb.fr_next, n++) { if (kmemcpy((char *)&fb, (u_long)fb.fr_next, fb.fr_size) == -1) { perror("kmemcpy"); return; } fp = &fb; #ifdef USE_INET6 if (use_inet6 != 0 && use_inet4 == 0) { if (fp->fr_family != 0 && fp->fr_family != AF_INET6) continue; } else if (use_inet4 != 0 && use_inet6 == 0) { #endif if (fp->fr_family != 0 && fp->fr_family != AF_INET) continue; #ifdef USE_INET6 } else { if (fp->fr_family != 0 && fp->fr_family != AF_INET && fp->fr_family != AF_INET6) continue; } #endif data = NULL; type = fb.fr_type & ~FR_T_BUILTIN; if (type == FR_T_IPF || type == FR_T_BPFOPC) { if (fb.fr_dsize) { data = malloc(fb.fr_dsize); if (kmemcpy(data, (u_long)fb.fr_data, fb.fr_dsize) == -1) { perror("kmemcpy"); return; } fb.fr_data = data; } } if (opts & OPT_HITS) #ifdef USE_QUAD_T PRINTF("%"PRIu64" ", (unsigned long long) fb.fr_hits); #else PRINTF("%lu ", fb.fr_hits); #endif if (opts & OPT_ACCNT) #ifdef USE_QUAD_T PRINTF("%"PRIu64" ", (unsigned long long) fb.fr_bytes); #else PRINTF("%lu ", fb.fr_bytes); #endif if (opts & OPT_SHOWLINENO) PRINTF("@%d ", n); printfr(fp, ioctl); if (opts & OPT_DEBUG) { binprint(fp, fp->fr_size); if (fb.fr_data != NULL && fb.fr_dsize > 0) binprint(fb.fr_data, fb.fr_dsize); } if (data != NULL) free(data); if (fb.fr_grhead != -1) { g = calloc(1, sizeof(*g)); if (g != NULL) { strncpy(g->fg_name, fb.fr_names + fb.fr_grhead, FR_GROUPLEN); if (grtop == NULL) { grtop = g; grtail = g; } else { grtail->fg_next = g; grtail = g; } } } if (type == FR_T_CALLFUNC) { printdeadlist(fiop, out, set, fb.fr_data, group, "# callfunc: "); } } while ((g = grtop) != NULL) { printdeadlist(fiop, out, set, NULL, g->fg_name, comment); grtop = g->fg_next; free(g); } } /* * print out all of the asked for rule sets, using the stats struct as * the base from which to get the pointers. */ -static void showlist(fiop) - struct friostat *fiop; +static void showlist(struct friostat *fiop) { struct frentry *fp = NULL; int i, set; set = fiop->f_active; if (opts & OPT_INACTIVE) set = 1 - set; if (opts & OPT_ACCNT) { if (opts & OPT_OUTQUE) { i = F_ACOUT; fp = (struct frentry *)fiop->f_acctout[set]; } else if (opts & OPT_INQUE) { i = F_ACIN; fp = (struct frentry *)fiop->f_acctin[set]; } else { FPRINTF(stderr, "No -i or -o given with -a\n"); return; } } else { if (opts & OPT_OUTQUE) { i = F_OUT; fp = (struct frentry *)fiop->f_fout[set]; } else if (opts & OPT_INQUE) { i = F_IN; fp = (struct frentry *)fiop->f_fin[set]; } else return; } if (opts & OPT_DEBUG) FPRINTF(stderr, "showlist:opts %#x i %d\n", opts, i); if (opts & OPT_DEBUG) PRINTF("fp %p set %d\n", fp, set); if (live_kernel == 1) { int printed; printed = printlivelist(fiop, i, set, fp, NULL, NULL); if (printed == 0) { FPRINTF(stderr, "# empty list for %s%s\n", (opts & OPT_INACTIVE) ? "inactive " : "", filters[i]); } } else { if (!fp) { FPRINTF(stderr, "# empty list for %s%s\n", (opts & OPT_INACTIVE) ? "inactive " : "", filters[i]); } else { printdeadlist(fiop, i, set, fp, NULL, NULL); } } } /* * Display ipfilter stateful filtering information */ -static void showipstates(ipsp, filter) - ips_stat_t *ipsp; - int *filter; +static void showipstates(ips_stat_t *ipsp, int *filter) { ipstate_t *is; int i; /* * If a list of states hasn't been asked for, only print out stats */ if (!(opts & OPT_SHOWLIST)) { showstatestats(ipsp); return; } if ((state_fields != NULL) && (nohdrfields == 0)) { for (i = 0; state_fields[i].w_value != 0; i++) { printfieldhdr(statefields, state_fields + i); if (state_fields[i + 1].w_value != 0) printf("\t"); } printf("\n"); } /* * Print out all the state information currently held in the kernel. */ for (is = ipsp->iss_list; is != NULL; ) { ipstate_t ips; is = fetchstate(is, &ips); if (is == NULL) break; is = ips.is_next; if ((filter != NULL) && (state_matcharray(&ips, filter) == 0)) { continue; } if (state_fields != NULL) { for (i = 0; state_fields[i].w_value != 0; i++) { printstatefield(&ips, state_fields[i].w_value); if (state_fields[i + 1].w_value != 0) printf("\t"); } printf("\n"); } else { printstate(&ips, opts, ipsp->iss_ticks); } } } -static void showstatestats(ipsp) - ips_stat_t *ipsp; +static void showstatestats(ips_stat_t *ipsp) { int minlen, maxlen, totallen; ipftable_t table; u_int *buckets; ipfobj_t obj; int i, sz; /* * If a list of states hasn't been asked for, only print out stats */ sz = sizeof(*buckets) * ipsp->iss_state_size; buckets = (u_int *)malloc(sz); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_GTABLE; obj.ipfo_size = sizeof(table); obj.ipfo_ptr = &table; table.ita_type = IPFTABLE_BUCKETS; table.ita_table = buckets; if (live_kernel == 1) { if (ioctl(state_fd, SIOCGTABL, &obj) != 0) { free(buckets); return; } } else { if (kmemcpy((char *)buckets, (u_long)ipsp->iss_bucketlen, sz)) { free(buckets); return; } } PRINTF("%u\tactive state table entries\n",ipsp->iss_active); PRINTF("%lu\tadd bad\n", ipsp->iss_add_bad); PRINTF("%lu\tadd duplicate\n", ipsp->iss_add_dup); PRINTF("%lu\tadd locked\n", ipsp->iss_add_locked); PRINTF("%lu\tadd oow\n", ipsp->iss_add_oow); PRINTF("%lu\tbucket full\n", ipsp->iss_bucket_full); PRINTF("%lu\tcheck bad\n", ipsp->iss_check_bad); PRINTF("%lu\tcheck miss\n", ipsp->iss_check_miss); PRINTF("%lu\tcheck nattag\n", ipsp->iss_check_nattag); PRINTF("%lu\tclone nomem\n", ipsp->iss_clone_nomem); PRINTF("%lu\tcheck notag\n", ipsp->iss_check_notag); PRINTF("%lu\tcheck success\n", ipsp->iss_hits); PRINTF("%lu\tcloned\n", ipsp->iss_cloned); PRINTF("%lu\texpired\n", ipsp->iss_expire); PRINTF("%lu\tflush all\n", ipsp->iss_flush_all); PRINTF("%lu\tflush closing\n", ipsp->iss_flush_closing); PRINTF("%lu\tflush queue\n", ipsp->iss_flush_queue); PRINTF("%lu\tflush state\n", ipsp->iss_flush_state); PRINTF("%lu\tflush timeout\n", ipsp->iss_flush_timeout); PRINTF("%u\thash buckets in use\n", ipsp->iss_inuse); PRINTF("%lu\tICMP bad\n", ipsp->iss_icmp_bad); PRINTF("%lu\tICMP banned\n", ipsp->iss_icmp_banned); PRINTF("%lu\tICMP errors\n", ipsp->iss_icmp_icmperr); PRINTF("%lu\tICMP head block\n", ipsp->iss_icmp_headblock); PRINTF("%lu\tICMP hits\n", ipsp->iss_icmp_hits); PRINTF("%lu\tICMP not query\n", ipsp->iss_icmp_notquery); PRINTF("%lu\tICMP short\n", ipsp->iss_icmp_short); PRINTF("%lu\tICMP too many\n", ipsp->iss_icmp_toomany); PRINTF("%lu\tICMPv6 errors\n", ipsp->iss_icmp6_icmperr); PRINTF("%lu\tICMPv6 miss\n", ipsp->iss_icmp6_miss); PRINTF("%lu\tICMPv6 not info\n", ipsp->iss_icmp6_notinfo); PRINTF("%lu\tICMPv6 not query\n", ipsp->iss_icmp6_notquery); PRINTF("%lu\tlog fail\n", ipsp->iss_log_fail); PRINTF("%lu\tlog ok\n", ipsp->iss_log_ok); PRINTF("%lu\tlookup interface mismatch\n", ipsp->iss_lookup_badifp); PRINTF("%lu\tlookup mask mismatch\n", ipsp->iss_miss_mask); PRINTF("%lu\tlookup port mismatch\n", ipsp->iss_lookup_badport); PRINTF("%lu\tlookup miss\n", ipsp->iss_lookup_miss); PRINTF("%lu\tmaximum rule references\n", ipsp->iss_max_ref); PRINTF("%lu\tmaximum hosts per rule\n", ipsp->iss_max_track); PRINTF("%lu\tno memory\n", ipsp->iss_nomem); PRINTF("%lu\tout of window\n", ipsp->iss_oow); PRINTF("%lu\torphans\n", ipsp->iss_orphan); PRINTF("%lu\tscan block\n", ipsp->iss_scan_block); PRINTF("%lu\tstate table maximum reached\n", ipsp->iss_max); PRINTF("%lu\tTCP closing\n", ipsp->iss_tcp_closing); PRINTF("%lu\tTCP OOW\n", ipsp->iss_tcp_oow); PRINTF("%lu\tTCP RST add\n", ipsp->iss_tcp_rstadd); PRINTF("%lu\tTCP too small\n", ipsp->iss_tcp_toosmall); PRINTF("%lu\tTCP bad options\n", ipsp->iss_tcp_badopt); PRINTF("%lu\tTCP removed\n", ipsp->iss_fin); PRINTF("%lu\tTCP FSM\n", ipsp->iss_tcp_fsm); PRINTF("%lu\tTCP strict\n", ipsp->iss_tcp_strict); PRINTF("%lu\tTCP wild\n", ipsp->iss_wild); PRINTF("%lu\tMicrosoft Windows SACK\n", ipsp->iss_winsack); PRINTF("State logging %sabled\n", state_logging ? "en" : "dis"); PRINTF("IP states added:\n"); for (i = 0; i < 256; i++) { if (ipsp->iss_proto[i] != 0) { struct protoent *proto; proto = getprotobynumber(i); PRINTF("%lu", ipsp->iss_proto[i]); if (proto != NULL) PRINTF("\t%s\n", proto->p_name); else PRINTF("\t%d\n", i); } } PRINTF("\nState table bucket statistics:\n"); PRINTF("%u\tin use\n", ipsp->iss_inuse); minlen = ipsp->iss_max; totallen = 0; maxlen = 0; for (i = 0; i < ipsp->iss_state_size; i++) { if (buckets[i] > maxlen) maxlen = buckets[i]; if (buckets[i] < minlen) minlen = buckets[i]; totallen += buckets[i]; } PRINTF("%d\thash efficiency\n", totallen ? ipsp->iss_inuse * 100 / totallen : 0); PRINTF("%2.2f%%\tbucket usage\n%u\tminimal length\n", ((float)ipsp->iss_inuse / ipsp->iss_state_size) * 100.0, minlen); PRINTF("%u\tmaximal length\n%.3f\taverage length\n", maxlen, ipsp->iss_inuse ? (float) totallen/ ipsp->iss_inuse : 0.0); #define ENTRIES_PER_LINE 5 if (opts & OPT_VERBOSE) { PRINTF("\nCurrent bucket sizes :\n"); for (i = 0; i < ipsp->iss_state_size; i++) { if ((i % ENTRIES_PER_LINE) == 0) PRINTF("\t"); PRINTF("%4d -> %4u", i, buckets[i]); if ((i % ENTRIES_PER_LINE) == (ENTRIES_PER_LINE - 1)) PRINTF("\n"); else PRINTF(" "); } PRINTF("\n"); } PRINTF("\n"); free(buckets); if (live_kernel == 1) { showtqtable_live(state_fd); } else { printtqtable(ipsp->iss_tcptab); } } #ifdef STATETOP static int handle_resize = 0, handle_break = 0; -static void topipstates(saddr, daddr, sport, dport, protocol, ver, - refreshtime, topclosed, filter) - i6addr_t saddr; - i6addr_t daddr; - int sport; - int dport; - int protocol; - int ver; - int refreshtime; - int topclosed; - int *filter; +static void topipstates(i6addr_t saddr, i6addr_t daddr, int sport, int dport, + int protocol, int ver, int refreshtime, int topclosed, int *filter) { char str1[STSTRSIZE], str2[STSTRSIZE], str3[STSTRSIZE], str4[STSTRSIZE]; int maxtsentries = 0, reverse = 0, sorting = STSORT_DEFAULT; int i, j, winy, tsentry, maxx, maxy, redraw = 0, ret = 0; int len, srclen, dstlen, forward = 1, c = 0; ips_stat_t ipsst, *ipsstp = &ipsst; int token_type = IPFGENITER_STATE; statetop_t *tstable = NULL, *tp; const char *errstr = ""; ipstate_t ips; ipfobj_t ipfo; struct timeval selecttimeout; char hostnm[HOSTNMLEN]; struct protoent *proto; fd_set readfd; time_t t; /* install signal handlers */ signal(SIGINT, sig_break); signal(SIGQUIT, sig_break); signal(SIGTERM, sig_break); signal(SIGWINCH, sig_resize); /* init ncurses stuff */ initscr(); cbreak(); noecho(); curs_set(0); timeout(0); getmaxyx(stdscr, maxy, maxx); /* init hostname */ gethostname(hostnm, sizeof(hostnm) - 1); hostnm[sizeof(hostnm) - 1] = '\0'; /* init ipfobj_t stuff */ bzero((caddr_t)&ipfo, sizeof(ipfo)); ipfo.ipfo_rev = IPFILTER_VERSION; ipfo.ipfo_type = IPFOBJ_STATESTAT; ipfo.ipfo_size = sizeof(*ipsstp); ipfo.ipfo_ptr = (void *)ipsstp; /* repeat until user aborts */ while ( 1 ) { /* get state table */ bzero((char *)&ipsst, sizeof(ipsst)); if ((ioctl(state_fd, SIOCGETFS, &ipfo) == -1)) { errstr = "ioctl(SIOCGETFS)"; ret = -1; goto out; } /* clear the history */ tsentry = -1; /* reset max str len */ srclen = dstlen = 0; /* read the state table and store in tstable */ for (; ipsstp->iss_list; ipsstp->iss_list = ips.is_next) { ipsstp->iss_list = fetchstate(ipsstp->iss_list, &ips); if (ipsstp->iss_list == NULL) break; if (ver != 0 && ips.is_v != ver) continue; if ((filter != NULL) && (state_matcharray(&ips, filter) == 0)) continue; /* check v4 src/dest addresses */ if (ips.is_v == 4) { if ((saddr.in4.s_addr != INADDR_ANY && saddr.in4.s_addr != ips.is_saddr) || (daddr.in4.s_addr != INADDR_ANY && daddr.in4.s_addr != ips.is_daddr)) continue; } #ifdef USE_INET6 /* check v6 src/dest addresses */ if (ips.is_v == 6) { if ((IP6_NEQ(&saddr, &in6addr_any) && IP6_NEQ(&saddr, &ips.is_src)) || (IP6_NEQ(&daddr, &in6addr_any) && IP6_NEQ(&daddr, &ips.is_dst))) continue; } #endif /* check protocol */ if (protocol > 0 && protocol != ips.is_p) continue; /* check ports if protocol is TCP or UDP */ if (((ips.is_p == IPPROTO_TCP) || (ips.is_p == IPPROTO_UDP)) && (((sport > 0) && (htons(sport) != ips.is_sport)) || ((dport > 0) && (htons(dport) != ips.is_dport)))) continue; /* show closed TCP sessions ? */ if ((topclosed == 0) && (ips.is_p == IPPROTO_TCP) && (ips.is_state[0] >= IPF_TCPS_LAST_ACK) && (ips.is_state[1] >= IPF_TCPS_LAST_ACK)) continue; /* * if necessary make room for this state * entry */ tsentry++; if (!maxtsentries || tsentry == maxtsentries) { maxtsentries += STGROWSIZE; tstable = reallocarray(tstable, maxtsentries, sizeof(statetop_t)); if (tstable == NULL) { perror("realloc"); exit(-1); } } /* get max src/dest address string length */ len = strlen(getip(ips.is_v, &ips.is_src)); if (srclen < len) srclen = len; len = strlen(getip(ips.is_v, &ips.is_dst)); if (dstlen < len) dstlen = len; /* fill structure */ tp = tstable + tsentry; tp->st_src = ips.is_src; tp->st_dst = ips.is_dst; tp->st_p = ips.is_p; tp->st_v = ips.is_v; tp->st_state[0] = ips.is_state[0]; tp->st_state[1] = ips.is_state[1]; if (forward) { tp->st_pkts = ips.is_pkts[0]+ips.is_pkts[1]; tp->st_bytes = ips.is_bytes[0]+ips.is_bytes[1]; } else { tp->st_pkts = ips.is_pkts[2]+ips.is_pkts[3]; tp->st_bytes = ips.is_bytes[2]+ips.is_bytes[3]; } tp->st_age = ips.is_die - ipsstp->iss_ticks; if ((ips.is_p == IPPROTO_TCP) || (ips.is_p == IPPROTO_UDP)) { tp->st_sport = ips.is_sport; tp->st_dport = ips.is_dport; } } (void) ioctl(state_fd, SIOCIPFDELTOK, &token_type); /* sort the array */ if (tsentry != -1) { switch (sorting) { case STSORT_PR: qsort(tstable, tsentry + 1, sizeof(statetop_t), sort_p); break; case STSORT_PKTS: qsort(tstable, tsentry + 1, sizeof(statetop_t), sort_pkts); break; case STSORT_BYTES: qsort(tstable, tsentry + 1, sizeof(statetop_t), sort_bytes); break; case STSORT_TTL: qsort(tstable, tsentry + 1, sizeof(statetop_t), sort_ttl); break; case STSORT_SRCIP: qsort(tstable, tsentry + 1, sizeof(statetop_t), sort_srcip); break; case STSORT_SRCPT: qsort(tstable, tsentry +1, sizeof(statetop_t), sort_srcpt); break; case STSORT_DSTIP: qsort(tstable, tsentry + 1, sizeof(statetop_t), sort_dstip); break; case STSORT_DSTPT: qsort(tstable, tsentry + 1, sizeof(statetop_t), sort_dstpt); break; default: break; } } /* handle window resizes */ if (handle_resize) { endwin(); initscr(); cbreak(); noecho(); curs_set(0); timeout(0); getmaxyx(stdscr, maxy, maxx); redraw = 1; handle_resize = 0; } /* stop program? */ if (handle_break) break; /* print title */ erase(); attron(A_BOLD); winy = 0; move(winy,0); snprintf(str1, sizeof(str1), "%s - %s - state top", hostnm, IPL_VERSION); for (j = 0 ; j < (maxx - 8 - strlen(str1)) / 2; j++) printw(" "); printw("%s", str1); attroff(A_BOLD); /* just for fun add a clock */ move(winy, maxx - 8); t = time(NULL); strftime(str1, 80, "%T", localtime(&t)); printw("%s\n", str1); /* * print the display filters, this is placed in the loop, * because someday I might add code for changing these * while the programming is running :-) */ if (sport >= 0) snprintf(str1, sizeof(str1), "%s,%d", getip(ver, &saddr), sport); else snprintf(str1, sizeof(str1), "%s", getip(ver, &saddr)); if (dport >= 0) snprintf(str2, sizeof(str2), "%s,%d", getip(ver, &daddr), dport); else snprintf(str2, sizeof(str2), "%s", getip(ver, &daddr)); if (protocol < 0) strcpy(str3, "any"); else if ((proto = getprotobynumber(protocol)) != NULL) snprintf(str3, sizeof(str3), "%s", proto->p_name); else snprintf(str3, sizeof(str3), "%d", protocol); switch (sorting) { case STSORT_PR: snprintf(str4, sizeof(str4), "proto"); break; case STSORT_PKTS: snprintf(str4, sizeof(str4), "# pkts"); break; case STSORT_BYTES: snprintf(str4, sizeof(str4), "# bytes"); break; case STSORT_TTL: snprintf(str4, sizeof(str4), "ttl"); break; case STSORT_SRCIP: snprintf(str4, sizeof(str4), "src ip"); break; case STSORT_SRCPT: snprintf(str4, sizeof(str4), "src port"); break; case STSORT_DSTIP: snprintf(str4, sizeof(str4), "dest ip"); break; case STSORT_DSTPT: snprintf(str4, sizeof(str4), "dest port"); break; default: snprintf(str4, sizeof(str4), "unknown"); break; } if (reverse) strcat(str4, " (reverse)"); winy += 2; move(winy,0); printw("Src: %s, Dest: %s, Proto: %s, Sorted by: %s\n\n", str1, str2, str3, str4); /* * For an IPv4 IP address we need at most 15 characters, * 4 tuples of 3 digits, separated by 3 dots. Enforce this * length, so the colums do not change positions based * on the size of the IP address. This length makes the * output fit in a 80 column terminal. * We are lacking a good solution for IPv6 addresses (that * can be longer that 15 characters), so we do not enforce * a maximum on the IP field size. */ if (srclen < 15) srclen = 15; if (dstlen < 15) dstlen = 15; /* print column description */ winy += 2; move(winy,0); attron(A_BOLD); printw("%-*s %-*s %3s %4s %7s %9s %9s\n", srclen + 6, "Source IP", dstlen + 6, "Destination IP", "ST", "PR", "#pkts", "#bytes", "ttl"); attroff(A_BOLD); /* print all the entries */ tp = tstable; if (reverse) tp += tsentry; if (tsentry > maxy - 6) tsentry = maxy - 6; for (i = 0; i <= tsentry; i++) { /* print src/dest and port */ if ((tp->st_p == IPPROTO_TCP) || (tp->st_p == IPPROTO_UDP)) { snprintf(str1, sizeof(str1), "%s,%hu", getip(tp->st_v, &tp->st_src), ntohs(tp->st_sport)); snprintf(str2, sizeof(str2), "%s,%hu", getip(tp->st_v, &tp->st_dst), ntohs(tp->st_dport)); } else { snprintf(str1, sizeof(str1), "%s", getip(tp->st_v, &tp->st_src)); snprintf(str2, sizeof(str2), "%s", getip(tp->st_v, &tp->st_dst)); } winy++; move(winy, 0); printw("%-*s %-*s", srclen + 6, str1, dstlen + 6, str2); /* print state */ snprintf(str1, sizeof(str1), "%X/%X", tp->st_state[0], tp->st_state[1]); printw(" %3s", str1); /* print protocol */ proto = getprotobynumber(tp->st_p); if (proto) { strncpy(str1, proto->p_name, 4); str1[4] = '\0'; } else { snprintf(str1, sizeof(str1), "%d", tp->st_p); } /* just print icmp for IPv6-ICMP */ if (tp->st_p == IPPROTO_ICMPV6) strcpy(str1, "icmp"); printw(" %4s", str1); /* print #pkt/#bytes */ #ifdef USE_QUAD_T printw(" %7qu %9qu", (unsigned long long) tp->st_pkts, (unsigned long long) tp->st_bytes); #else printw(" %7lu %9lu", tp->st_pkts, tp->st_bytes); #endif printw(" %9s", ttl_to_string(tp->st_age)); if (reverse) tp--; else tp++; } /* screen data structure is filled, now update the screen */ if (redraw) clearok(stdscr,1); if (refresh() == ERR) break; if (redraw) { clearok(stdscr,0); redraw = 0; } /* wait for key press or a 1 second time out period */ selecttimeout.tv_sec = refreshtime; selecttimeout.tv_usec = 0; FD_ZERO(&readfd); FD_SET(0, &readfd); select(1, &readfd, NULL, NULL, &selecttimeout); /* if key pressed, read all waiting keys */ if (FD_ISSET(0, &readfd)) { c = wgetch(stdscr); if (c == ERR) continue; if (ISALPHA(c) && ISUPPER(c)) c = TOLOWER(c); if (c == 'l') { redraw = 1; } else if (c == 'q') { break; } else if (c == 'r') { reverse = !reverse; } else if (c == 'b') { forward = 0; } else if (c == 'f') { forward = 1; } else if (c == 's') { if (++sorting > STSORT_MAX) sorting = 0; } } } /* while */ out: printw("\n"); curs_set(1); /* nocbreak(); XXX - endwin() should make this redundant */ endwin(); free(tstable); if (ret != 0) perror(errstr); } #endif /* * Show fragment cache information that's held in the kernel. */ -static void showfrstates(ifsp, ticks) - ipfrstat_t *ifsp; - u_long ticks; +static void showfrstates(ipfrstat_t *ifsp, u_long ticks) { struct ipfr *ipfrtab[IPFT_SIZE], ifr; int i; /* * print out the numeric statistics */ PRINTF("IP fragment states:\n%lu\tnew\n%lu\texpired\n%lu\thits\n", ifsp->ifs_new, ifsp->ifs_expire, ifsp->ifs_hits); PRINTF("%lu\tretrans\n%lu\ttoo short\n", ifsp->ifs_retrans0, ifsp->ifs_short); PRINTF("%lu\tno memory\n%lu\talready exist\n", ifsp->ifs_nomem, ifsp->ifs_exists); PRINTF("%lu\tinuse\n", ifsp->ifs_inuse); PRINTF("\n"); if (live_kernel == 0) { if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_table, sizeof(ipfrtab))) return; } /* * Print out the contents (if any) of the fragment cache table. */ if (live_kernel == 1) { do { if (fetchfrag(ipf_fd, IPFGENITER_FRAG, &ifr) != 0) break; if (ifr.ipfr_ifp == NULL) break; ifr.ipfr_ttl -= ticks; printfraginfo("", &ifr); } while (ifr.ipfr_next != NULL); } else { for (i = 0; i < IPFT_SIZE; i++) while (ipfrtab[i] != NULL) { if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i], sizeof(ifr)) == -1) break; printfraginfo("", &ifr); ipfrtab[i] = ifr.ipfr_next; } } /* * Print out the contents (if any) of the NAT fragment cache table. */ if (live_kernel == 0) { if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_nattab, sizeof(ipfrtab))) return; } if (live_kernel == 1) { do { if (fetchfrag(nat_fd, IPFGENITER_NATFRAG, &ifr) != 0) break; if (ifr.ipfr_ifp == NULL) break; ifr.ipfr_ttl -= ticks; printfraginfo("NAT: ", &ifr); } while (ifr.ipfr_next != NULL); } else { for (i = 0; i < IPFT_SIZE; i++) while (ipfrtab[i] != NULL) { if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i], sizeof(ifr)) == -1) break; printfraginfo("NAT: ", &ifr); ipfrtab[i] = ifr.ipfr_next; } } } /* * Show stats on how auth within IPFilter has been used */ -static void showauthstates(asp) - ipf_authstat_t *asp; +static void showauthstates(ipf_authstat_t *asp) { frauthent_t *frap, fra; ipfgeniter_t auth; ipfobj_t obj; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_GENITER; obj.ipfo_size = sizeof(auth); obj.ipfo_ptr = &auth; auth.igi_type = IPFGENITER_AUTH; auth.igi_nitems = 1; auth.igi_data = &fra; #ifdef USE_QUAD_T printf("Authorisation hits: %"PRIu64"\tmisses %"PRIu64"\n", (unsigned long long) asp->fas_hits, (unsigned long long) asp->fas_miss); #else printf("Authorisation hits: %ld\tmisses %ld\n", asp->fas_hits, asp->fas_miss); #endif printf("nospace %ld\nadded %ld\nsendfail %ld\nsendok %ld\n", asp->fas_nospace, asp->fas_added, asp->fas_sendfail, asp->fas_sendok); printf("queok %ld\nquefail %ld\nexpire %ld\n", asp->fas_queok, asp->fas_quefail, asp->fas_expire); frap = asp->fas_faelist; while (frap) { if (live_kernel == 1) { if (ioctl(auth_fd, SIOCGENITER, &obj)) break; } else { if (kmemcpy((char *)&fra, (u_long)frap, sizeof(fra)) == -1) break; } printf("age %ld\t", fra.fae_age); printfr(&fra.fae_fr, ioctl); frap = fra.fae_next; } } /* * Display groups used for each of filter rules, accounting rules and * authentication, separately. */ -static void showgroups(fiop) - struct friostat *fiop; +static void showgroups(struct friostat *fiop) { static char *gnames[3] = { "Filter", "Accounting", "Authentication" }; static int gnums[3] = { IPL_LOGIPF, IPL_LOGCOUNT, IPL_LOGAUTH }; frgroup_t *fp, grp; int on, off, i; on = fiop->f_active; off = 1 - on; for (i = 0; i < 3; i++) { printf("%s groups (active):\n", gnames[i]); for (fp = fiop->f_groups[gnums[i]][on]; fp != NULL; fp = grp.fg_next) if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp))) break; else printf("%s\n", grp.fg_name); printf("%s groups (inactive):\n", gnames[i]); for (fp = fiop->f_groups[gnums[i]][off]; fp != NULL; fp = grp.fg_next) if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp))) break; else printf("%s\n", grp.fg_name); } } -static void parse_ipportstr(argument, ip, port) - const char *argument; - i6addr_t *ip; - int *port; +static void parse_ipportstr(const char *argument, i6addr_t *ip, int *port) { char *s, *comma; int ok = 0; /* make working copy of argument, Theoretically you must be able * to write to optarg, but that seems very ugly to me.... */ s = strdup(argument); if (s == NULL) return; /* get port */ if ((comma = strchr(s, ',')) != NULL) { if (!strcasecmp(comma + 1, "any")) { *port = -1; } else if (!sscanf(comma + 1, "%d", port) || (*port < 0) || (*port > 65535)) { fprintf(stderr, "Invalid port specification in %s\n", argument); free(s); exit(-2); } *comma = '\0'; } /* get ip address */ if (!strcasecmp(s, "any")) { ip->in4.s_addr = INADDR_ANY; ok = 1; #ifdef USE_INET6 ip->in6 = in6addr_any; } else if (use_inet6 && !use_inet4 && inet_pton(AF_INET6, s, &ip->in6)) { ok = 1; #endif } else if (inet_aton(s, &ip->in4)) ok = 1; if (ok == 0) { fprintf(stderr, "Invalid IP address: %s\n", s); free(s); exit(-2); } /* free allocated memory */ free(s); } #ifdef STATETOP -static void sig_resize(s) - int s; +static void sig_resize(int s) { handle_resize = 1; } -static void sig_break(s) - int s; +static void sig_break(int s) { handle_break = 1; } -static char *getip(v, addr) - int v; - i6addr_t *addr; +static char *getip(int v, i6addr_t *addr) { #ifdef USE_INET6 static char hostbuf[MAXHOSTNAMELEN+1]; #endif if (v == 0) return ("any"); if (v == 4) return inet_ntoa(addr->in4); #ifdef USE_INET6 (void) inet_ntop(AF_INET6, &addr->in6, hostbuf, sizeof(hostbuf) - 1); hostbuf[MAXHOSTNAMELEN] = '\0'; return hostbuf; #else return "IPv6"; #endif } -static char *ttl_to_string(ttl) - long int ttl; +static char *ttl_to_string(long int ttl) { static char ttlbuf[STSTRSIZE]; int hours, minutes, seconds; /* ttl is in half seconds */ ttl /= 2; hours = ttl / 3600; ttl = ttl % 3600; minutes = ttl / 60; seconds = ttl % 60; if (hours > 0) snprintf(ttlbuf, sizeof(ttlbuf), "%2d:%02d:%02d", hours, minutes, seconds); else snprintf(ttlbuf, sizeof(ttlbuf), "%2d:%02d", minutes, seconds); return ttlbuf; } -static int sort_pkts(a, b) - const void *a; - const void *b; +static int sort_pkts(const void *a, const void *b) { register const statetop_t *ap = a; register const statetop_t *bp = b; if (ap->st_pkts == bp->st_pkts) return 0; else if (ap->st_pkts < bp->st_pkts) return 1; return -1; } -static int sort_bytes(a, b) - const void *a; - const void *b; +static int sort_bytes(const void *a, const void *b) { register const statetop_t *ap = a; register const statetop_t *bp = b; if (ap->st_bytes == bp->st_bytes) return 0; else if (ap->st_bytes < bp->st_bytes) return 1; return -1; } -static int sort_p(a, b) - const void *a; - const void *b; +static int sort_p(const void *a, const void *b) { register const statetop_t *ap = a; register const statetop_t *bp = b; if (ap->st_p == bp->st_p) return 0; else if (ap->st_p < bp->st_p) return 1; return -1; } -static int sort_ttl(a, b) - const void *a; - const void *b; +static int sort_ttl(const void *a, const void *b) { register const statetop_t *ap = a; register const statetop_t *bp = b; if (ap->st_age == bp->st_age) return 0; else if (ap->st_age < bp->st_age) return 1; return -1; } -static int sort_srcip(a, b) - const void *a; - const void *b; +static int sort_srcip(const void *a, const void *b) { register const statetop_t *ap = a; register const statetop_t *bp = b; #ifdef USE_INET6 if (use_inet6 && !use_inet4) { if (IP6_EQ(&ap->st_src, &bp->st_src)) return 0; else if (IP6_GT(&ap->st_src, &bp->st_src)) return 1; } else #endif { if (ntohl(ap->st_src.in4.s_addr) == ntohl(bp->st_src.in4.s_addr)) return 0; else if (ntohl(ap->st_src.in4.s_addr) > ntohl(bp->st_src.in4.s_addr)) return 1; } return -1; } -static int sort_srcpt(a, b) - const void *a; - const void *b; +static int sort_srcpt(const void *a, const void *b) { register const statetop_t *ap = a; register const statetop_t *bp = b; if (htons(ap->st_sport) == htons(bp->st_sport)) return 0; else if (htons(ap->st_sport) > htons(bp->st_sport)) return 1; return -1; } -static int sort_dstip(a, b) - const void *a; - const void *b; +static int sort_dstip(const void *a, const void *b) { register const statetop_t *ap = a; register const statetop_t *bp = b; #ifdef USE_INET6 if (use_inet6 && !use_inet4) { if (IP6_EQ(&ap->st_dst, &bp->st_dst)) return 0; else if (IP6_GT(&ap->st_dst, &bp->st_dst)) return 1; } else #endif { if (ntohl(ap->st_dst.in4.s_addr) == ntohl(bp->st_dst.in4.s_addr)) return 0; else if (ntohl(ap->st_dst.in4.s_addr) > ntohl(bp->st_dst.in4.s_addr)) return 1; } return -1; } -static int sort_dstpt(a, b) - const void *a; - const void *b; +static int sort_dstpt(const void *a, const void *b) { register const statetop_t *ap = a; register const statetop_t *bp = b; if (htons(ap->st_dport) == htons(bp->st_dport)) return 0; else if (htons(ap->st_dport) > htons(bp->st_dport)) return 1; return -1; } #endif -ipstate_t *fetchstate(src, dst) - ipstate_t *src, *dst; +ipstate_t *fetchstate(ipstate_t *src, ipstate_t *dst) { if (live_kernel == 1) { ipfgeniter_t state; ipfobj_t obj; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_GENITER; obj.ipfo_size = sizeof(state); obj.ipfo_ptr = &state; state.igi_type = IPFGENITER_STATE; state.igi_nitems = 1; state.igi_data = dst; if (ioctl(state_fd, SIOCGENITER, &obj) != 0) return NULL; if (dst->is_next == NULL) { int n = IPFGENITER_STATE; (void) ioctl(ipf_fd,SIOCIPFDELTOK, &n); } } else { if (kmemcpy((char *)dst, (u_long)src, sizeof(*dst))) return NULL; } return dst; } -static int fetchfrag(fd, type, frp) - int fd, type; - ipfr_t *frp; +static int fetchfrag( int fd, int type, ipfr_t *frp) { ipfgeniter_t frag; ipfobj_t obj; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_GENITER; obj.ipfo_size = sizeof(frag); obj.ipfo_ptr = &frag; frag.igi_type = type; frag.igi_nitems = 1; frag.igi_data = frp; if (ioctl(fd, SIOCGENITER, &obj)) return EFAULT; return 0; } -static int state_matcharray(stp, array) - ipstate_t *stp; - int *array; +static int state_matcharray(ipstate_t *stp, int *array) { int i, n, *x, rv, p; ipfexp_t *e; rv = 0; for (n = array[0], x = array + 1; n > 0; x += e->ipfe_size) { e = (ipfexp_t *)x; if (e->ipfe_cmd == IPF_EXP_END) break; n -= e->ipfe_size; rv = 0; /* * The upper 16 bits currently store the protocol value. * This is currently used with TCP and UDP port compares and * allows "tcp.port = 80" without requiring an explicit " "ip.pr = tcp" first. */ p = e->ipfe_cmd >> 16; if ((p != 0) && (p != stp->is_p)) break; switch (e->ipfe_cmd) { case IPF_EXP_IP_PR : for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= (stp->is_p == e->ipfe_arg0[i]); } break; case IPF_EXP_IP_SRCADDR : if (stp->is_v != 4) break; for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= ((stp->is_saddr & e->ipfe_arg0[i * 2 + 1]) == e->ipfe_arg0[i * 2]); } break; case IPF_EXP_IP_DSTADDR : if (stp->is_v != 4) break; for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= ((stp->is_daddr & e->ipfe_arg0[i * 2 + 1]) == e->ipfe_arg0[i * 2]); } break; case IPF_EXP_IP_ADDR : if (stp->is_v != 4) break; for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= ((stp->is_saddr & e->ipfe_arg0[i * 2 + 1]) == e->ipfe_arg0[i * 2]) || ((stp->is_daddr & e->ipfe_arg0[i * 2 + 1]) == e->ipfe_arg0[i * 2]); } break; #ifdef USE_INET6 case IPF_EXP_IP6_SRCADDR : if (stp->is_v != 6) break; for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= IP6_MASKEQ(&stp->is_src, &e->ipfe_arg0[i * 8 + 4], &e->ipfe_arg0[i * 8]); } break; case IPF_EXP_IP6_DSTADDR : if (stp->is_v != 6) break; for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= IP6_MASKEQ(&stp->is_dst, &e->ipfe_arg0[i * 8 + 4], &e->ipfe_arg0[i * 8]); } break; case IPF_EXP_IP6_ADDR : if (stp->is_v != 6) break; for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= IP6_MASKEQ(&stp->is_src, &e->ipfe_arg0[i * 8 + 4], &e->ipfe_arg0[i * 8]) || IP6_MASKEQ(&stp->is_dst, &e->ipfe_arg0[i * 8 + 4], &e->ipfe_arg0[i * 8]); } break; #endif case IPF_EXP_UDP_PORT : case IPF_EXP_TCP_PORT : for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= (stp->is_sport == e->ipfe_arg0[i]) || (stp->is_dport == e->ipfe_arg0[i]); } break; case IPF_EXP_UDP_SPORT : case IPF_EXP_TCP_SPORT : for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= (stp->is_sport == e->ipfe_arg0[i]); } break; case IPF_EXP_UDP_DPORT : case IPF_EXP_TCP_DPORT : for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= (stp->is_dport == e->ipfe_arg0[i]); } break; case IPF_EXP_IDLE_GT : for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= (stp->is_die < e->ipfe_arg0[i]); } break; case IPF_EXP_TCP_STATE : for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= (stp->is_state[0] == e->ipfe_arg0[i]) || (stp->is_state[1] == e->ipfe_arg0[i]); } break; } rv ^= e->ipfe_not; if (rv == 0) break; } return rv; } -static void showtqtable_live(fd) - int fd; +static void showtqtable_live(int fd) { ipftq_t table[IPF_TCP_NSTATES]; ipfobj_t obj; bzero((char *)&obj, sizeof(obj)); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_size = sizeof(table); obj.ipfo_ptr = (void *)table; obj.ipfo_type = IPFOBJ_STATETQTAB; if (ioctl(fd, SIOCGTQTAB, &obj) == 0) { printtqtable(table); } } diff --git a/sbin/ipf/ipftest/ipftest.c b/sbin/ipf/ipftest/ipftest.c index d7f97c1fa66b..df77dd650ffa 100644 --- a/sbin/ipf/ipftest/ipftest.c +++ b/sbin/ipf/ipftest/ipftest.c @@ -1,716 +1,715 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" #include "ipt.h" #include #include #if !defined(lint) static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-2000 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif extern char *optarg; extern struct ipread pcap, iptext, iphex; extern struct ifnet *get_unit(char *, int); extern void init_ifp(void); extern ipnat_t *natparse(char *, int); extern hostmap_t **ipf_hm_maptable; extern hostmap_t *ipf_hm_maplist; ipfmutex_t ipl_mutex, ipf_auth_mx, ipf_rw, ipf_stinsert; ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock; ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag, ip_poolrw, ipf_frcache; ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_authlk; ipfrwlock_t ipf_tokens; int opts = OPT_DONTOPEN; int use_inet6 = 0; int docksum = 0; int pfil_delayed_copy = 0; int main(int, char *[]); int loadrules(char *, int); int kmemcpy(char *, long, int); int kstrncpy(char *, long, int n); int blockreason; void dumpnat(void *); void dumpgroups(ipf_main_softc_t *); void dumprules(frentry_t *); void drain_log(char *); void fixv4sums(mb_t *, ip_t *); int ipftestioctl(int, ioctlcmd_t, ...); int ipnattestioctl(int, ioctlcmd_t, ...); int ipstatetestioctl(int, ioctlcmd_t, ...); int ipauthtestioctl(int, ioctlcmd_t, ...); int ipscantestioctl(int, ioctlcmd_t, ...); int ipsynctestioctl(int, ioctlcmd_t, ...); int ipooltestioctl(int, ioctlcmd_t, ...); static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ipftestioctl, ipnattestioctl, ipstatetestioctl, ipauthtestioctl, ipsynctestioctl, ipscantestioctl, ipooltestioctl, NULL }; static ipf_main_softc_t *softc = NULL; int -main(argc,argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { char *datain, *iface, *ifname, *logout; int fd, i, dir, c, loaded, dump, hlen; struct in_addr sip; struct ifnet *ifp; struct ipread *r; mb_t mb, *m, *n; ip_t *ip; m = &mb; dir = 0; dump = 0; hlen = 0; loaded = 0; r = &iptext; iface = NULL; logout = NULL; datain = NULL; sip.s_addr = 0; ifname = "anon0"; initparse(); ipf_load_all(); softc = ipf_create_all(NULL); if (softc == NULL) exit(1); if (ipf_init_all(softc) == -1) exit(1); i = 1; if (ipftestioctl(IPL_LOGIPF, SIOCFRENB, &i) != 0) exit(1); while ((c = getopt(argc, argv, "6bCdDF:i:I:l:N:P:or:RS:T:vxX")) != -1) switch (c) { case '6' : #ifdef USE_INET6 use_inet6 = 1; #else fprintf(stderr, "IPv6 not supported\n"); exit(1); #endif break; case 'b' : opts |= OPT_BRIEF; break; case 'd' : opts |= OPT_DEBUG; break; case 'C' : docksum = 1; break; case 'D' : dump = 1; break; case 'F' : if (strcasecmp(optarg, "pcap") == 0) r = &pcap; else if (strcasecmp(optarg, "hex") == 0) r = &iphex; else if (strcasecmp(optarg, "text") == 0) r = &iptext; break; case 'i' : datain = optarg; break; case 'I' : ifname = optarg; break; case 'l' : logout = optarg; break; case 'N' : if (ipnat_parsefile(-1, ipnat_addrule, ipnattestioctl, optarg) == -1) return -1; loaded = 1; opts |= OPT_NAT; break; case 'o' : opts |= OPT_SAVEOUT; break; case 'P' : if (ippool_parsefile(-1, optarg, ipooltestioctl) == -1) return -1; loaded = 1; break; case 'r' : if (ipf_parsefile(-1, ipf_addrule, iocfunctions, optarg) == -1) return -1; loaded = 1; break; case 'S' : sip.s_addr = inet_addr(optarg); break; case 'R' : opts |= OPT_NORESOLVE; break; case 'T' : ipf_dotuning(-1, optarg, ipftestioctl); break; case 'v' : opts |= OPT_VERBOSE; break; case 'x' : opts |= OPT_HEX; break; } if (loaded == 0) { (void)fprintf(stderr,"no rules loaded\n"); exit(-1); } if (opts & OPT_SAVEOUT) init_ifp(); if (datain) fd = (*r->r_open)(datain); else fd = (*r->r_open)("-"); if (fd < 0) { perror("error opening input"); exit(-1); } m->m_data = (char *)m->mb_buf; while ((i = (*r->r_readip)(m, &iface, &dir)) > 0) { if ((iface == NULL) || (*iface == '\0')) iface = ifname; ip = MTOD(m, ip_t *); ifp = get_unit(iface, IP_V(ip)); if (IP_V(ip) == 4) { if ((r->r_flags & R_DO_CKSUM) || docksum) fixv4sums(m, ip); hlen = IP_HL(ip) << 2; if (sip.s_addr) dir = !(sip.s_addr == ip->ip_src.s_addr); } #ifdef USE_INET6 else hlen = sizeof(ip6_t); #endif /* ipfr_slowtimer(); */ blockreason = 0; m = &mb; m->mb_ifp = ifp; m->mb_len = i; i = ipf_check(softc, ip, hlen, ifp, dir, &m); if ((opts & OPT_NAT) == 0) switch (i) { case -4 : (void)printf("preauth"); break; case -3 : (void)printf("account"); break; case -2 : (void)printf("auth"); break; case -1 : (void)printf("block"); break; case 0 : (void)printf("pass"); break; case 1 : if (m == NULL) (void)printf("bad-packet"); else (void)printf("nomatch"); break; case 3 : (void)printf("block return-rst"); break; case 4 : (void)printf("block return-icmp"); break; case 5 : (void)printf("block return-icmp-as-dest"); break; default : (void)printf("recognised return %#x\n", i); break; } if (!(opts & OPT_BRIEF)) { putchar(' '); if (m != NULL) printpacket(dir, m); else printpacket(dir, &mb); printf("--------------"); } else if ((opts & (OPT_BRIEF|OPT_NAT)) == (OPT_NAT|OPT_BRIEF)) { if (m != NULL) printpacket(dir, m); else PRINTF("%d\n", blockreason); } ipf_state_flush(softc, 1, 0); if (dir && (ifp != NULL) && IP_V(ip) && (m != NULL)) (*ifp->if_output)(ifp, (void *)m, NULL, 0); while ((m != NULL) && (m != &mb)) { n = m->mb_next; freembt(m); m = n; } if ((opts & (OPT_BRIEF|OPT_NAT)) != (OPT_NAT|OPT_BRIEF)) putchar('\n'); dir = 0; if (iface != ifname) { free(iface); iface = ifname; } m = &mb; m->mb_data = (char *)m->mb_buf; } if (i != 0) fprintf(stderr, "readip failed: %d\n", i); (*r->r_close)(); if (logout != NULL) { drain_log(logout); } if (dump == 1) { dumpnat(softc->ipf_nat_soft); ipf_state_dump(softc, softc->ipf_state_soft); ipf_lookup_dump(softc, softc->ipf_state_soft); dumpgroups(softc); } ipf_fini_all(softc); ipf_destroy_all(softc); ipf_unload_all(); ipf_mutex_clean(); ipf_rwlock_clean(); if (getenv("FINDLEAKS")) { fflush(stdout); abort(); } return 0; } int ipftestioctl(int dev, ioctlcmd_t cmd, ...) { caddr_t data; va_list ap; int i; dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); i = ipfioctl(softc, IPL_LOGIPF, cmd, data, FWRITE|FREAD); if (opts & OPT_DEBUG) fprintf(stderr, "ipfioctl(IPF,%#x,%p) = %d (%d)\n", (u_int)cmd, data, i, softc->ipf_interror); if (i != 0) { errno = i; return -1; } return 0; } -int ipnattestioctl(int dev, ioctlcmd_t cmd, ...) +int +ipnattestioctl(int dev, ioctlcmd_t cmd, ...) { caddr_t data; va_list ap; int i; dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); i = ipfioctl(softc, IPL_LOGNAT, cmd, data, FWRITE|FREAD); if (opts & OPT_DEBUG) fprintf(stderr, "ipfioctl(NAT,%#x,%p) = %d\n", (u_int)cmd, data, i); if (i != 0) { errno = i; return -1; } return 0; } -int ipstatetestioctl(int dev, ioctlcmd_t cmd, ...) +int +ipstatetestioctl(int dev, ioctlcmd_t cmd, ...) { caddr_t data; va_list ap; int i; dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); i = ipfioctl(softc, IPL_LOGSTATE, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) fprintf(stderr, "ipfioctl(STATE,%#x,%p) = %d\n", (u_int)cmd, data, i); if (i != 0) { errno = i; return -1; } return 0; } -int ipauthtestioctl(int dev, ioctlcmd_t cmd, ...) +int +ipauthtestioctl(int dev, ioctlcmd_t cmd, ...) { caddr_t data; va_list ap; int i; dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); i = ipfioctl(softc, IPL_LOGAUTH, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) fprintf(stderr, "ipfioctl(AUTH,%#x,%p) = %d\n", (u_int)cmd, data, i); if (i != 0) { errno = i; return -1; } return 0; } -int ipscantestioctl(int dev, ioctlcmd_t cmd, ...) +int +ipscantestioctl(int dev, ioctlcmd_t cmd, ...) { caddr_t data; va_list ap; int i; dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); i = ipfioctl(softc, IPL_LOGSCAN, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) fprintf(stderr, "ipfioctl(SCAN,%#x,%p) = %d\n", (u_int)cmd, data, i); if (i != 0) { errno = i; return -1; } return 0; } -int ipsynctestioctl(int dev, ioctlcmd_t cmd, ...) +int +ipsynctestioctl(int dev, ioctlcmd_t cmd, ...) { caddr_t data; va_list ap; int i; dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); i = ipfioctl(softc, IPL_LOGSYNC, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) fprintf(stderr, "ipfioctl(SYNC,%#x,%p) = %d\n", (u_int)cmd, data, i); if (i != 0) { errno = i; return -1; } return 0; } -int ipooltestioctl(int dev, ioctlcmd_t cmd, ...) +int +ipooltestioctl(int dev, ioctlcmd_t cmd, ...) { caddr_t data; va_list ap; int i; dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); i = ipfioctl(softc, IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) fprintf(stderr, "ipfioctl(POOL,%#x,%p) = %d (%d)\n", (u_int)cmd, data, i, softc->ipf_interror); if (i != 0) { errno = i; return -1; } return 0; } -int kmemcpy(addr, offset, size) - char *addr; - long offset; - int size; +int +kmemcpy(char *addr, long offset, int size) { bcopy((char *)offset, addr, size); return 0; } -int kstrncpy(buf, pos, n) - char *buf; - long pos; - int n; +int +kstrncpy(char *buf, long pos, int n) { char *ptr; ptr = (char *)pos; while ((n > 0) && (*buf++ = *ptr++)) ; return 0; } /* * Display the built up NAT table rules and mapping entries. */ -void dumpnat(arg) - void *arg; +void +dumpnat(void *arg) { ipf_nat_softc_t *softn = arg; hostmap_t *hm; ipnat_t *ipn; nat_t *nat; printf("List of active MAP/Redirect filters:\n"); for (ipn = softn->ipf_nat_list; ipn != NULL; ipn = ipn->in_next) printnat(ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); printf("\nList of active sessions:\n"); for (nat = softn->ipf_nat_instances; nat; nat = nat->nat_next) { printactivenat(nat, opts, 0); if (nat->nat_aps) printf("\tproxy active\n"); } printf("\nHostmap table:\n"); for (hm = softn->ipf_hm_maplist; hm != NULL; hm = hm->hm_next) printhostmap(hm, hm->hm_hv); } -void dumpgroups(softc) - ipf_main_softc_t *softc; +void +dumpgroups(ipf_main_softc_t *softc) { frgroup_t *fg; int i; printf("List of groups configured (set 0)\n"); for (i = 0; i < IPL_LOGSIZE; i++) for (fg = softc->ipf_groups[i][0]; fg != NULL; fg = fg->fg_next) { printf("Dev.%d. Group %s Ref %d Flags %#x\n", i, fg->fg_name, fg->fg_ref, fg->fg_flags); dumprules(fg->fg_start); } printf("List of groups configured (set 1)\n"); for (i = 0; i < IPL_LOGSIZE; i++) for (fg = softc->ipf_groups[i][1]; fg != NULL; fg = fg->fg_next) { printf("Dev.%d. Group %s Ref %d Flags %#x\n", i, fg->fg_name, fg->fg_ref, fg->fg_flags); dumprules(fg->fg_start); } printf("Rules configured (set 0, in)\n"); dumprules(softc->ipf_rules[0][0]); printf("Rules configured (set 0, out)\n"); dumprules(softc->ipf_rules[1][0]); printf("Rules configured (set 1, in)\n"); dumprules(softc->ipf_rules[0][1]); printf("Rules configured (set 1, out)\n"); dumprules(softc->ipf_rules[1][1]); printf("Accounting rules configured (set 0, in)\n"); dumprules(softc->ipf_acct[0][0]); printf("Accounting rules configured (set 0, out)\n"); dumprules(softc->ipf_acct[0][1]); printf("Accounting rules configured (set 1, in)\n"); dumprules(softc->ipf_acct[1][0]); printf("Accounting rules configured (set 1, out)\n"); dumprules(softc->ipf_acct[1][1]); } -void dumprules(rulehead) - frentry_t *rulehead; +void +dumprules(frentry_t *rulehead) { frentry_t *fr; for (fr = rulehead; fr != NULL; fr = fr->fr_next) { #ifdef USE_QUAD_T printf("%"PRIu64" ",(unsigned long long)fr->fr_hits); #else printf("%ld ", fr->fr_hits); #endif printfr(fr, ipftestioctl); } } -void drain_log(filename) - char *filename; +void +drain_log(char *filename) { char buffer[DEFAULT_IPFLOGSIZE]; struct iovec iov; struct uio uio; size_t resid; int fd, i; fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0644); if (fd == -1) { perror("drain_log:open"); return; } for (i = 0; i <= IPL_LOGMAX; i++) while (1) { bzero((char *)&iov, sizeof(iov)); iov.iov_base = buffer; iov.iov_len = sizeof(buffer); bzero((char *)&uio, sizeof(uio)); uio.uio_iov = &iov; uio.uio_iovcnt = 1; uio.uio_resid = iov.iov_len; resid = uio.uio_resid; if (ipf_log_read(softc, i, &uio) == 0) { /* * If nothing was read then break out. */ if (uio.uio_resid == resid) break; write(fd, buffer, resid - uio.uio_resid); } else break; } close(fd); } -void fixv4sums(m, ip) - mb_t *m; - ip_t *ip; +void +fixv4sums(mb_t *m, ip_t *ip) { u_char *csump, *hdr, p; fr_info_t tmp; int len; p = 0; len = 0; bzero((char *)&tmp, sizeof(tmp)); csump = (u_char *)ip; if (IP_V(ip) == 4) { ip->ip_sum = 0; ip->ip_sum = ipf_cksum((u_short *)ip, IP_HL(ip) << 2); tmp.fin_hlen = IP_HL(ip) << 2; csump += IP_HL(ip) << 2; p = ip->ip_p; len = ntohs(ip->ip_len); #ifdef USE_INET6 } else if (IP_V(ip) == 6) { tmp.fin_hlen = sizeof(ip6_t); csump += sizeof(ip6_t); p = ((ip6_t *)ip)->ip6_nxt; len = ntohs(((ip6_t *)ip)->ip6_plen); len += sizeof(ip6_t); #endif } tmp.fin_plen = len; tmp.fin_dlen = len - tmp.fin_hlen; switch (p) { case IPPROTO_TCP : hdr = csump; csump += offsetof(tcphdr_t, th_sum); break; case IPPROTO_UDP : hdr = csump; csump += offsetof(udphdr_t, uh_sum); break; case IPPROTO_ICMP : hdr = csump; csump += offsetof(icmphdr_t, icmp_cksum); break; default : csump = NULL; hdr = NULL; break; } if (hdr != NULL) { tmp.fin_m = m; tmp.fin_mp = &m; tmp.fin_dp = hdr; tmp.fin_ip = ip; tmp.fin_plen = len; *csump = 0; *(u_short *)csump = fr_cksum(&tmp, ip, p, hdr); } } void ip_fillid(struct ip *ip) { static uint16_t ip_id; ip->ip_id = ip_id++; } diff --git a/sbin/ipf/ipftest/md5.c b/sbin/ipf/ipftest/md5.c index 899bb91700ba..b9e8ff99de82 100644 --- a/sbin/ipf/ipftest/md5.c +++ b/sbin/ipf/ipftest/md5.c @@ -1,310 +1,302 @@ /* $FreeBSD$ */ /* *********************************************************************** ** md5.c -- the source code for MD5 routines ** ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** ** Created: 2/17/90 RLR ** ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** *********************************************************************** */ /* *********************************************************************** ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** ** ** ** License to copy and use this software is granted provided that ** ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** ** Digest Algorithm" in all material mentioning or referencing this ** ** software or this function. ** ** ** ** License is also granted to make and use derivative works ** ** provided that such works are identified as "derived from the RSA ** ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** ** material mentioning or referencing the derived work. ** ** ** ** RSA Data Security, Inc. makes no representations concerning ** ** either the merchantability of this software or the suitability ** ** of this software for any particular purpose. It is provided "as ** ** is" without express or implied warranty of any kind. ** ** ** ** These notices must be retained in any copies of any part of this ** ** documentation and/or software. ** *********************************************************************** */ # if defined(_KERNEL) # include # else # include # endif #include "md5.h" /* *********************************************************************** ** Message-digest routines: ** ** To form the message digest for a message M ** ** (1) Initialize a context buffer mdContext using MD5Init ** ** (2) Call MD5Update on mdContext and M ** ** (3) Call MD5Final on mdContext ** ** The message digest is now in mdContext->digest[0...15] ** *********************************************************************** */ /* forward declaration */ static void Transform(UINT4 *, UINT4 *); static unsigned char PADDING[64] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* F, G, H and I are basic MD5 functions */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ /* Rotation is separate from addition to prevent recomputation */ #define FF(a, b, c, d, x, s, ac) \ {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) \ {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) \ {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) \ {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define UL(x) x##U /* The routine MD5Init initializes the message-digest context mdContext. All fields are set to zero. */ -void MD5Init (mdContext) -MD5_CTX *mdContext; +void MD5Init (MD5_CTX *mdContext) { mdContext->i[0] = mdContext->i[1] = (UINT4)0; /* Load magic initialization constants. */ mdContext->buf[0] = (UINT4)0x67452301; mdContext->buf[1] = (UINT4)0xefcdab89; mdContext->buf[2] = (UINT4)0x98badcfe; mdContext->buf[3] = (UINT4)0x10325476; } /* The routine MD5Update updates the message-digest context to account for the presence of each of the characters inBuf[0..inLen-1] in the message whose digest is being computed. */ -void MD5Update (mdContext, inBuf, inLen) -MD5_CTX *mdContext; -unsigned char *inBuf; -unsigned int inLen; +void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) { UINT4 in[16]; int mdi; unsigned int i, ii; /* compute number of bytes mod 64 */ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); /* update number of bits */ if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) mdContext->i[1]++; mdContext->i[0] += ((UINT4)inLen << 3); mdContext->i[1] += ((UINT4)inLen >> 29); while (inLen--) { /* add new character to buffer, increment mdi */ mdContext->in[mdi++] = *inBuf++; /* transform if necessary */ if (mdi == 0x40) { for (i = 0, ii = 0; i < 16; i++, ii += 4) in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | (((UINT4)mdContext->in[ii+2]) << 16) | (((UINT4)mdContext->in[ii+1]) << 8) | ((UINT4)mdContext->in[ii]); Transform (mdContext->buf, in); mdi = 0; } } } /* The routine MD5Final terminates the message-digest computation and ends with the desired message digest in mdContext->digest[0...15]. */ -void MD5Final (hash, mdContext) -unsigned char hash[]; -MD5_CTX *mdContext; +void MD5Final (unsigned char hash[], MD5_CTX *mdContext) { UINT4 in[16]; int mdi; unsigned int i, ii; unsigned int padLen; /* save number of bits */ in[14] = mdContext->i[0]; in[15] = mdContext->i[1]; /* compute number of bytes mod 64 */ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); /* pad out to 56 mod 64 */ padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); MD5Update (mdContext, PADDING, padLen); /* append length in bits and transform */ for (i = 0, ii = 0; i < 14; i++, ii += 4) in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | (((UINT4)mdContext->in[ii+2]) << 16) | (((UINT4)mdContext->in[ii+1]) << 8) | ((UINT4)mdContext->in[ii]); Transform (mdContext->buf, in); /* store buffer in digest */ for (i = 0, ii = 0; i < 4; i++, ii += 4) { mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); mdContext->digest[ii+1] = (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); mdContext->digest[ii+2] = (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); mdContext->digest[ii+3] = (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); } bcopy((char *)mdContext->digest, (char *)hash, 16); } /* Basic MD5 step. Transforms buf based on in. */ -static void Transform (buf, in) -UINT4 *buf; -UINT4 *in; +static void Transform (UINT4 *buf, UINT4 *in) { UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; /* Round 1 */ #define S11 7 #define S12 12 #define S13 17 #define S14 22 FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ /* Round 2 */ #define S21 5 #define S22 9 #define S23 14 #define S24 20 GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ /* Round 3 */ #define S31 4 #define S32 11 #define S33 16 #define S34 23 HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ /* Round 4 */ #define S41 6 #define S42 10 #define S43 15 #define S44 21 II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } /* *********************************************************************** ** End of md5.c ** ******************************** (cut) ******************************** */ diff --git a/sbin/ipf/iplang/iplang_l.l b/sbin/ipf/iplang/iplang_l.l index f8b1b82d4707..ba807edb9a70 100644 --- a/sbin/ipf/iplang/iplang_l.l +++ b/sbin/ipf/iplang/iplang_l.l @@ -1,319 +1,317 @@ /* $FreeBSD$ */ %{ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include #include #if defined(__SVR4) || defined(__sysv__) #include #endif #include #include #include #include "iplang_y.h" #include "ipf.h" #ifndef __P # define __P(x) x #endif extern int opts; int lineNum = 0, ipproto = 0, oldipproto = 0, next = -1, laststate = 0; int *prstack = NULL, numpr = 0, state = 0, token = 0; void yyerror(char *); void push_proto(void); void pop_proto(void); int next_state(int, int); int next_item(int); int save_token(void); void swallow(void); int yylex(void); struct lwordtab { char *word; int state; int next; }; struct lwordtab words[] = { { "interface", IL_INTERFACE, -1 }, { "iface", IL_INTERFACE, -1 }, { "name", IL_IFNAME, IL_TOKEN }, { "ifname", IL_IFNAME, IL_TOKEN }, { "router", IL_DEFROUTER, IL_TOKEN }, { "mtu", IL_MTU, IL_NUMBER }, { "eaddr", IL_EADDR, IL_TOKEN }, { "v4addr", IL_V4ADDR, IL_TOKEN }, { "ipv4", IL_IPV4, -1 }, { "v", IL_V4V, IL_TOKEN }, { "proto", IL_V4PROTO, IL_TOKEN }, { "hl", IL_V4HL, IL_TOKEN }, { "id", IL_V4ID, IL_TOKEN }, { "ttl", IL_V4TTL, IL_TOKEN }, { "tos", IL_V4TOS, IL_TOKEN }, { "src", IL_V4SRC, IL_TOKEN }, { "dst", IL_V4DST, IL_TOKEN }, { "opt", IL_OPT, -1 }, { "len", IL_LEN, IL_TOKEN }, { "off", IL_OFF, IL_TOKEN }, { "sum", IL_SUM, IL_TOKEN }, { "tcp", IL_TCP, -1 }, { "sport", IL_SPORT, IL_TOKEN }, { "dport", IL_DPORT, IL_TOKEN }, { "seq", IL_TCPSEQ, IL_TOKEN }, { "ack", IL_TCPACK, IL_TOKEN }, { "flags", IL_TCPFL, IL_TOKEN }, { "urp", IL_TCPURP, IL_TOKEN }, { "win", IL_TCPWIN, IL_TOKEN }, { "udp", IL_UDP, -1 }, { "send", IL_SEND, -1 }, { "via", IL_VIA, IL_TOKEN }, { "arp", IL_ARP, -1 }, { "data", IL_DATA, -1 }, { "value", IL_DVALUE, IL_TOKEN }, { "file", IL_DFILE, IL_TOKEN }, { "nop", IL_IPO_NOP, -1 }, { "eol", IL_IPO_EOL, -1 }, { "rr", IL_IPO_RR, -1 }, { "zsu", IL_IPO_ZSU, -1 }, { "mtup", IL_IPO_MTUP, -1 }, { "mtur", IL_IPO_MTUR, -1 }, { "encode", IL_IPO_ENCODE, -1 }, { "ts", IL_IPO_TS, -1 }, { "tr", IL_IPO_TR, -1 }, { "sec", IL_IPO_SEC, -1 }, { "secclass", IL_IPO_SECCLASS, IL_TOKEN }, { "lsrr", IL_IPO_LSRR, -1 }, { "esec", IL_IPO_ESEC, -1 }, { "cipso", IL_IPO_CIPSO, -1 }, { "satid", IL_IPO_SATID, -1 }, { "ssrr", IL_IPO_SSRR, -1 }, { "addext", IL_IPO_ADDEXT, -1 }, { "visa", IL_IPO_VISA, -1 }, { "imitd", IL_IPO_IMITD, -1 }, { "eip", IL_IPO_EIP, -1 }, { "finn", IL_IPO_FINN, -1 }, { "mss", IL_TCPO_MSS, IL_TOKEN }, { "wscale", IL_TCPO_WSCALE, IL_TOKEN }, { "reserv-4", IL_IPS_RESERV4, -1 }, { "topsecret", IL_IPS_TOPSECRET, -1 }, { "secret", IL_IPS_SECRET, -1 }, { "reserv-3", IL_IPS_RESERV3, -1 }, { "confid", IL_IPS_CONFID, -1 }, { "unclass", IL_IPS_UNCLASS, -1 }, { "reserv-2", IL_IPS_RESERV2, -1 }, { "reserv-1", IL_IPS_RESERV1, -1 }, { "icmp", IL_ICMP, -1 }, { "type", IL_ICMPTYPE, -1 }, { "code", IL_ICMPCODE, -1 }, { "echorep", IL_ICMP_ECHOREPLY, -1 }, { "unreach", IL_ICMP_UNREACH, -1 }, { "squench", IL_ICMP_SOURCEQUENCH, -1 }, { "redir", IL_ICMP_REDIRECT, -1 }, { "echo", IL_ICMP_ECHO, -1 }, { "routerad", IL_ICMP_ROUTERADVERT, -1 }, { "routersol", IL_ICMP_ROUTERSOLICIT, -1 }, { "timex", IL_ICMP_TIMXCEED, -1 }, { "paramprob", IL_ICMP_PARAMPROB, -1 }, { "timest", IL_ICMP_TSTAMP, -1 }, { "timestrep", IL_ICMP_TSTAMPREPLY, -1 }, { "inforeq", IL_ICMP_IREQ, -1 }, { "inforep", IL_ICMP_IREQREPLY, -1 }, { "maskreq", IL_ICMP_MASKREQ, -1 }, { "maskrep", IL_ICMP_MASKREPLY, -1 }, { "net-unr", IL_ICMP_UNREACH_NET, -1 }, { "host-unr", IL_ICMP_UNREACH_HOST, -1 }, { "proto-unr", IL_ICMP_UNREACH_PROTOCOL, -1 }, { "port-unr", IL_ICMP_UNREACH_PORT, -1 }, { "needfrag", IL_ICMP_UNREACH_NEEDFRAG, -1 }, { "srcfail", IL_ICMP_UNREACH_SRCFAIL, -1 }, { "net-unk", IL_ICMP_UNREACH_NET_UNKNOWN, -1 }, { "host-unk", IL_ICMP_UNREACH_HOST_UNKNOWN, -1 }, { "isolate", IL_ICMP_UNREACH_ISOLATED, -1 }, { "net-prohib", IL_ICMP_UNREACH_NET_PROHIB, -1 }, { "host-prohib", IL_ICMP_UNREACH_HOST_PROHIB, -1 }, { "net-tos", IL_ICMP_UNREACH_TOSNET, -1 }, { "host-tos", IL_ICMP_UNREACH_TOSHOST, -1 }, { "filter-prohib", IL_ICMP_UNREACH_FILTER_PROHIB, -1 }, { "host-preced", IL_ICMP_UNREACH_HOST_PRECEDENCE, -1 }, { "cutoff-preced", IL_ICMP_UNREACH_PRECEDENCE_CUTOFF, -1 }, { "net-redir", IL_ICMP_REDIRECT_NET, -1 }, { "host-redir", IL_ICMP_REDIRECT_HOST, -1 }, { "tos-net-redir", IL_ICMP_REDIRECT_TOSNET, -1 }, { "tos-host-redir", IL_ICMP_REDIRECT_TOSHOST, -1 }, { "intrans", IL_ICMP_TIMXCEED_INTRANS, -1 }, { "reass", IL_ICMP_TIMXCEED_REASS, -1 }, { "optabsent", IL_ICMP_PARAMPROB_OPTABSENT, -1 }, { "otime", IL_ICMP_OTIME, -1 }, { "rtime", IL_ICMP_RTIME, -1 }, { "ttime", IL_ICMP_TTIME, -1 }, { "icmpseq", IL_ICMP_SEQ, -1 }, { "icmpid", IL_ICMP_SEQ, -1 }, { ".", IL_DOT, -1 }, { NULL, 0, 0 } }; %} white [ \t\r]+ %% {white} ; \n { lineNum++; swallow(); } \{ { push_proto(); return next_item('{'); } \} { pop_proto(); return next_item('}'); } ; { return next_item(';'); } [0-9]+ { return next_item(IL_NUMBER); } [0-9a-fA-F] { return next_item(IL_HEXDIGIT); } : { return next_item(IL_COLON); } #[^\n]* { return next_item(IL_COMMENT); } [^ \{\}\n\t;:{}]* { return next_item(IL_TOKEN); } \"[^\"]*\" { return next_item(IL_TOKEN); } %% void yyerror(msg) char *msg; { fprintf(stderr, "%s error at \"%s\", line %d\n", msg, yytext, lineNum + 1); exit(1); } -void push_proto() +void push_proto(void) { numpr++; if (!prstack) prstack = (int *)malloc(sizeof(int)); else prstack = (int *)reallocarray((char *)prstack, numpr, sizeof(int)); prstack[numpr - 1] = oldipproto; } -void pop_proto() +void pop_proto(void) { numpr--; ipproto = prstack[numpr]; if (!numpr) { free(prstack); prstack = NULL; return; } prstack = (int *)realloc((char *)prstack, numpr * sizeof(int)); } -int save_token() +int save_token(void) { yylval.str = strdup((char *)yytext); return IL_TOKEN; } -int next_item(nstate) -int nstate; +int next_item(int nstate) { struct lwordtab *wt; if (opts & OPT_DEBUG) printf("text=[%s] id=%d next=%d\n", yytext, nstate, next); if (next == IL_TOKEN) { next = -1; return save_token(); } token++; for (wt = words; wt->word; wt++) if (!strcasecmp(wt->word, (char *)yytext)) return next_state(wt->state, wt->next); if (opts & OPT_DEBUG) printf("unknown keyword=[%s]\n", yytext); next = -1; if (nstate == IL_NUMBER) yylval.num = atoi((char *)yytext); token++; return nstate; } -int next_state(nstate, fornext) -int nstate, fornext; +int next_state(int nstate, int fornext) { next = fornext; switch (nstate) { case IL_IPV4 : case IL_TCP : case IL_UDP : case IL_ICMP : case IL_DATA : case IL_INTERFACE : case IL_ARP : oldipproto = ipproto; ipproto = nstate; break; case IL_SUM : if (ipproto == IL_IPV4) nstate = IL_V4SUM; else if (ipproto == IL_TCP) nstate = IL_TCPSUM; else if (ipproto == IL_UDP) nstate = IL_UDPSUM; break; case IL_OPT : if (ipproto == IL_IPV4) nstate = IL_V4OPT; else if (ipproto == IL_TCP) nstate = IL_TCPOPT; break; case IL_IPO_NOP : if (ipproto == IL_TCP) nstate = IL_TCPO_NOP; break; case IL_IPO_EOL : if (ipproto == IL_TCP) nstate = IL_TCPO_EOL; break; case IL_IPO_TS : if (ipproto == IL_TCP) nstate = IL_TCPO_TS; break; case IL_OFF : if (ipproto == IL_IPV4) nstate = IL_V4OFF; else if (ipproto == IL_TCP) nstate = IL_TCPOFF; break; case IL_LEN : if (ipproto == IL_IPV4) nstate = IL_V4LEN; else if (ipproto == IL_UDP) nstate = IL_UDPLEN; break; } return nstate; } -void swallow() +void swallow(void) { int c; c = input(); if (c == '#') { while ((c != '\n') && (c != EOF)) c = input(); } if (c != EOF) unput(c); } diff --git a/sbin/ipf/iplang/iplang_y.y b/sbin/ipf/iplang/iplang_y.y index 484fe1951d52..c098b98d6a75 100644 --- a/sbin/ipf/iplang/iplang_y.y +++ b/sbin/ipf/iplang/iplang_y.y @@ -1,1819 +1,1757 @@ /* $FreeBSD$ */ %{ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * Id: iplang_y.y,v 2.9.2.4 2006/03/17 12:11:29 darrenr Exp $ * $FreeBSD$ */ #include #include #include #if !defined(__SVR4) && !defined(__svr4__) # include #else # include #endif #include #include #include #include #include #include #include #include #include #include #include #include # include # include # include #include #include #include #include #include #include "ipsend.h" #include "ip_compat.h" #include "ipf.h" #include "iplang.h" extern int opts; extern struct ipopt_names ionames[]; extern int state, state, lineNum, token; extern int yylineno; extern char yytext[]; extern FILE *yyin; int yylex __P((void)); #define YYDEBUG 1 int yydebug = 1; iface_t *iflist = NULL, **iftail = &iflist; iface_t *cifp = NULL; arp_t *arplist = NULL, **arptail = &arplist, *carp = NULL; struct in_addr defrouter; send_t sending; char *sclass = NULL; u_short c_chksum(u_short *, u_int, u_long); u_long p_chksum(u_short *, u_int); u_long ipbuffer[67584/sizeof(u_long)]; /* 66K */ aniphdr_t *aniphead = NULL, *canip = NULL, **aniptail = &aniphead; ip_t *ip = NULL; udphdr_t *udp = NULL; tcphdr_t *tcp = NULL; icmphdr_t *icmp = NULL; struct statetoopt { int sto_st; int sto_op; }; struct in_addr getipv4addr(char *arg); u_short getportnum(char *, char *); struct ether_addr *geteaddr(char *, struct ether_addr *); void *new_header(int); void free_aniplist(void); void inc_anipheaders(int); void new_data(void); void set_datalen(char **); void set_datafile(char **); void set_data(char **); void new_packet(void); void set_ipv4proto(char **); void set_ipv4src(char **); void set_ipv4dst(char **); void set_ipv4off(char **); void set_ipv4v(char **); void set_ipv4hl(char **); void set_ipv4ttl(char **); void set_ipv4tos(char **); void set_ipv4id(char **); void set_ipv4sum(char **); void set_ipv4len(char **); void new_tcpheader(void); void set_tcpsport(char **); void set_tcpdport(char **); void set_tcpseq(char **); void set_tcpack(char **); void set_tcpoff(char **); void set_tcpurp(char **); void set_tcpwin(char **); void set_tcpsum(char **); void set_tcpflags(char **); void set_tcpopt(int, char **); void end_tcpopt(void); void new_udpheader(void); void set_udplen(char **); void set_udpsum(char **); void prep_packet(void); void packet_done(void); void new_interface(void); void check_interface(void); void set_ifname(char **); void set_ifmtu(int); void set_ifv4addr(char **); void set_ifeaddr(char **); void new_arp(void); void set_arpeaddr(char **); void set_arpv4addr(char **); void reset_send(void); void set_sendif(char **); void set_sendvia(char **); void set_defaultrouter(char **); void new_icmpheader(void); void set_icmpcode(int); void set_icmptype(int); void set_icmpcodetok(char **); void set_icmptypetok(char **); void set_icmpid(int); void set_icmpseq(int); void set_icmpotime(int); void set_icmprtime(int); void set_icmpttime(int); void set_icmpmtu(int); void set_redir(int, char **); void new_ipv4opt(void); void set_icmppprob(int); void add_ipopt(int, void *); void end_ipopt(void); void set_secclass(char **); void free_anipheader(void); void end_ipv4(void); void end_icmp(void); void end_udp(void); void end_tcp(void); void end_data(void); void yyerror(char *); void iplang(FILE *); int arp_getipv4(char *, char *); int yyparse(void); %} %union { char *str; int num; } %token IL_NUMBER %type number digits optnumber %token IL_TOKEN %type token optoken %token IL_HEXDIGIT IL_COLON IL_DOT IL_EOF IL_COMMENT %token IL_INTERFACE IL_IFNAME IL_MTU IL_EADDR %token IL_IPV4 IL_V4PROTO IL_V4SRC IL_V4DST IL_V4OFF IL_V4V IL_V4HL IL_V4TTL %token IL_V4TOS IL_V4SUM IL_V4LEN IL_V4OPT IL_V4ID %token IL_TCP IL_SPORT IL_DPORT IL_TCPFL IL_TCPSEQ IL_TCPACK IL_TCPOFF %token IL_TCPWIN IL_TCPSUM IL_TCPURP IL_TCPOPT IL_TCPO_NOP IL_TCPO_EOL %token IL_TCPO_MSS IL_TCPO_WSCALE IL_TCPO_TS %token IL_UDP IL_UDPLEN IL_UDPSUM %token IL_ICMP IL_ICMPTYPE IL_ICMPCODE %token IL_SEND IL_VIA %token IL_ARP %token IL_DEFROUTER %token IL_SUM IL_OFF IL_LEN IL_V4ADDR IL_OPT %token IL_DATA IL_DLEN IL_DVALUE IL_DFILE %token IL_IPO_NOP IL_IPO_RR IL_IPO_ZSU IL_IPO_MTUP IL_IPO_MTUR IL_IPO_EOL %token IL_IPO_TS IL_IPO_TR IL_IPO_SEC IL_IPO_LSRR IL_IPO_ESEC %token IL_IPO_SATID IL_IPO_SSRR IL_IPO_ADDEXT IL_IPO_VISA IL_IPO_IMITD %token IL_IPO_EIP IL_IPO_FINN IL_IPO_SECCLASS IL_IPO_CIPSO IL_IPO_ENCODE %token IL_IPS_RESERV4 IL_IPS_TOPSECRET IL_IPS_SECRET IL_IPS_RESERV3 %token IL_IPS_CONFID IL_IPS_UNCLASS IL_IPS_RESERV2 IL_IPS_RESERV1 %token IL_ICMP_ECHOREPLY IL_ICMP_UNREACH IL_ICMP_UNREACH_NET %token IL_ICMP_UNREACH_HOST IL_ICMP_UNREACH_PROTOCOL IL_ICMP_UNREACH_PORT %token IL_ICMP_UNREACH_NEEDFRAG IL_ICMP_UNREACH_SRCFAIL %token IL_ICMP_UNREACH_NET_UNKNOWN IL_ICMP_UNREACH_HOST_UNKNOWN %token IL_ICMP_UNREACH_ISOLATED IL_ICMP_UNREACH_NET_PROHIB %token IL_ICMP_UNREACH_HOST_PROHIB IL_ICMP_UNREACH_TOSNET %token IL_ICMP_UNREACH_TOSHOST IL_ICMP_UNREACH_FILTER_PROHIB %token IL_ICMP_UNREACH_HOST_PRECEDENCE IL_ICMP_UNREACH_PRECEDENCE_CUTOFF %token IL_ICMP_SOURCEQUENCH IL_ICMP_REDIRECT IL_ICMP_REDIRECT_NET %token IL_ICMP_REDIRECT_HOST IL_ICMP_REDIRECT_TOSNET %token IL_ICMP_REDIRECT_TOSHOST IL_ICMP_ECHO IL_ICMP_ROUTERADVERT %token IL_ICMP_ROUTERSOLICIT IL_ICMP_TIMXCEED IL_ICMP_TIMXCEED_INTRANS %token IL_ICMP_TIMXCEED_REASS IL_ICMP_PARAMPROB IL_ICMP_PARAMPROB_OPTABSENT %token IL_ICMP_TSTAMP IL_ICMP_TSTAMPREPLY IL_ICMP_IREQ IL_ICMP_IREQREPLY %token IL_ICMP_MASKREQ IL_ICMP_MASKREPLY IL_ICMP_SEQ IL_ICMP_ID %token IL_ICMP_OTIME IL_ICMP_RTIME IL_ICMP_TTIME %% file: line | line file | IL_COMMENT | IL_COMMENT file ; line: iface | arp | send | defrouter | ipline ; iface: ifhdr '{' ifaceopts '}' ';' { check_interface(); } ; ifhdr: IL_INTERFACE { new_interface(); } ; ifaceopts: ifaceopt | ifaceopt ifaceopts ; ifaceopt: IL_IFNAME token { set_ifname(&$2); } | IL_MTU number { set_ifmtu($2); } | IL_V4ADDR token { set_ifv4addr(&$2); } | IL_EADDR token { set_ifeaddr(&$2); } ; send: sendhdr '{' sendbody '}' ';' { packet_done(); } | sendhdr ';' { packet_done(); } ; sendhdr: IL_SEND { reset_send(); } ; sendbody: sendopt | sendbody sendopt ; sendopt: IL_IFNAME token { set_sendif(&$2); } | IL_VIA token { set_sendvia(&$2); } ; arp: arphdr '{' arpbody '}' ';' ; arphdr: IL_ARP { new_arp(); } ; arpbody: arpopt | arpbody arpopt ; arpopt: IL_V4ADDR token { set_arpv4addr(&$2); } | IL_EADDR token { set_arpeaddr(&$2); } ; defrouter: IL_DEFROUTER token { set_defaultrouter(&$2); } ; bodyline: ipline | tcp tcpline | udp udpline | icmp icmpline | data dataline ; ipline: ipv4 '{' ipv4body '}' ';' { end_ipv4(); } ; ipv4: IL_IPV4 { new_packet(); } ipv4body: ipv4type | ipv4type ipv4body | bodyline ; ipv4type: IL_V4PROTO token { set_ipv4proto(&$2); } | IL_V4SRC token { set_ipv4src(&$2); } | IL_V4DST token { set_ipv4dst(&$2); } | IL_V4OFF token { set_ipv4off(&$2); } | IL_V4V token { set_ipv4v(&$2); } | IL_V4HL token { set_ipv4hl(&$2); } | IL_V4ID token { set_ipv4id(&$2); } | IL_V4TTL token { set_ipv4ttl(&$2); } | IL_V4TOS token { set_ipv4tos(&$2); } | IL_V4SUM token { set_ipv4sum(&$2); } | IL_V4LEN token { set_ipv4len(&$2); } | ipv4opt '{' ipv4optlist '}' ';' { end_ipopt(); } ; tcp: IL_TCP { new_tcpheader(); } ; tcpline: '{' tcpheader '}' ';' { end_tcp(); } ; tcpheader: tcpbody | tcpbody tcpheader | bodyline ; tcpbody: IL_SPORT token { set_tcpsport(&$2); } | IL_DPORT token { set_tcpdport(&$2); } | IL_TCPSEQ token { set_tcpseq(&$2); } | IL_TCPACK token { set_tcpack(&$2); } | IL_TCPOFF token { set_tcpoff(&$2); } | IL_TCPURP token { set_tcpurp(&$2); } | IL_TCPWIN token { set_tcpwin(&$2); } | IL_TCPSUM token { set_tcpsum(&$2); } | IL_TCPFL token { set_tcpflags(&$2); } | IL_TCPOPT '{' tcpopts '}' ';' { end_tcpopt(); } ; tcpopts: | tcpopt tcpopts ; tcpopt: IL_TCPO_NOP ';' { set_tcpopt(IL_TCPO_NOP, NULL); } | IL_TCPO_EOL ';' { set_tcpopt(IL_TCPO_EOL, NULL); } | IL_TCPO_MSS optoken { set_tcpopt(IL_TCPO_MSS,&$2);} | IL_TCPO_WSCALE optoken { set_tcpopt(IL_TCPO_WSCALE,&$2);} | IL_TCPO_TS optoken { set_tcpopt(IL_TCPO_TS, &$2);} ; udp: IL_UDP { new_udpheader(); } ; udpline: '{' udpheader '}' ';' { end_udp(); } ; udpheader: udpbody | udpbody udpheader | bodyline ; udpbody: IL_SPORT token { set_tcpsport(&$2); } | IL_DPORT token { set_tcpdport(&$2); } | IL_UDPLEN token { set_udplen(&$2); } | IL_UDPSUM token { set_udpsum(&$2); } ; icmp: IL_ICMP { new_icmpheader(); } ; icmpline: '{' icmpbody '}' ';' { end_icmp(); } ; icmpbody: icmpheader | icmpheader bodyline ; icmpheader: IL_ICMPTYPE icmptype | IL_ICMPTYPE icmptype icmpcode ; icmpcode: IL_ICMPCODE token { set_icmpcodetok(&$2); } ; icmptype: IL_ICMP_ECHOREPLY ';' { set_icmptype(ICMP_ECHOREPLY); } | IL_ICMP_ECHOREPLY '{' icmpechoopts '}' ';' | unreach | IL_ICMP_SOURCEQUENCH ';' { set_icmptype(ICMP_SOURCEQUENCH); } | redirect | IL_ICMP_ROUTERADVERT ';' { set_icmptype(ICMP_ROUTERADVERT); } | IL_ICMP_ROUTERSOLICIT ';' { set_icmptype(ICMP_ROUTERSOLICIT); } | IL_ICMP_ECHO ';' { set_icmptype(ICMP_ECHO); } | IL_ICMP_ECHO '{' icmpechoopts '}' ';' | IL_ICMP_TIMXCEED ';' { set_icmptype(ICMP_TIMXCEED); } | IL_ICMP_TIMXCEED '{' exceed '}' ';' | IL_ICMP_TSTAMP ';' { set_icmptype(ICMP_TSTAMP); } | IL_ICMP_TSTAMPREPLY ';' { set_icmptype(ICMP_TSTAMPREPLY); } | IL_ICMP_TSTAMPREPLY '{' icmptsopts '}' ';' | IL_ICMP_IREQ ';' { set_icmptype(ICMP_IREQ); } | IL_ICMP_IREQREPLY ';' { set_icmptype(ICMP_IREQREPLY); } | IL_ICMP_IREQREPLY '{' data dataline '}' ';' | IL_ICMP_MASKREQ ';' { set_icmptype(ICMP_MASKREQ); } | IL_ICMP_MASKREPLY ';' { set_icmptype(ICMP_MASKREPLY); } | IL_ICMP_MASKREPLY '{' token '}' ';' | IL_ICMP_PARAMPROB ';' { set_icmptype(ICMP_PARAMPROB); } | IL_ICMP_PARAMPROB '{' paramprob '}' ';' | IL_TOKEN ';' { set_icmptypetok(&$1); } ; icmpechoopts: | icmpechoopts icmpecho ; icmpecho: IL_ICMP_SEQ number { set_icmpseq($2); } | IL_ICMP_ID number { set_icmpid($2); } ; icmptsopts: | icmptsopts icmpts ';' ; icmpts: IL_ICMP_OTIME number { set_icmpotime($2); } | IL_ICMP_RTIME number { set_icmprtime($2); } | IL_ICMP_TTIME number { set_icmpttime($2); } ; unreach: IL_ICMP_UNREACH | IL_ICMP_UNREACH '{' unreachopts '}' ';' ; unreachopts: IL_ICMP_UNREACH_NET line | IL_ICMP_UNREACH_HOST line | IL_ICMP_UNREACH_PROTOCOL line | IL_ICMP_UNREACH_PORT line | IL_ICMP_UNREACH_NEEDFRAG number ';' { set_icmpmtu($2); } | IL_ICMP_UNREACH_SRCFAIL line | IL_ICMP_UNREACH_NET_UNKNOWN line | IL_ICMP_UNREACH_HOST_UNKNOWN line | IL_ICMP_UNREACH_ISOLATED line | IL_ICMP_UNREACH_NET_PROHIB line | IL_ICMP_UNREACH_HOST_PROHIB line | IL_ICMP_UNREACH_TOSNET line | IL_ICMP_UNREACH_TOSHOST line | IL_ICMP_UNREACH_FILTER_PROHIB line | IL_ICMP_UNREACH_HOST_PRECEDENCE line | IL_ICMP_UNREACH_PRECEDENCE_CUTOFF line ; redirect: IL_ICMP_REDIRECT | IL_ICMP_REDIRECT '{' redirectopts '}' ';' ; redirectopts: | IL_ICMP_REDIRECT_NET token { set_redir(0, &$2); } | IL_ICMP_REDIRECT_HOST token { set_redir(1, &$2); } | IL_ICMP_REDIRECT_TOSNET token { set_redir(2, &$2); } | IL_ICMP_REDIRECT_TOSHOST token { set_redir(3, &$2); } ; exceed: IL_ICMP_TIMXCEED_INTRANS line | IL_ICMP_TIMXCEED_REASS line ; paramprob: IL_ICMP_PARAMPROB_OPTABSENT | IL_ICMP_PARAMPROB_OPTABSENT paraprobarg paraprobarg: '{' number '}' ';' { set_icmppprob($2); } ; ipv4opt: IL_V4OPT { new_ipv4opt(); } ; ipv4optlist: | ipv4opts ipv4optlist ; ipv4opts: IL_IPO_NOP ';' { add_ipopt(IL_IPO_NOP, NULL); } | IL_IPO_RR optnumber { add_ipopt(IL_IPO_RR, &$2); } | IL_IPO_ZSU ';' { add_ipopt(IL_IPO_ZSU, NULL); } | IL_IPO_MTUP ';' { add_ipopt(IL_IPO_MTUP, NULL); } | IL_IPO_MTUR ';' { add_ipopt(IL_IPO_MTUR, NULL); } | IL_IPO_ENCODE ';' { add_ipopt(IL_IPO_ENCODE, NULL); } | IL_IPO_TS ';' { add_ipopt(IL_IPO_TS, NULL); } | IL_IPO_TR ';' { add_ipopt(IL_IPO_TR, NULL); } | IL_IPO_SEC ';' { add_ipopt(IL_IPO_SEC, NULL); } | IL_IPO_SECCLASS secclass { add_ipopt(IL_IPO_SECCLASS, sclass); } | IL_IPO_LSRR token { add_ipopt(IL_IPO_LSRR,&$2); } | IL_IPO_ESEC ';' { add_ipopt(IL_IPO_ESEC, NULL); } | IL_IPO_CIPSO ';' { add_ipopt(IL_IPO_CIPSO, NULL); } | IL_IPO_SATID optnumber { add_ipopt(IL_IPO_SATID,&$2);} | IL_IPO_SSRR token { add_ipopt(IL_IPO_SSRR,&$2); } | IL_IPO_ADDEXT ';' { add_ipopt(IL_IPO_ADDEXT, NULL); } | IL_IPO_VISA ';' { add_ipopt(IL_IPO_VISA, NULL); } | IL_IPO_IMITD ';' { add_ipopt(IL_IPO_IMITD, NULL); } | IL_IPO_EIP ';' { add_ipopt(IL_IPO_EIP, NULL); } | IL_IPO_FINN ';' { add_ipopt(IL_IPO_FINN, NULL); } ; secclass: IL_IPS_RESERV4 ';' { set_secclass(&$1); } | IL_IPS_TOPSECRET ';' { set_secclass(&$1); } | IL_IPS_SECRET ';' { set_secclass(&$1); } | IL_IPS_RESERV3 ';' { set_secclass(&$1); } | IL_IPS_CONFID ';' { set_secclass(&$1); } | IL_IPS_UNCLASS ';' { set_secclass(&$1); } | IL_IPS_RESERV2 ';' { set_secclass(&$1); } | IL_IPS_RESERV1 ';' { set_secclass(&$1); } ; data: IL_DATA { new_data(); } ; dataline: '{' databody '}' ';' { end_data(); } ; databody: dataopts | dataopts databody ; dataopts: IL_DLEN token { set_datalen(&$2); } | IL_DVALUE token { set_data(&$2); } | IL_DFILE token { set_datafile(&$2); } ; token: IL_TOKEN ';' ; optoken: ';' { $$ = ""; } | token ; number: digits ';' ; optnumber: ';' { $$ = 0; } | number ; digits: IL_NUMBER | digits IL_NUMBER ; %% struct statetoopt toipopts[] = { { IL_IPO_NOP, IPOPT_NOP }, { IL_IPO_RR, IPOPT_RR }, { IL_IPO_ZSU, IPOPT_ZSU }, { IL_IPO_MTUP, IPOPT_MTUP }, { IL_IPO_MTUR, IPOPT_MTUR }, { IL_IPO_ENCODE, IPOPT_ENCODE }, { IL_IPO_TS, IPOPT_TS }, { IL_IPO_TR, IPOPT_TR }, { IL_IPO_SEC, IPOPT_SECURITY }, { IL_IPO_SECCLASS, IPOPT_SECURITY }, { IL_IPO_LSRR, IPOPT_LSRR }, { IL_IPO_ESEC, IPOPT_E_SEC }, { IL_IPO_CIPSO, IPOPT_CIPSO }, { IL_IPO_SATID, IPOPT_SATID }, { IL_IPO_SSRR, IPOPT_SSRR }, { IL_IPO_ADDEXT, IPOPT_ADDEXT }, { IL_IPO_VISA, IPOPT_VISA }, { IL_IPO_IMITD, IPOPT_IMITD }, { IL_IPO_EIP, IPOPT_EIP }, { IL_IPO_FINN, IPOPT_FINN }, { 0, 0 } }; struct statetoopt tosecopts[] = { { IL_IPS_RESERV4, IPSO_CLASS_RES4 }, { IL_IPS_TOPSECRET, IPSO_CLASS_TOPS }, { IL_IPS_SECRET, IPSO_CLASS_SECR }, { IL_IPS_RESERV3, IPSO_CLASS_RES3 }, { IL_IPS_CONFID, IPSO_CLASS_CONF }, { IL_IPS_UNCLASS, IPSO_CLASS_UNCL }, { IL_IPS_RESERV2, IPSO_CLASS_RES2 }, { IL_IPS_RESERV1, IPSO_CLASS_RES1 }, { 0, 0 } }; struct in_addr getipv4addr(arg) char *arg; { struct hostent *hp; struct in_addr in; in.s_addr = 0xffffffff; if ((hp = gethostbyname(arg))) bcopy(hp->h_addr, &in.s_addr, sizeof(struct in_addr)); else in.s_addr = inet_addr(arg); return in; } u_short getportnum(pr, name) char *pr, *name; { struct servent *sp; if (!(sp = getservbyname(name, pr))) return htons(atoi(name)); return sp->s_port; } -struct ether_addr *geteaddr(arg, buf) -char *arg; -struct ether_addr *buf; +struct ether_addr *geteaddr(char *arg, struct ether_addr *buf) { struct ether_addr *e; e = ether_aton(arg); if (!e) fprintf(stderr, "Invalid ethernet address: %s\n", arg); else # ifdef __FreeBSD__ bcopy(e->octet, buf->octet, sizeof(e->octet)); # else bcopy(e->ether_addr_octet, buf->ether_addr_octet, sizeof(e->ether_addr_octet)); # endif return e; } -void *new_header(type) -int type; +void *new_header(int type) { aniphdr_t *aip, *oip = canip; int sz = 0; aip = (aniphdr_t *)calloc(1, sizeof(*aip)); *aniptail = aip; aniptail = &aip->ah_next; aip->ah_p = type; aip->ah_prev = oip; canip = aip; if (type == IPPROTO_UDP) sz = sizeof(udphdr_t); else if (type == IPPROTO_TCP) sz = sizeof(tcphdr_t); else if (type == IPPROTO_ICMP) sz = sizeof(icmphdr_t); else if (type == IPPROTO_IP) sz = sizeof(ip_t); if (oip) canip->ah_data = oip->ah_data + oip->ah_len; else canip->ah_data = (char *)ipbuffer; /* * Increase the size fields in all wrapping headers. */ for (aip = aniphead; aip; aip = aip->ah_next) { aip->ah_len += sz; if (aip->ah_p == IPPROTO_IP) aip->ah_ip->ip_len += sz; else if (aip->ah_p == IPPROTO_UDP) aip->ah_udp->uh_ulen += sz; } return (void *)canip->ah_data; } -void free_aniplist() +void free_aniplist(void) { aniphdr_t *aip, **aipp = &aniphead; while ((aip = *aipp)) { *aipp = aip->ah_next; free(aip); } aniptail = &aniphead; } -void inc_anipheaders(inc) -int inc; +void inc_anipheaders(int inc) { aniphdr_t *aip; for (aip = aniphead; aip; aip = aip->ah_next) { aip->ah_len += inc; if (aip->ah_p == IPPROTO_IP) aip->ah_ip->ip_len += inc; else if (aip->ah_p == IPPROTO_UDP) aip->ah_udp->uh_ulen += inc; } } -void new_data() +void new_data(void) { (void) new_header(-1); canip->ah_len = 0; } -void set_datalen(arg) -char **arg; +void set_datalen(char **arg) { int len; len = strtol(*arg, NULL, 0); inc_anipheaders(len); free(*arg); *arg = NULL; } -void set_data(arg) -char **arg; +void set_data(char **arg) { u_char *s = (u_char *)*arg, *t = (u_char *)canip->ah_data, c; int len = 0, todo = 0, quote = 0, val = 0; while ((c = *s++)) { if (todo) { if (ISDIGIT(c)) { todo--; if (c > '7') { fprintf(stderr, "octal with %c!\n", c); break; } val <<= 3; val |= (c - '0'); } if (!ISDIGIT(c) || !todo) { *t++ = (u_char)(val & 0xff); todo = 0; } if (todo) continue; } if (quote) { if (ISDIGIT(c)) { todo = 2; if (c > '7') { fprintf(stderr, "octal with %c!\n", c); break; } val = (c - '0'); } else { switch (c) { case '\"' : *t++ = '\"'; break; case '\\' : *t++ = '\\'; break; case 'n' : *t++ = '\n'; break; case 'r' : *t++ = '\r'; break; case 't' : *t++ = '\t'; break; } } quote = 0; continue; } if (c == '\\') quote = 1; else *t++ = c; } if (todo) *t++ = (u_char)(val & 0xff); if (quote) *t++ = '\\'; len = t - (u_char *)canip->ah_data; inc_anipheaders(len - canip->ah_len); canip->ah_len = len; } -void set_datafile(arg) -char **arg; +void set_datafile(char **arg) { struct stat sb; char *file = *arg; int fd, len; if ((fd = open(file, O_RDONLY)) == -1) { perror("open"); exit(-1); } if (fstat(fd, &sb) == -1) { perror("fstat"); exit(-1); } if ((sb.st_size + aniphead->ah_len ) > 65535) { fprintf(stderr, "data file %s too big to include.\n", file); close(fd); return; } if ((len = read(fd, canip->ah_data, sb.st_size)) == -1) { perror("read"); close(fd); return; } inc_anipheaders(len); canip->ah_len += len; close(fd); } -void new_packet() +void new_packet(void) { static u_short id = 0; if (!aniphead) bzero((char *)ipbuffer, sizeof(ipbuffer)); ip = (ip_t *)new_header(IPPROTO_IP); ip->ip_v = IPVERSION; ip->ip_hl = sizeof(ip_t) >> 2; ip->ip_len = sizeof(ip_t); ip->ip_ttl = 63; ip->ip_id = htons(id++); } void set_ipv4proto(arg) char **arg; { struct protoent *pr; if ((pr = getprotobyname(*arg))) ip->ip_p = pr->p_proto; else if (!(ip->ip_p = atoi(*arg))) fprintf(stderr, "unknown protocol %s\n", *arg); free(*arg); *arg = NULL; } -void set_ipv4src(arg) -char **arg; +void set_ipv4src(char **arg) { ip->ip_src = getipv4addr(*arg); free(*arg); *arg = NULL; } -void set_ipv4dst(arg) -char **arg; +void set_ipv4dst(char **arg) { ip->ip_dst = getipv4addr(*arg); free(*arg); *arg = NULL; } -void set_ipv4off(arg) -char **arg; +void set_ipv4off(char **arg) { ip->ip_off = htons(strtol(*arg, NULL, 0)); free(*arg); *arg = NULL; } -void set_ipv4v(arg) -char **arg; +void set_ipv4v(char **arg) { ip->ip_v = strtol(*arg, NULL, 0); free(*arg); *arg = NULL; } -void set_ipv4hl(arg) -char **arg; +void set_ipv4hl(char **arg) { int newhl, inc; newhl = strtol(*arg, NULL, 0); inc = (newhl - ip->ip_hl) << 2; ip->ip_len += inc; ip->ip_hl = newhl; canip->ah_len += inc; free(*arg); *arg = NULL; } -void set_ipv4ttl(arg) -char **arg; +void set_ipv4ttl(char **arg) { ip->ip_ttl = strtol(*arg, NULL, 0); free(*arg); *arg = NULL; } -void set_ipv4tos(arg) -char **arg; +void set_ipv4tos(char **arg) { ip->ip_tos = strtol(*arg, NULL, 0); free(*arg); *arg = NULL; } -void set_ipv4id(arg) -char **arg; +void set_ipv4id(char **arg) { ip->ip_id = htons(strtol(*arg, NULL, 0)); free(*arg); *arg = NULL; } -void set_ipv4sum(arg) -char **arg; +void set_ipv4sum(char **arg) { ip->ip_sum = strtol(*arg, NULL, 0); free(*arg); *arg = NULL; } -void set_ipv4len(arg) -char **arg; +void set_ipv4len(char **arg) { int len; len = strtol(*arg, NULL, 0); inc_anipheaders(len - ip->ip_len); ip->ip_len = len; free(*arg); *arg = NULL; } -void new_tcpheader() +void new_tcpheader(void) { if ((ip->ip_p) && (ip->ip_p != IPPROTO_TCP)) { fprintf(stderr, "protocol %d specified with TCP!\n", ip->ip_p); return; } ip->ip_p = IPPROTO_TCP; tcp = (tcphdr_t *)new_header(IPPROTO_TCP); tcp->th_win = htons(4096); tcp->th_off = sizeof(*tcp) >> 2; } -void set_tcpsport(arg) -char **arg; +void set_tcpsport(char **arg) { u_short *port; char *pr; if (ip->ip_p == IPPROTO_UDP) { port = &udp->uh_sport; pr = "udp"; } else { port = &tcp->th_sport; pr = "udp"; } *port = getportnum(pr, *arg); free(*arg); *arg = NULL; } -void set_tcpdport(arg) -char **arg; +void set_tcpdport(char **arg) { u_short *port; char *pr; if (ip->ip_p == IPPROTO_UDP) { port = &udp->uh_dport; pr = "udp"; } else { port = &tcp->th_dport; pr = "udp"; } *port = getportnum(pr, *arg); free(*arg); *arg = NULL; } -void set_tcpseq(arg) -char **arg; +void set_tcpseq(char **arg) { tcp->th_seq = htonl(strtol(*arg, NULL, 0)); free(*arg); *arg = NULL; } -void set_tcpack(arg) -char **arg; +void set_tcpack(char **arg) { tcp->th_ack = htonl(strtol(*arg, NULL, 0)); free(*arg); *arg = NULL; } -void set_tcpoff(arg) -char **arg; +void set_tcpoff(char **arg) { int off; off = strtol(*arg, NULL, 0); inc_anipheaders((off - tcp->th_off) << 2); tcp->th_off = off; free(*arg); *arg = NULL; } -void set_tcpurp(arg) -char **arg; +void set_tcpurp(char **arg) { tcp->th_urp = htons(strtol(*arg, NULL, 0)); free(*arg); *arg = NULL; } -void set_tcpwin(arg) -char **arg; +void set_tcpwin(char **arg) { tcp->th_win = htons(strtol(*arg, NULL, 0)); free(*arg); *arg = NULL; } -void set_tcpsum(arg) -char **arg; +void set_tcpsum(char **arg) { tcp->th_sum = strtol(*arg, NULL, 0); free(*arg); *arg = NULL; } -void set_tcpflags(arg) -char **arg; +void set_tcpflags(char **arg) { static char flags[] = "ASURPF"; static int flagv[] = { TH_ACK, TH_SYN, TH_URG, TH_RST, TH_PUSH, TH_FIN } ; char *s, *t; for (s = *arg; *s; s++) if (!(t = strchr(flags, *s))) { if (s - *arg) { fprintf(stderr, "unknown TCP flag %c\n", *s); break; } tcp->th_flags = strtol(*arg, NULL, 0); break; } else tcp->th_flags |= flagv[t - flags]; free(*arg); *arg = NULL; } -void set_tcpopt(state, arg) -int state; -char **arg; +void set_tcpopt(int state, char **arg) { u_char *s; int val, len, val2, pad, optval; if (arg && *arg) val = atoi(*arg); else val = 0; s = (u_char *)tcp + sizeof(*tcp) + canip->ah_optlen; switch (state) { case IL_TCPO_EOL : optval = 0; len = 1; break; case IL_TCPO_NOP : optval = 1; len = 1; break; case IL_TCPO_MSS : optval = 2; len = 4; break; case IL_TCPO_WSCALE : optval = 3; len = 3; break; case IL_TCPO_TS : optval = 8; len = 10; break; default : optval = 0; len = 0; break; } if (len > 1) { /* * prepend padding - if required. */ if (len & 3) for (pad = 4 - (len & 3); pad; pad--) { *s++ = 1; canip->ah_optlen++; } /* * build tcp option */ *s++ = (u_char)optval; *s++ = (u_char)len; if (len > 2) { if (len == 3) { /* 1 byte - char */ *s++ = (u_char)val; } else if (len == 4) { /* 2 bytes - short */ *s++ = (u_char)((val >> 8) & 0xff); *s++ = (u_char)(val & 0xff); } else if (len >= 6) { /* 4 bytes - long */ val2 = htonl(val); bcopy((char *)&val2, s, 4); } s += (len - 2); } } else *s++ = (u_char)optval; canip->ah_lastopt = optval; canip->ah_optlen += len; if (arg && *arg) { free(*arg); *arg = NULL; } } -void end_tcpopt() +void end_tcpopt(void) { int pad; char *s = (char *)tcp; s += sizeof(*tcp) + canip->ah_optlen; /* * pad out so that we have a multiple of 4 bytes in size fo the * options. make sure last byte is EOL. */ if (canip->ah_optlen & 3) { if (canip->ah_lastopt != 1) { for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { *s++ = 1; canip->ah_optlen++; } canip->ah_optlen++; } else { s -= 1; for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { *s++ = 1; canip->ah_optlen++; } } *s++ = 0; } tcp->th_off = (sizeof(*tcp) + canip->ah_optlen) >> 2; inc_anipheaders(canip->ah_optlen); } -void new_udpheader() +void new_udpheader(void) { if ((ip->ip_p) && (ip->ip_p != IPPROTO_UDP)) { fprintf(stderr, "protocol %d specified with UDP!\n", ip->ip_p); return; } ip->ip_p = IPPROTO_UDP; udp = (udphdr_t *)new_header(IPPROTO_UDP); udp->uh_ulen = sizeof(*udp); } void set_udplen(arg) char **arg; { int len; len = strtol(*arg, NULL, 0); inc_anipheaders(len - udp->uh_ulen); udp->uh_ulen = len; free(*arg); *arg = NULL; } -void set_udpsum(arg) -char **arg; +void set_udpsum(char **arg) { udp->uh_sum = strtol(*arg, NULL, 0); free(*arg); *arg = NULL; } -void prep_packet() +void prep_packet(void) { iface_t *ifp; struct in_addr gwip; ifp = sending.snd_if; if (!ifp) { fprintf(stderr, "no interface defined for sending!\n"); return; } if (ifp->if_fd == -1) ifp->if_fd = initdevice(ifp->if_name, 5); gwip = sending.snd_gw; if (!gwip.s_addr) { if (aniphead == NULL) { fprintf(stderr, "no destination address defined for sending\n"); return; } gwip = aniphead->ah_ip->ip_dst; } (void) send_ip(ifp->if_fd, ifp->if_MTU, (ip_t *)ipbuffer, gwip, 2); } -void packet_done() +void packet_done(void) { char outline[80]; int i, j, k; u_char *s = (u_char *)ipbuffer, *t = (u_char *)outline; if (opts & OPT_VERBOSE) { ip->ip_len = htons(ip->ip_len); for (i = ntohs(ip->ip_len), j = 0; i; i--, j++, s++) { if (j && !(j & 0xf)) { *t++ = '\n'; *t = '\0'; fputs(outline, stdout); fflush(stdout); t = (u_char *)outline; *t = '\0'; } sprintf((char *)t, "%02x", *s & 0xff); t += 2; if (!((j + 1) & 0xf)) { s -= 15; sprintf((char *)t, " "); t += 8; for (k = 16; k; k--, s++) *t++ = (isprint(*s) ? *s : '.'); s--; } if ((j + 1) & 0xf) *t++ = ' ';; } if (j & 0xf) { for (k = 16 - (j & 0xf); k; k--) { *t++ = ' '; *t++ = ' '; *t++ = ' '; } sprintf((char *)t, " "); t += 7; s -= j & 0xf; for (k = j & 0xf; k; k--, s++) *t++ = (isprint(*s) ? *s : '.'); *t++ = '\n'; *t = '\0'; } fputs(outline, stdout); fflush(stdout); ip->ip_len = ntohs(ip->ip_len); } prep_packet(); free_aniplist(); } -void new_interface() +void new_interface(void) { cifp = (iface_t *)calloc(1, sizeof(iface_t)); *iftail = cifp; iftail = &cifp->if_next; cifp->if_fd = -1; } -void check_interface() +void check_interface(void) { if (!cifp->if_name || !*cifp->if_name) fprintf(stderr, "No interface name given!\n"); if (!cifp->if_MTU || !*cifp->if_name) fprintf(stderr, "Interface %s has an MTU of 0!\n", cifp->if_name); } -void set_ifname(arg) -char **arg; +void set_ifname(char **arg) { cifp->if_name = *arg; *arg = NULL; } -void set_ifmtu(arg) -int arg; +void set_ifmtu(int arg) { cifp->if_MTU = arg; } -void set_ifv4addr(arg) -char **arg; +void set_ifv4addr(char **arg) { cifp->if_addr = getipv4addr(*arg); free(*arg); *arg = NULL; } -void set_ifeaddr(arg) -char **arg; +void set_ifeaddr(char **arg) { (void) geteaddr(*arg, &cifp->if_eaddr); free(*arg); *arg = NULL; } -void new_arp() +void new_arp(void) { carp = (arp_t *)calloc(1, sizeof(arp_t)); *arptail = carp; arptail = &carp->arp_next; } -void set_arpeaddr(arg) -char **arg; +void set_arpeaddr(char **arg) { (void) geteaddr(*arg, &carp->arp_eaddr); free(*arg); *arg = NULL; } -void set_arpv4addr(arg) -char **arg; +void set_arpv4addr(char **arg) { carp->arp_addr = getipv4addr(*arg); free(*arg); *arg = NULL; } -int arp_getipv4(ip, addr) -char *ip; -char *addr; +int arp_getipv4(char *ip, char *addr) { arp_t *a; for (a = arplist; a; a = a->arp_next) if (!bcmp(ip, (char *)&a->arp_addr, 4)) { bcopy((char *)&a->arp_eaddr, addr, 6); return 0; } return -1; } -void reset_send() +void reset_send(void) { sending.snd_if = iflist; sending.snd_gw = defrouter; } -void set_sendif(arg) -char **arg; +void set_sendif(char **arg) { iface_t *ifp; for (ifp = iflist; ifp; ifp = ifp->if_next) if (ifp->if_name && !strcmp(ifp->if_name, *arg)) break; sending.snd_if = ifp; if (!ifp) fprintf(stderr, "couldn't find interface %s\n", *arg); free(*arg); *arg = NULL; } -void set_sendvia(arg) -char **arg; +void set_sendvia(char **arg) { sending.snd_gw = getipv4addr(*arg); free(*arg); *arg = NULL; } -void set_defaultrouter(arg) -char **arg; +void set_defaultrouter(char **arg) { defrouter = getipv4addr(*arg); free(*arg); *arg = NULL; } -void new_icmpheader() +void new_icmpheader(void) { if ((ip->ip_p) && (ip->ip_p != IPPROTO_ICMP)) { fprintf(stderr, "protocol %d specified with ICMP!\n", ip->ip_p); return; } ip->ip_p = IPPROTO_ICMP; icmp = (icmphdr_t *)new_header(IPPROTO_ICMP); } -void set_icmpcode(code) -int code; +void set_icmpcode(int code) { icmp->icmp_code = code; } -void set_icmptype(type) -int type; +void set_icmptype(int type) { icmp->icmp_type = type; } -void set_icmpcodetok(code) -char **code; +void set_icmpcodetok(char **code) { char *s; int i; for (i = 0; (s = icmpcodes[i]); i++) if (!strcmp(s, *code)) { icmp->icmp_code = i; break; } if (!s) fprintf(stderr, "unknown ICMP code %s\n", *code); free(*code); *code = NULL; } -void set_icmptypetok(type) -char **type; +void set_icmptypetok(char **type) { char *s; int i, done = 0; for (i = 0; !(s = icmptypes[i]) || strcmp(s, "END"); i++) if (s && !strcmp(s, *type)) { icmp->icmp_type = i; done = 1; break; } if (!done) fprintf(stderr, "unknown ICMP type %s\n", *type); free(*type); *type = NULL; } -void set_icmpid(arg) -int arg; +void set_icmpid(int arg) { icmp->icmp_id = htons(arg); } -void set_icmpseq(arg) -int arg; +void set_icmpseq(int arg) { icmp->icmp_seq = htons(arg); } -void set_icmpotime(arg) -int arg; +void set_icmpotime(int arg) { icmp->icmp_otime = htonl(arg); } -void set_icmprtime(arg) -int arg; +void set_icmprtime(int arg) { icmp->icmp_rtime = htonl(arg); } -void set_icmpttime(arg) -int arg; +void set_icmpttime(int arg) { icmp->icmp_ttime = htonl(arg); } -void set_icmpmtu(arg) -int arg; +void set_icmpmtu(int arg) { icmp->icmp_nextmtu = htons(arg); } -void set_redir(redir, arg) -int redir; -char **arg; +void set_redir(int redir, char **arg) { icmp->icmp_code = redir; icmp->icmp_gwaddr = getipv4addr(*arg); free(*arg); *arg = NULL; } -void set_icmppprob(num) -int num; +void set_icmppprob(int num) { icmp->icmp_pptr = num; } -void new_ipv4opt() +void new_ipv4opt(void) { new_header(-2); } -void add_ipopt(state, ptr) -int state; -void *ptr; +void add_ipopt(int state, void *ptr) { struct ipopt_names *io; struct statetoopt *sto; char numbuf[16], *arg, **param = ptr; int inc, hlen; if (state == IL_IPO_RR || state == IL_IPO_SATID) { if (param) snprintf(numbuf, sizeof(numbuf), "%d", *(int *)param); else strcpy(numbuf, "0"); arg = numbuf; } else arg = param ? *param : NULL; if (canip->ah_next) { fprintf(stderr, "cannot specify options after data body\n"); return; } for (sto = toipopts; sto->sto_st; sto++) if (sto->sto_st == state) break; if (!sto->sto_st) { fprintf(stderr, "No mapping for state %d to IP option\n", state); return; } hlen = sizeof(ip_t) + canip->ah_optlen; for (io = ionames; io->on_name; io++) if (io->on_value == sto->sto_op) break; canip->ah_lastopt = io->on_value; if (io->on_name) { inc = addipopt((char *)ip + hlen, io, hlen - sizeof(ip_t),arg); if (inc > 0) { while (inc & 3) { ((char *)ip)[sizeof(*ip) + inc] = IPOPT_NOP; canip->ah_lastopt = IPOPT_NOP; inc++; } hlen += inc; } } canip->ah_optlen = hlen - sizeof(ip_t); if (state != IL_IPO_RR && state != IL_IPO_SATID) if (param && *param) { free(*param); *param = NULL; } sclass = NULL; } -void end_ipopt() +void end_ipopt(void) { int pad; char *s, *buf = (char *)ip; /* * pad out so that we have a multiple of 4 bytes in size fo the * options. make sure last byte is EOL. */ if (canip->ah_lastopt == IPOPT_NOP) { buf[sizeof(*ip) + canip->ah_optlen - 1] = IPOPT_EOL; } else if (canip->ah_lastopt != IPOPT_EOL) { s = buf + sizeof(*ip) + canip->ah_optlen; for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { *s++ = IPOPT_NOP; *s = IPOPT_EOL; canip->ah_optlen++; } canip->ah_optlen++; } else { s = buf + sizeof(*ip) + canip->ah_optlen - 1; for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) { *s++ = IPOPT_NOP; *s = IPOPT_EOL; canip->ah_optlen++; } } ip->ip_hl = (sizeof(*ip) + canip->ah_optlen) >> 2; inc_anipheaders(canip->ah_optlen); free_anipheader(); } -void set_secclass(arg) -char **arg; +void set_secclass(char **arg) { sclass = *arg; *arg = NULL; } -void free_anipheader() +void free_anipheader(void) { aniphdr_t *aip; aip = canip; if ((canip = aip->ah_prev)) { canip->ah_next = NULL; aniptail = &canip->ah_next; } if (canip) free(aip); } -void end_ipv4() +void end_ipv4(void) { aniphdr_t *aip; ip->ip_sum = 0; ip->ip_len = htons(ip->ip_len); ip->ip_sum = chksum((u_short *)ip, ip->ip_hl << 2); ip->ip_len = ntohs(ip->ip_len); free_anipheader(); for (aip = aniphead, ip = NULL; aip; aip = aip->ah_next) if (aip->ah_p == IPPROTO_IP) ip = aip->ah_ip; } -void end_icmp() +void end_icmp(void) { aniphdr_t *aip; icmp->icmp_cksum = 0; icmp->icmp_cksum = chksum((u_short *)icmp, canip->ah_len); free_anipheader(); for (aip = aniphead, icmp = NULL; aip; aip = aip->ah_next) if (aip->ah_p == IPPROTO_ICMP) icmp = aip->ah_icmp; } -void end_udp() +void end_udp(void) { u_long sum; aniphdr_t *aip; ip_t iptmp; bzero((char *)&iptmp, sizeof(iptmp)); iptmp.ip_p = ip->ip_p; iptmp.ip_src = ip->ip_src; iptmp.ip_dst = ip->ip_dst; iptmp.ip_len = htons(ip->ip_len - (ip->ip_hl << 2)); sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp)); udp->uh_ulen = htons(udp->uh_ulen); udp->uh_sum = c_chksum((u_short *)udp, (u_int)ntohs(iptmp.ip_len), sum); free_anipheader(); for (aip = aniphead, udp = NULL; aip; aip = aip->ah_next) if (aip->ah_p == IPPROTO_UDP) udp = aip->ah_udp; } -void end_tcp() +void end_tcp(void) { u_long sum; aniphdr_t *aip; ip_t iptmp; bzero((char *)&iptmp, sizeof(iptmp)); iptmp.ip_p = ip->ip_p; iptmp.ip_src = ip->ip_src; iptmp.ip_dst = ip->ip_dst; iptmp.ip_len = htons(ip->ip_len - (ip->ip_hl << 2)); sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp)); tcp->th_sum = 0; tcp->th_sum = c_chksum((u_short *)tcp, (u_int)ntohs(iptmp.ip_len), sum); free_anipheader(); for (aip = aniphead, tcp = NULL; aip; aip = aip->ah_next) if (aip->ah_p == IPPROTO_TCP) tcp = aip->ah_tcp; } -void end_data() +void end_data(void) { free_anipheader(); } -void iplang(fp) -FILE *fp; +void iplang(FILE *fp) { yyin = fp; yydebug = (opts & OPT_DEBUG) ? 1 : 0; while (!feof(fp)) yyparse(); } -u_short c_chksum(buf, len, init) -u_short *buf; -u_int len; -u_long init; +u_short c_chksum(u_short *buf, u_int len, u_long init) { u_long sum = init; int nwords = len >> 1; for(; nwords > 0; nwords--) sum += *buf++; sum = (sum>>16) + (sum & 0xffff); sum += (sum >>16); return (~sum); } -u_long p_chksum(buf,len) -u_short *buf; -u_int len; +u_long p_chksum(u_short *buf, u_int len) { u_long sum = 0; int nwords = len >> 1; for(; nwords > 0; nwords--) sum += *buf++; return sum; } diff --git a/sbin/ipf/ipmon/ipmon.c b/sbin/ipf/ipmon/ipmon.c index 9022f12b6149..c5dd8828d6d2 100644 --- a/sbin/ipf/ipmon/ipmon.c +++ b/sbin/ipf/ipmon/ipmon.c @@ -1,1872 +1,1855 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" #include "ipmon.h" #include #include #include #include #include #include #if !defined(lint) static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-2000 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #define STRERROR(x) strerror(x) extern int optind; extern char *optarg; extern ipmon_saver_t executesaver; extern ipmon_saver_t filesaver; extern ipmon_saver_t nothingsaver; extern ipmon_saver_t snmpv1saver; extern ipmon_saver_t snmpv2saver; extern ipmon_saver_t syslogsaver; struct flags { int value; char flag; }; typedef struct logsource { int fd; int logtype; char *file; int regular; size_t size; } logsource_t; typedef struct config { int opts; int maxfd; logsource_t logsrc[3]; fd_set fdmr; FILE *blog; char *bfile; FILE *log; char *file; char *cfile; } config_t; typedef struct icmp_subtype { int ist_val; char *ist_name; } icmp_subtype_t; typedef struct icmp_type { int it_val; struct icmp_subtype *it_subtable; size_t it_stsize; char *it_name; } icmp_type_t; #define IST_SZ(x) (sizeof(x)/sizeof(icmp_subtype_t)) struct flags tcpfl[] = { { TH_ACK, 'A' }, { TH_RST, 'R' }, { TH_SYN, 'S' }, { TH_FIN, 'F' }, { TH_URG, 'U' }, { TH_PUSH,'P' }, { TH_ECN, 'E' }, { TH_CWR, 'C' }, { 0, '\0' } }; char *reasons[] = { "filter-rule", "log-or-block_1", "pps-rate", "jumbogram", "makefrip-fail", "state_add-fail", "updateipid-fail", "log-or-block_2", "decap-fail", "auth_new-fail", "auth_captured", "coalesce-fail", "pullup-fail", "auth-feedback", "bad-frag", "natv4_out-fail", "natv4_in-fail", "natv6_out-fail", "natv6_in-fail", }; #if SOLARIS static char *pidfile = "/etc/opt/ipf/ipmon.pid"; #else static char *pidfile = "/var/run/ipmon.pid"; #endif static char line[2048]; static int donehup = 0; static void usage(char *); static void handlehup(int); static void flushlogs(char *, FILE *); static void print_log(config_t *, logsource_t *, char *, int); static void print_ipflog(config_t *, char *, int); static void print_natlog(config_t *, char *, int); static void print_statelog(config_t *, char *, int); static int read_log(int, int *, char *, int); static void write_pid(char *); static char *icmpname(u_int, u_int); static char *icmpname6(u_int, u_int); static icmp_type_t *find_icmptype(int, icmp_type_t *, size_t); static icmp_subtype_t *find_icmpsubtype(int, icmp_subtype_t *, size_t); static struct tm *get_tm(time_t); char *portlocalname(int, char *, u_int); int main(int, char *[]); static void logopts(int, char *); static void init_tabs(void); static char *getlocalproto(u_int); static void openlogs(config_t *conf); static int read_loginfo(config_t *conf); static void initconfig(config_t *conf); static char **protocols = NULL; static char **udp_ports = NULL; static char **tcp_ports = NULL; #define HOSTNAMEV4(b) hostname(AF_INET, (u_32_t *)&(b)) #ifndef LOGFAC #define LOGFAC LOG_LOCAL0 #endif int logfac = LOGFAC; int ipmonopts = 0; int opts = OPT_NORESOLVE; int use_inet6 = 0; static icmp_subtype_t icmpunreachnames[] = { { ICMP_UNREACH_NET, "net" }, { ICMP_UNREACH_HOST, "host" }, { ICMP_UNREACH_PROTOCOL, "protocol" }, { ICMP_UNREACH_PORT, "port" }, { ICMP_UNREACH_NEEDFRAG, "needfrag" }, { ICMP_UNREACH_SRCFAIL, "srcfail" }, { ICMP_UNREACH_NET_UNKNOWN, "net_unknown" }, { ICMP_UNREACH_HOST_UNKNOWN, "host_unknown" }, { ICMP_UNREACH_NET, "isolated" }, { ICMP_UNREACH_NET_PROHIB, "net_prohib" }, { ICMP_UNREACH_NET_PROHIB, "host_prohib" }, { ICMP_UNREACH_TOSNET, "tosnet" }, { ICMP_UNREACH_TOSHOST, "toshost" }, { ICMP_UNREACH_ADMIN_PROHIBIT, "admin_prohibit" }, { -2, NULL } }; static icmp_subtype_t redirectnames[] = { { ICMP_REDIRECT_NET, "net" }, { ICMP_REDIRECT_HOST, "host" }, { ICMP_REDIRECT_TOSNET, "tosnet" }, { ICMP_REDIRECT_TOSHOST, "toshost" }, { -2, NULL } }; static icmp_subtype_t timxceednames[] = { { ICMP_TIMXCEED_INTRANS, "transit" }, { ICMP_TIMXCEED_REASS, "reassem" }, { -2, NULL } }; static icmp_subtype_t paramnames[] = { { ICMP_PARAMPROB_ERRATPTR, "errata_pointer" }, { ICMP_PARAMPROB_OPTABSENT, "optmissing" }, { ICMP_PARAMPROB_LENGTH, "length" }, { -2, NULL } }; static icmp_type_t icmptypes4[] = { { ICMP_ECHOREPLY, NULL, 0, "echoreply" }, { -1, NULL, 0, NULL }, { -1, NULL, 0, NULL }, { ICMP_UNREACH, icmpunreachnames, IST_SZ(icmpunreachnames),"unreach" }, { ICMP_SOURCEQUENCH, NULL, 0, "sourcequench" }, { ICMP_REDIRECT, redirectnames, IST_SZ(redirectnames), "redirect" }, { -1, NULL, 0, NULL }, { -1, NULL, 0, NULL }, { ICMP_ECHO, NULL, 0, "echo" }, { ICMP_ROUTERADVERT, NULL, 0, "routeradvert" }, { ICMP_ROUTERSOLICIT, NULL, 0, "routersolicit" }, { ICMP_TIMXCEED, timxceednames, IST_SZ(timxceednames), "timxceed" }, { ICMP_PARAMPROB, paramnames, IST_SZ(paramnames), "paramprob" }, { ICMP_TSTAMP, NULL, 0, "timestamp" }, { ICMP_TSTAMPREPLY, NULL, 0, "timestampreply" }, { ICMP_IREQ, NULL, 0, "inforeq" }, { ICMP_IREQREPLY, NULL, 0, "inforeply" }, { ICMP_MASKREQ, NULL, 0, "maskreq" }, { ICMP_MASKREPLY, NULL, 0, "maskreply" }, { -2, NULL, 0, NULL } }; static icmp_subtype_t icmpredirect6[] = { { ICMP6_DST_UNREACH_NOROUTE, "noroute" }, { ICMP6_DST_UNREACH_ADMIN, "admin" }, { ICMP6_DST_UNREACH_NOTNEIGHBOR, "neighbour" }, { ICMP6_DST_UNREACH_ADDR, "address" }, { ICMP6_DST_UNREACH_NOPORT, "noport" }, { -2, NULL } }; static icmp_subtype_t icmptimexceed6[] = { { ICMP6_TIME_EXCEED_TRANSIT, "intransit" }, { ICMP6_TIME_EXCEED_REASSEMBLY, "reassem" }, { -2, NULL } }; static icmp_subtype_t icmpparamprob6[] = { { ICMP6_PARAMPROB_HEADER, "header" }, { ICMP6_PARAMPROB_NEXTHEADER, "nextheader" }, { ICMP6_PARAMPROB_OPTION, "option" }, { -2, NULL } }; static icmp_subtype_t icmpquerysubject6[] = { { ICMP6_NI_SUBJ_IPV6, "ipv6" }, { ICMP6_NI_SUBJ_FQDN, "fqdn" }, { ICMP6_NI_SUBJ_IPV4, "ipv4" }, { -2, NULL }, }; static icmp_subtype_t icmpnodeinfo6[] = { { ICMP6_NI_SUCCESS, "success" }, { ICMP6_NI_REFUSED, "refused" }, { ICMP6_NI_UNKNOWN, "unknown" }, { -2, NULL } }; static icmp_subtype_t icmprenumber6[] = { { ICMP6_ROUTER_RENUMBERING_COMMAND, "command" }, { ICMP6_ROUTER_RENUMBERING_RESULT, "result" }, { ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET, "seqnum_reset" }, { -2, NULL } }; static icmp_type_t icmptypes6[] = { { 0, NULL, 0, NULL }, { ICMP6_DST_UNREACH, icmpredirect6, IST_SZ(icmpredirect6), "unreach" }, { ICMP6_PACKET_TOO_BIG, NULL, 0, "toobig" }, { ICMP6_TIME_EXCEEDED, icmptimexceed6, IST_SZ(icmptimexceed6), "timxceed" }, { ICMP6_PARAM_PROB, icmpparamprob6, IST_SZ(icmpparamprob6), "paramprob" }, { ICMP6_ECHO_REQUEST, NULL, 0, "echo" }, { ICMP6_ECHO_REPLY, NULL, 0, "echoreply" }, { ICMP6_MEMBERSHIP_QUERY, icmpquerysubject6, IST_SZ(icmpquerysubject6), "groupmemberquery" }, { ICMP6_MEMBERSHIP_REPORT,NULL, 0, "groupmemberreport" }, { ICMP6_MEMBERSHIP_REDUCTION,NULL, 0, "groupmemberterm" }, { ND_ROUTER_SOLICIT, NULL, 0, "routersolicit" }, { ND_ROUTER_ADVERT, NULL, 0, "routeradvert" }, { ND_NEIGHBOR_SOLICIT, NULL, 0, "neighborsolicit" }, { ND_NEIGHBOR_ADVERT, NULL, 0, "neighboradvert" }, { ND_REDIRECT, NULL, 0, "redirect" }, { ICMP6_ROUTER_RENUMBERING, icmprenumber6, IST_SZ(icmprenumber6), "routerrenumber" }, { ICMP6_WRUREQUEST, NULL, 0, "whoareyourequest" }, { ICMP6_WRUREPLY, NULL, 0, "whoareyoureply" }, { ICMP6_FQDN_QUERY, NULL, 0, "fqdnquery" }, { ICMP6_FQDN_REPLY, NULL, 0, "fqdnreply" }, { ICMP6_NI_QUERY, icmpnodeinfo6, IST_SZ(icmpnodeinfo6), "nodeinforequest" }, { ICMP6_NI_REPLY, NULL, 0, "nodeinforeply" }, { MLD6_MTRACE_RESP, NULL, 0, "mtraceresponse" }, { MLD6_MTRACE, NULL, 0, "mtracerequest" }, { -2, NULL, 0, NULL } }; -static icmp_subtype_t *find_icmpsubtype(type, table, tablesz) - int type; - icmp_subtype_t *table; - size_t tablesz; +static icmp_subtype_t * +find_icmpsubtype(int type, icmp_subtype_t *table, size_t tablesz) { icmp_subtype_t *ist; int i; if (tablesz < 2) return NULL; if ((type < 0) || (type > table[tablesz - 2].ist_val)) return NULL; i = type; if (table[type].ist_val == type) return table + type; for (i = 0, ist = table; ist->ist_val != -2; i++, ist++) if (ist->ist_val == type) return ist; return NULL; } -static icmp_type_t *find_icmptype(type, table, tablesz) - int type; - icmp_type_t *table; - size_t tablesz; +static icmp_type_t * +find_icmptype(int type, icmp_type_t *table, size_t tablesz) { icmp_type_t *it; int i; if (tablesz < 2) return NULL; if ((type < 0) || (type > table[tablesz - 2].it_val)) return NULL; i = type; if (table[type].it_val == type) return table + type; for (i = 0, it = table; it->it_val != -2; i++, it++) if (it->it_val == type) return it; return NULL; } -static void handlehup(sig) - int sig; +static void +handlehup(int sig) { signal(SIGHUP, handlehup); donehup = 1; } -static void init_tabs() +static void +init_tabs(void) { struct protoent *p; struct servent *s; char *name, **tab; int port, i; if (protocols != NULL) { for (i = 0; i < 256; i++) if (protocols[i] != NULL) { free(protocols[i]); protocols[i] = NULL; } free(protocols); protocols = NULL; } protocols = (char **)malloc(256 * sizeof(*protocols)); if (protocols != NULL) { bzero((char *)protocols, 256 * sizeof(*protocols)); setprotoent(1); while ((p = getprotoent()) != NULL) if (p->p_proto >= 0 && p->p_proto <= 255 && p->p_name != NULL && protocols[p->p_proto] == NULL) protocols[p->p_proto] = strdup(p->p_name); endprotoent(); if (protocols[0]) free(protocols[0]); protocols[0] = strdup("ip"); } if (udp_ports != NULL) { for (i = 0; i < 65536; i++) if (udp_ports[i] != NULL) { free(udp_ports[i]); udp_ports[i] = NULL; } free(udp_ports); udp_ports = NULL; } udp_ports = (char **)malloc(65536 * sizeof(*udp_ports)); if (udp_ports != NULL) bzero((char *)udp_ports, 65536 * sizeof(*udp_ports)); if (tcp_ports != NULL) { for (i = 0; i < 65536; i++) if (tcp_ports[i] != NULL) { free(tcp_ports[i]); tcp_ports[i] = NULL; } free(tcp_ports); tcp_ports = NULL; } tcp_ports = (char **)malloc(65536 * sizeof(*tcp_ports)); if (tcp_ports != NULL) bzero((char *)tcp_ports, 65536 * sizeof(*tcp_ports)); setservent(1); while ((s = getservent()) != NULL) { if (s->s_proto == NULL) continue; else if (!strcmp(s->s_proto, "tcp")) { port = ntohs(s->s_port); name = s->s_name; tab = tcp_ports; } else if (!strcmp(s->s_proto, "udp")) { port = ntohs(s->s_port); name = s->s_name; tab = udp_ports; } else continue; if ((port < 0 || port > 65535) || (name == NULL)) continue; if (tab != NULL) tab[port] = strdup(name); } endservent(); } -static char *getlocalproto(p) - u_int p; +static char * +getlocalproto(u_int p) { static char pnum[4]; char *s; p &= 0xff; s = protocols ? protocols[p] : NULL; if (s == NULL) { sprintf(pnum, "%u", p); s = pnum; } return s; } -static int read_log(fd, lenp, buf, bufsize) - int fd, bufsize, *lenp; - char *buf; +static int +read_log(int fd, int *lenp, char *buf, int bufsize) { int nr; if (bufsize > IPFILTER_LOGSIZE) bufsize = IPFILTER_LOGSIZE; nr = read(fd, buf, bufsize); if (!nr) return 2; if ((nr < 0) && (errno != EINTR)) return -1; *lenp = nr; return 0; } -char *portlocalname(res, proto, port) +char * +portlocalname(res, proto, port) int res; char *proto; u_int port; { static char pname[8]; char *s; port = ntohs(port); port &= 0xffff; sprintf(pname, "%u", port); if (!res || (ipmonopts & IPMON_PORTNUM)) return pname; s = NULL; if (!strcmp(proto, "tcp")) s = tcp_ports[port]; else if (!strcmp(proto, "udp")) s = udp_ports[port]; if (s == NULL) s = pname; return s; } -static char *icmpname(type, code) - u_int type; - u_int code; +static char * +icmpname(u_int type, u_int code) { static char name[80]; icmp_subtype_t *ist; icmp_type_t *it; char *s; s = NULL; it = find_icmptype(type, icmptypes4, sizeof(icmptypes4) / sizeof(*it)); if (it != NULL) s = it->it_name; if (s == NULL) sprintf(name, "icmptype(%d)/", type); else sprintf(name, "%s/", s); ist = NULL; if (it != NULL && it->it_subtable != NULL) ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize); if (ist != NULL && ist->ist_name != NULL) strcat(name, ist->ist_name); else sprintf(name + strlen(name), "%d", code); return name; } -static char *icmpname6(type, code) - u_int type; - u_int code; +static char * +icmpname6(u_int type, u_int code) { static char name[80]; icmp_subtype_t *ist; icmp_type_t *it; char *s; s = NULL; it = find_icmptype(type, icmptypes6, sizeof(icmptypes6) / sizeof(*it)); if (it != NULL) s = it->it_name; if (s == NULL) sprintf(name, "icmpv6type(%d)/", type); else sprintf(name, "%s/", s); ist = NULL; if (it != NULL && it->it_subtable != NULL) ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize); if (ist != NULL && ist->ist_name != NULL) strcat(name, ist->ist_name); else sprintf(name + strlen(name), "%d", code); return name; } -void dumphex(log, dopts, buf, len) - FILE *log; - int dopts; - char *buf; - int len; +void +dumphex(FILE *log, int dopts, char *buf, int len) { char hline[80]; int i, j, k; u_char *s = (u_char *)buf, *t = (u_char *)hline; if (buf == NULL || len == 0) return; *hline = '\0'; for (i = len, j = 0; i; i--, j++, s++) { if (j && !(j & 0xf)) { *t++ = '\n'; *t = '\0'; if ((dopts & IPMON_SYSLOG)) syslog(LOG_INFO, "%s", hline); else if (log != NULL) fputs(hline, log); t = (u_char *)hline; *t = '\0'; } sprintf((char *)t, "%02x", *s & 0xff); t += 2; if (!((j + 1) & 0xf)) { s -= 15; sprintf((char *)t, " "); t += 8; for (k = 16; k; k--, s++) *t++ = (isprint(*s) ? *s : '.'); s--; } if ((j + 1) & 0xf) *t++ = ' ';; } if (j & 0xf) { for (k = 16 - (j & 0xf); k; k--) { *t++ = ' '; *t++ = ' '; *t++ = ' '; } sprintf((char *)t, " "); t += 7; s -= j & 0xf; for (k = j & 0xf; k; k--, s++) *t++ = (isprint(*s) ? *s : '.'); *t++ = '\n'; *t = '\0'; } if ((dopts & IPMON_SYSLOG) != 0) syslog(LOG_INFO, "%s", hline); else if (log != NULL) { fputs(hline, log); fflush(log); } } -static struct tm *get_tm(sec) - time_t sec; +static struct tm * +get_tm(time_t sec) { struct tm *tm; time_t t; t = sec; tm = localtime(&t); return tm; } -static void print_natlog(conf, buf, blen) - config_t *conf; - char *buf; - int blen; +static void +print_natlog(config_t *conf, char *buf, int blen) { static u_32_t seqnum = 0; int res, i, len, family; struct natlog *nl; struct tm *tm; iplog_t *ipl; char *proto; int simple; char *t; t = line; simple = 0; ipl = (iplog_t *)buf; if (ipl->ipl_seqnum != seqnum) { if ((ipmonopts & IPMON_SYSLOG) != 0) { syslog(LOG_WARNING, "missed %u NAT log entries: %u %u", ipl->ipl_seqnum - seqnum, seqnum, ipl->ipl_seqnum); } else { (void) fprintf(conf->log, "missed %u NAT log entries: %u %u\n", ipl->ipl_seqnum - seqnum, seqnum, ipl->ipl_seqnum); } } seqnum = ipl->ipl_seqnum + ipl->ipl_count; nl = (struct natlog *)((char *)ipl + sizeof(*ipl)); res = (ipmonopts & IPMON_RESOLVE) ? 1 : 0; tm = get_tm(ipl->ipl_sec); len = sizeof(line); if (!(ipmonopts & IPMON_SYSLOG)) { (void) strftime(t, len, "%d/%m/%Y ", tm); i = strlen(t); len -= i; t += i; } (void) strftime(t, len, "%T", tm); t += strlen(t); sprintf(t, ".%-.6ld @%hd ", (long)ipl->ipl_usec, nl->nl_rule + 1); t += strlen(t); switch (nl->nl_action) { case NL_NEW : strcpy(t, "NAT:NEW"); break; case NL_FLUSH : strcpy(t, "NAT:FLUSH"); break; case NL_CLONE : strcpy(t, "NAT:CLONE"); break; case NL_EXPIRE : strcpy(t, "NAT:EXPIRE"); break; case NL_DESTROY : strcpy(t, "NAT:DESTROY"); break; case NL_PURGE : strcpy(t, "NAT:PURGE"); break; default : sprintf(t, "NAT:Action(%d)", nl->nl_action); break; } t += strlen(t); switch (nl->nl_type) { case NAT_MAP : strcpy(t, "-MAP "); simple = 1; break; case NAT_REDIRECT : strcpy(t, "-RDR "); simple = 1; break; case NAT_BIMAP : strcpy(t, "-BIMAP "); simple = 1; break; case NAT_MAPBLK : strcpy(t, "-MAPBLOCK "); simple = 1; break; case NAT_REWRITE|NAT_MAP : strcpy(t, "-RWR_MAP "); break; case NAT_REWRITE|NAT_REDIRECT : strcpy(t, "-RWR_RDR "); break; case NAT_ENCAP|NAT_MAP : strcpy(t, "-ENC_MAP "); break; case NAT_ENCAP|NAT_REDIRECT : strcpy(t, "-ENC_RDR "); break; case NAT_DIVERTUDP|NAT_MAP : strcpy(t, "-DIV_MAP "); break; case NAT_DIVERTUDP|NAT_REDIRECT : strcpy(t, "-DIV_RDR "); break; default : sprintf(t, "-Type(%d) ", nl->nl_type); break; } t += strlen(t); proto = getlocalproto(nl->nl_p[0]); family = vtof(nl->nl_v[0]); if (simple == 1) { sprintf(t, "%s,%s <- -> ", hostname(family, nl->nl_osrcip.i6), portlocalname(res, proto, (u_int)nl->nl_osrcport)); t += strlen(t); sprintf(t, "%s,%s ", hostname(family, nl->nl_nsrcip.i6), portlocalname(res, proto, (u_int)nl->nl_nsrcport)); t += strlen(t); sprintf(t, "[%s,%s] ", hostname(family, nl->nl_odstip.i6), portlocalname(res, proto, (u_int)nl->nl_odstport)); } else { sprintf(t, "%s,%s ", hostname(family, nl->nl_osrcip.i6), portlocalname(res, proto, (u_int)nl->nl_osrcport)); t += strlen(t); sprintf(t, "%s,%s <- -> ", hostname(family, nl->nl_odstip.i6), portlocalname(res, proto, (u_int)nl->nl_odstport)); t += strlen(t); sprintf(t, "%s,%s ", hostname(family, nl->nl_nsrcip.i6), portlocalname(res, proto, (u_int)nl->nl_nsrcport)); t += strlen(t); sprintf(t, "%s,%s ", hostname(family, nl->nl_ndstip.i6), portlocalname(res, proto, (u_int)nl->nl_ndstport)); } t += strlen(t); strcpy(t, getlocalproto(nl->nl_p[0])); t += strlen(t); if (nl->nl_action == NL_EXPIRE || nl->nl_action == NL_FLUSH) { #ifdef USE_QUAD_T # ifdef PRId64 sprintf(t, " Pkts %" PRId64 "/%" PRId64 " Bytes %" PRId64 "/%" PRId64, # else sprintf(t, " Pkts %qd/%qd Bytes %qd/%qd", # endif #else sprintf(t, " Pkts %ld/%ld Bytes %ld/%ld", #endif nl->nl_pkts[0], nl->nl_pkts[1], nl->nl_bytes[0], nl->nl_bytes[1]); t += strlen(t); } *t++ = '\n'; *t++ = '\0'; if (ipmonopts & IPMON_SYSLOG) syslog(LOG_INFO, "%s", line); else if (conf->log != NULL) (void) fprintf(conf->log, "%s", line); } -static void print_statelog(conf, buf, blen) - config_t *conf; - char *buf; - int blen; +static void +print_statelog(config_t *conf, char *buf, int blen) { static u_32_t seqnum = 0; int res, i, len, family; struct ipslog *sl; char *t, *proto; struct tm *tm; iplog_t *ipl; t = line; ipl = (iplog_t *)buf; if (ipl->ipl_seqnum != seqnum) { if ((ipmonopts & IPMON_SYSLOG) != 0) { syslog(LOG_WARNING, "missed %u state log entries: %u %u", ipl->ipl_seqnum - seqnum, seqnum, ipl->ipl_seqnum); } else { (void) fprintf(conf->log, "missed %u state log entries: %u %u\n", ipl->ipl_seqnum - seqnum, seqnum, ipl->ipl_seqnum); } } seqnum = ipl->ipl_seqnum + ipl->ipl_count; sl = (struct ipslog *)((char *)ipl + sizeof(*ipl)); res = (ipmonopts & IPMON_RESOLVE) ? 1 : 0; tm = get_tm(ipl->ipl_sec); len = sizeof(line); if (!(ipmonopts & IPMON_SYSLOG)) { (void) strftime(t, len, "%d/%m/%Y ", tm); i = strlen(t); len -= i; t += i; } (void) strftime(t, len, "%T", tm); t += strlen(t); sprintf(t, ".%-.6ld ", (long)ipl->ipl_usec); t += strlen(t); family = vtof(sl->isl_v); switch (sl->isl_type) { case ISL_NEW : strcpy(t, "STATE:NEW "); break; case ISL_CLONE : strcpy(t, "STATE:CLONED "); break; case ISL_EXPIRE : if ((sl->isl_p == IPPROTO_TCP) && (sl->isl_state[0] > IPF_TCPS_ESTABLISHED || sl->isl_state[1] > IPF_TCPS_ESTABLISHED)) strcpy(t, "STATE:CLOSE "); else strcpy(t, "STATE:EXPIRE "); break; case ISL_FLUSH : strcpy(t, "STATE:FLUSH "); break; case ISL_INTERMEDIATE : strcpy(t, "STATE:INTERMEDIATE "); break; case ISL_REMOVE : strcpy(t, "STATE:REMOVE "); break; case ISL_KILLED : strcpy(t, "STATE:KILLED "); break; case ISL_UNLOAD : strcpy(t, "STATE:UNLOAD "); break; default : sprintf(t, "Type: %d ", sl->isl_type); break; } t += strlen(t); proto = getlocalproto(sl->isl_p); if (sl->isl_p == IPPROTO_TCP || sl->isl_p == IPPROTO_UDP) { sprintf(t, "%s,%s -> ", hostname(family, (u_32_t *)&sl->isl_src), portlocalname(res, proto, (u_int)sl->isl_sport)); t += strlen(t); sprintf(t, "%s,%s PR %s", hostname(family, (u_32_t *)&sl->isl_dst), portlocalname(res, proto, (u_int)sl->isl_dport), proto); } else if (sl->isl_p == IPPROTO_ICMP) { sprintf(t, "%s -> ", hostname(family, (u_32_t *)&sl->isl_src)); t += strlen(t); sprintf(t, "%s PR icmp %d", hostname(family, (u_32_t *)&sl->isl_dst), sl->isl_itype); } else if (sl->isl_p == IPPROTO_ICMPV6) { sprintf(t, "%s -> ", hostname(family, (u_32_t *)&sl->isl_src)); t += strlen(t); sprintf(t, "%s PR icmpv6 %d", hostname(family, (u_32_t *)&sl->isl_dst), sl->isl_itype); } else { sprintf(t, "%s -> ", hostname(family, (u_32_t *)&sl->isl_src)); t += strlen(t); sprintf(t, "%s PR %s", hostname(family, (u_32_t *)&sl->isl_dst), proto); } t += strlen(t); if (sl->isl_tag != FR_NOLOGTAG) { sprintf(t, " tag %u", sl->isl_tag); t += strlen(t); } if (sl->isl_type != ISL_NEW) { sprintf(t, #ifdef USE_QUAD_T #ifdef PRId64 " Forward: Pkts in %" PRId64 " Bytes in %" PRId64 " Pkts out %" PRId64 " Bytes out %" PRId64 " Backward: Pkts in %" PRId64 " Bytes in %" PRId64 " Pkts out %" PRId64 " Bytes out %" PRId64, #else " Forward: Pkts in %qd Bytes in %qd Pkts out %qd Bytes out %qd Backward: Pkts in %qd Bytes in %qd Pkts out %qd Bytes out %qd", #endif /* PRId64 */ #else " Forward: Pkts in %ld Bytes in %ld Pkts out %ld Bytes out %ld Backward: Pkts in %ld Bytes in %ld Pkts out %ld Bytes out %ld", #endif sl->isl_pkts[0], sl->isl_bytes[0], sl->isl_pkts[1], sl->isl_bytes[1], sl->isl_pkts[2], sl->isl_bytes[2], sl->isl_pkts[3], sl->isl_bytes[3]); t += strlen(t); } *t++ = '\n'; *t++ = '\0'; if (ipmonopts & IPMON_SYSLOG) syslog(LOG_INFO, "%s", line); else if (conf->log != NULL) (void) fprintf(conf->log, "%s", line); } -static void print_log(conf, log, buf, blen) - config_t *conf; - logsource_t *log; - char *buf; - int blen; +static void +print_log(config_t *conf, logsource_t *log, char *buf, int blen) { char *bp, *bpo; iplog_t *ipl; int psize; bp = NULL; bpo = NULL; while (blen > 0) { ipl = (iplog_t *)buf; if ((u_long)ipl & (sizeof(long)-1)) { if (bp) bpo = bp; bp = (char *)malloc(blen); bcopy((char *)ipl, bp, blen); if (bpo) { free(bpo); bpo = NULL; } buf = bp; continue; } psize = ipl->ipl_dsize; if (psize > blen) break; if (conf->blog != NULL) { fwrite(buf, psize, 1, conf->blog); fflush(conf->blog); } if (log->logtype == IPL_LOGIPF) { if (ipl->ipl_magic == IPL_MAGIC) print_ipflog(conf, buf, psize); } else if (log->logtype == IPL_LOGNAT) { if (ipl->ipl_magic == IPL_MAGIC_NAT) print_natlog(conf, buf, psize); } else if (log->logtype == IPL_LOGSTATE) { if (ipl->ipl_magic == IPL_MAGIC_STATE) print_statelog(conf, buf, psize); } blen -= psize; buf += psize; } if (bp) free(bp); return; } -static void print_ipflog(conf, buf, blen) - config_t *conf; - char *buf; - int blen; +static void +print_ipflog(config_t *conf, char *buf, int blen) { static u_32_t seqnum = 0; int i, f, lvl, res, len, off, plen, ipoff, defaction; struct icmp *icmp; struct icmp *ic; char *t, *proto; ip_t *ipc, *ip; struct tm *tm; u_32_t *s, *d; u_short hl, p; ipflog_t *ipf; iplog_t *ipl; tcphdr_t *tp; #ifdef USE_INET6 struct ip6_ext *ehp; u_short ehl; ip6_t *ip6; int go; #endif ipl = (iplog_t *)buf; if (ipl->ipl_seqnum != seqnum) { if ((ipmonopts & IPMON_SYSLOG) != 0) { syslog(LOG_WARNING, "missed %u ipf log entries: %u %u", ipl->ipl_seqnum - seqnum, seqnum, ipl->ipl_seqnum); } else { (void) fprintf(conf->log, "missed %u ipf log entries: %u %u\n", ipl->ipl_seqnum - seqnum, seqnum, ipl->ipl_seqnum); } } seqnum = ipl->ipl_seqnum + ipl->ipl_count; ipf = (ipflog_t *)((char *)buf + sizeof(*ipl)); ip = (ip_t *)((char *)ipf + sizeof(*ipf)); f = ipf->fl_family; res = (ipmonopts & IPMON_RESOLVE) ? 1 : 0; t = line; *t = '\0'; tm = get_tm(ipl->ipl_sec); len = sizeof(line); if (!(ipmonopts & IPMON_SYSLOG)) { (void) strftime(t, len, "%d/%m/%Y ", tm); i = strlen(t); len -= i; t += i; } (void) strftime(t, len, "%T", tm); t += strlen(t); sprintf(t, ".%-.6ld ", (long)ipl->ipl_usec); t += strlen(t); if (ipl->ipl_count > 1) { sprintf(t, "%dx ", ipl->ipl_count); t += strlen(t); } { char ifname[sizeof(ipf->fl_ifname) + 1]; strncpy(ifname, ipf->fl_ifname, sizeof(ipf->fl_ifname)); ifname[sizeof(ipf->fl_ifname)] = '\0'; sprintf(t, "%s", ifname); t += strlen(t); # if SOLARIS if (ISALPHA(*(t - 1))) { sprintf(t, "%d", ipf->fl_unit); t += strlen(t); } # endif } if ((ipf->fl_group[0] == (char)~0) && (ipf->fl_group[1] == '\0')) strcat(t, " @-1:"); else if (ipf->fl_group[0] == '\0') (void) strcpy(t, " @0:"); else sprintf(t, " @%s:", ipf->fl_group); t += strlen(t); if (ipf->fl_rule == 0xffffffff) strcat(t, "-1 "); else sprintf(t, "%u ", ipf->fl_rule + 1); t += strlen(t); lvl = LOG_NOTICE; if (ipf->fl_lflags & FI_SHORT) { *t++ = 'S'; lvl = LOG_ERR; } if (FR_ISPASS(ipf->fl_flags)) { if (ipf->fl_flags & FR_LOGP) *t++ = 'p'; else *t++ = 'P'; } else if (FR_ISBLOCK(ipf->fl_flags)) { if (ipf->fl_flags & FR_LOGB) *t++ = 'b'; else *t++ = 'B'; lvl = LOG_WARNING; } else if ((ipf->fl_flags & FR_LOGMASK) == FR_LOG) { *t++ = 'L'; lvl = LOG_INFO; } else if (ipf->fl_flags & FF_LOGNOMATCH) { *t++ = 'n'; } else { *t++ = '?'; lvl = LOG_EMERG; } if (ipf->fl_loglevel != 0xffff) lvl = ipf->fl_loglevel; *t++ = ' '; *t = '\0'; if (f == AF_INET) { hl = IP_HL(ip) << 2; ipoff = ntohs(ip->ip_off); off = ipoff & IP_OFFMASK; p = (u_short)ip->ip_p; s = (u_32_t *)&ip->ip_src; d = (u_32_t *)&ip->ip_dst; plen = ntohs(ip->ip_len); } else #ifdef USE_INET6 if (f == AF_INET6) { off = 0; ipoff = 0; hl = sizeof(ip6_t); ip6 = (ip6_t *)ip; p = (u_short)ip6->ip6_nxt; s = (u_32_t *)&ip6->ip6_src; d = (u_32_t *)&ip6->ip6_dst; plen = hl + ntohs(ip6->ip6_plen); go = 1; ehp = (struct ip6_ext *)((char *)ip6 + hl); while (go == 1) { switch (p) { case IPPROTO_HOPOPTS : case IPPROTO_MOBILITY : case IPPROTO_DSTOPTS : case IPPROTO_ROUTING : case IPPROTO_AH : p = ehp->ip6e_nxt; ehl = 8 + (ehp->ip6e_len << 3); hl += ehl; ehp = (struct ip6_ext *)((char *)ehp + ehl); break; case IPPROTO_FRAGMENT : hl += sizeof(struct ip6_frag); /* FALLTHROUGH */ default : go = 0; break; } } } else #endif { goto printipflog; } proto = getlocalproto(p); if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !off) { tp = (tcphdr_t *)((char *)ip + hl); if (!(ipf->fl_lflags & FI_SHORT)) { sprintf(t, "%s,%s -> ", hostname(f, s), portlocalname(res, proto, (u_int)tp->th_sport)); t += strlen(t); sprintf(t, "%s,%s PR %s len %hu %hu", hostname(f, d), portlocalname(res, proto, (u_int)tp->th_dport), proto, hl, plen); t += strlen(t); if (p == IPPROTO_TCP) { *t++ = ' '; *t++ = '-'; for (i = 0; tcpfl[i].value; i++) if (tp->th_flags & tcpfl[i].value) *t++ = tcpfl[i].flag; if (ipmonopts & IPMON_VERBOSE) { sprintf(t, " %lu %lu %hu", (u_long)(ntohl(tp->th_seq)), (u_long)(ntohl(tp->th_ack)), ntohs(tp->th_win)); t += strlen(t); } } *t = '\0'; } else { sprintf(t, "%s -> ", hostname(f, s)); t += strlen(t); sprintf(t, "%s PR %s len %hu %hu", hostname(f, d), proto, hl, plen); } #if defined(AF_INET6) && defined(IPPROTO_ICMPV6) } else if ((p == IPPROTO_ICMPV6) && !off && (f == AF_INET6)) { ic = (struct icmp *)((char *)ip + hl); sprintf(t, "%s -> ", hostname(f, s)); t += strlen(t); sprintf(t, "%s PR icmpv6 len %hu %hu icmpv6 %s", hostname(f, d), hl, plen, icmpname6(ic->icmp_type, ic->icmp_code)); #endif } else if ((p == IPPROTO_ICMP) && !off && (f == AF_INET)) { ic = (struct icmp *)((char *)ip + hl); sprintf(t, "%s -> ", hostname(f, s)); t += strlen(t); sprintf(t, "%s PR icmp len %hu %hu icmp %s", hostname(f, d), hl, plen, icmpname(ic->icmp_type, ic->icmp_code)); if (ic->icmp_type == ICMP_UNREACH || ic->icmp_type == ICMP_SOURCEQUENCH || ic->icmp_type == ICMP_PARAMPROB || ic->icmp_type == ICMP_REDIRECT || ic->icmp_type == ICMP_TIMXCEED) { ipc = &ic->icmp_ip; i = ntohs(ipc->ip_len); /* * XXX - try to guess endian of ip_len in ICMP * returned data. */ if (i > 1500) i = ipc->ip_len; ipoff = ntohs(ipc->ip_off); proto = getlocalproto(ipc->ip_p); if (!(ipoff & IP_OFFMASK) && ((ipc->ip_p == IPPROTO_TCP) || (ipc->ip_p == IPPROTO_UDP))) { tp = (tcphdr_t *)((char *)ipc + hl); t += strlen(t); sprintf(t, " for %s,%s -", HOSTNAMEV4(ipc->ip_src), portlocalname(res, proto, (u_int)tp->th_sport)); t += strlen(t); sprintf(t, " %s,%s PR %s len %hu %hu", HOSTNAMEV4(ipc->ip_dst), portlocalname(res, proto, (u_int)tp->th_dport), proto, IP_HL(ipc) << 2, i); } else if (!(ipoff & IP_OFFMASK) && (ipc->ip_p == IPPROTO_ICMP)) { icmp = (icmphdr_t *)((char *)ipc + hl); t += strlen(t); sprintf(t, " for %s -", HOSTNAMEV4(ipc->ip_src)); t += strlen(t); sprintf(t, " %s PR icmp len %hu %hu icmp %d/%d", HOSTNAMEV4(ipc->ip_dst), IP_HL(ipc) << 2, i, icmp->icmp_type, icmp->icmp_code); } else { t += strlen(t); sprintf(t, " for %s -", HOSTNAMEV4(ipc->ip_src)); t += strlen(t); sprintf(t, " %s PR %s len %hu (%hu)", HOSTNAMEV4(ipc->ip_dst), proto, IP_HL(ipc) << 2, i); t += strlen(t); if (ipoff & IP_OFFMASK) { sprintf(t, "(frag %d:%hu@%hu%s%s)", ntohs(ipc->ip_id), i - (IP_HL(ipc) << 2), (ipoff & IP_OFFMASK) << 3, ipoff & IP_MF ? "+" : "", ipoff & IP_DF ? "-" : ""); } } } } else { sprintf(t, "%s -> ", hostname(f, s)); t += strlen(t); sprintf(t, "%s PR %s len %hu (%hu)", hostname(f, d), proto, hl, plen); t += strlen(t); if (off & IP_OFFMASK) sprintf(t, " (frag %d:%hu@%hu%s%s)", ntohs(ip->ip_id), plen - hl, (off & IP_OFFMASK) << 3, ipoff & IP_MF ? "+" : "", ipoff & IP_DF ? "-" : ""); } t += strlen(t); printipflog: if (ipf->fl_flags & FR_KEEPSTATE) { (void) strcpy(t, " K-S"); t += strlen(t); } if (ipf->fl_flags & FR_KEEPFRAG) { (void) strcpy(t, " K-F"); t += strlen(t); } if (ipf->fl_dir == 0) strcpy(t, " IN"); else if (ipf->fl_dir == 1) strcpy(t, " OUT"); t += strlen(t); if (ipf->fl_logtag != 0) { sprintf(t, " log-tag %d", ipf->fl_logtag); t += strlen(t); } if (ipf->fl_nattag.ipt_num[0] != 0) { strcpy(t, " nat-tag "); t += strlen(t); strncpy(t, ipf->fl_nattag.ipt_tag, sizeof(ipf->fl_nattag)); t += strlen(t); } if ((ipf->fl_lflags & FI_LOWTTL) != 0) { strcpy(t, " low-ttl"); t += 8; } if ((ipf->fl_lflags & FI_OOW) != 0) { strcpy(t, " OOW"); t += 4; } if ((ipf->fl_lflags & FI_BAD) != 0) { strcpy(t, " bad"); t += 4; } if ((ipf->fl_lflags & FI_NATED) != 0) { strcpy(t, " NAT"); t += 4; } if ((ipf->fl_lflags & FI_BADNAT) != 0) { strcpy(t, " bad-NAT"); t += 8; } if ((ipf->fl_lflags & FI_BADSRC) != 0) { strcpy(t, " bad-src"); t += 8; } if ((ipf->fl_lflags & FI_MULTICAST) != 0) { strcpy(t, " multicast"); t += 10; } if ((ipf->fl_lflags & FI_BROADCAST) != 0) { strcpy(t, " broadcast"); t += 10; } if ((ipf->fl_lflags & (FI_MULTICAST|FI_BROADCAST|FI_MBCAST)) == FI_MBCAST) { strcpy(t, " mbcast"); t += 7; } if (ipf->fl_breason != 0) { strcpy(t, " reason:"); t += 8; strcpy(t, reasons[ipf->fl_breason]); t += strlen(reasons[ipf->fl_breason]); } *t++ = '\n'; *t++ = '\0'; defaction = 0; if (conf->cfile != NULL) defaction = check_action(buf, line, ipmonopts, lvl); if (defaction == 0) { if (ipmonopts & IPMON_SYSLOG) { syslog(lvl, "%s", line); } else if (conf->log != NULL) { (void) fprintf(conf->log, "%s", line); } if (ipmonopts & IPMON_HEXHDR) { dumphex(conf->log, ipmonopts, buf, sizeof(iplog_t) + sizeof(*ipf)); } if (ipmonopts & IPMON_HEXBODY) { dumphex(conf->log, ipmonopts, (char *)ip, ipf->fl_plen + ipf->fl_hlen); } else if ((ipmonopts & IPMON_LOGBODY) && (ipf->fl_flags & FR_LOGBODY)) { dumphex(conf->log, ipmonopts, (char *)ip + ipf->fl_hlen, ipf->fl_plen); } } } -static void usage(prog) - char *prog; +static void +usage(char *prog) { fprintf(stderr, "Usage: %s [ -abDFhnpstvxX ] [ -B ] [ -C ]\n" "\t[ -f ] [ -L ] [ -N ]\n" "\t[ -o [NSI] ] [ -O [NSI] ] [ -P ] [ -S ]\n" "\t[ ]\n", prog); exit(1); } -static void write_pid(file) - char *file; +static void +write_pid(char *file) { FILE *fp = NULL; int fd; if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0644)) >= 0) { fp = fdopen(fd, "w"); if (fp == NULL) { close(fd); fprintf(stderr, "unable to open/create pid file: %s\n", file); return; } fprintf(fp, "%d", getpid()); fclose(fp); } } -static void flushlogs(file, log) - char *file; - FILE *log; +static void +flushlogs(char *file, FILE *log) { int fd, flushed = 0; if ((fd = open(file, O_RDWR)) == -1) { (void) fprintf(stderr, "%s: open: %s\n", file, STRERROR(errno)); exit(1); } if (ioctl(fd, SIOCIPFFB, &flushed) == 0) { printf("%d bytes flushed from log buffer\n", flushed); fflush(stdout); } else ipferror(fd, "SIOCIPFFB"); (void) close(fd); if (flushed) { if (ipmonopts & IPMON_SYSLOG) { syslog(LOG_INFO, "%d bytes flushed from log\n", flushed); } else if ((log != stdout) && (log != NULL)) { fprintf(log, "%d bytes flushed from log\n", flushed); } } } -static void logopts(turnon, options) - int turnon; - char *options; +static void +logopts(int turnon, char *options) { int flags = 0; char *s; for (s = options; *s; s++) { switch (*s) { case 'N' : flags |= IPMON_NAT; break; case 'S' : flags |= IPMON_STATE; break; case 'I' : flags |= IPMON_FILTER; break; default : fprintf(stderr, "Unknown log option %c\n", *s); exit(1); } } if (turnon) ipmonopts |= flags; else ipmonopts &= ~(flags); } -static void initconfig(config_t *conf) +static void +initconfig(config_t *conf) { int i; memset(conf, 0, sizeof(*conf)); conf->log = stdout; conf->maxfd = -1; for (i = 0; i < 3; i++) { conf->logsrc[i].fd = -1; conf->logsrc[i].logtype = -1; conf->logsrc[i].regular = -1; } conf->logsrc[0].file = IPL_NAME; conf->logsrc[1].file = IPNAT_NAME; conf->logsrc[2].file = IPSTATE_NAME; add_doing(&executesaver); add_doing(&snmpv1saver); add_doing(&snmpv2saver); add_doing(&syslogsaver); add_doing(&filesaver); add_doing(¬hingsaver); } -int main(argc, argv) - int argc; - char *argv[]; +int +main(int argc, char *argv[]) { int doread, c, make_daemon = 0; char *prog; config_t config; prog = strrchr(argv[0], '/'); if (prog == NULL) prog = argv[0]; else prog++; initconfig(&config); while ((c = getopt(argc, argv, "?abB:C:Df:FhL:nN:o:O:pP:sS:tvxX")) != -1) switch (c) { case 'a' : ipmonopts |= IPMON_LOGALL; config.logsrc[0].logtype = IPL_LOGIPF; config.logsrc[1].logtype = IPL_LOGNAT; config.logsrc[2].logtype = IPL_LOGSTATE; break; case 'b' : ipmonopts |= IPMON_LOGBODY; break; case 'B' : config.bfile = optarg; config.blog = fopen(optarg, "a"); break; case 'C' : config.cfile = optarg; break; case 'D' : make_daemon = 1; break; case 'f' : case 'I' : ipmonopts |= IPMON_FILTER; config.logsrc[0].logtype = IPL_LOGIPF; config.logsrc[0].file = optarg; break; case 'F' : flushlogs(config.logsrc[0].file, config.log); flushlogs(config.logsrc[1].file, config.log); flushlogs(config.logsrc[2].file, config.log); break; case 'L' : logfac = fac_findname(optarg); if (logfac == -1) { fprintf(stderr, "Unknown syslog facility '%s'\n", optarg); exit(1); } break; case 'n' : ipmonopts |= IPMON_RESOLVE; opts &= ~OPT_NORESOLVE; break; case 'N' : ipmonopts |= IPMON_NAT; config.logsrc[1].logtype = IPL_LOGNAT; config.logsrc[1].file = optarg; break; case 'o' : case 'O' : logopts(c == 'o', optarg); if (ipmonopts & IPMON_FILTER) config.logsrc[0].logtype = IPL_LOGIPF; if (ipmonopts & IPMON_NAT) config.logsrc[1].logtype = IPL_LOGNAT; if (ipmonopts & IPMON_STATE) config.logsrc[2].logtype = IPL_LOGSTATE; break; case 'p' : ipmonopts |= IPMON_PORTNUM; break; case 'P' : pidfile = optarg; break; case 's' : ipmonopts |= IPMON_SYSLOG; config.log = NULL; break; case 'S' : ipmonopts |= IPMON_STATE; config.logsrc[2].logtype = IPL_LOGSTATE; config.logsrc[2].file = optarg; break; case 't' : ipmonopts |= IPMON_TAIL; break; case 'v' : ipmonopts |= IPMON_VERBOSE; break; case 'x' : ipmonopts |= IPMON_HEXBODY; break; case 'X' : ipmonopts |= IPMON_HEXHDR; break; default : case 'h' : case '?' : usage(argv[0]); } if (ipmonopts & IPMON_SYSLOG) openlog(prog, LOG_NDELAY|LOG_PID, logfac); init_tabs(); if (config.cfile) if (load_config(config.cfile) == -1) { unload_config(); exit(1); } /* * Default action is to only open the filter log file. */ if ((config.logsrc[0].logtype == -1) && (config.logsrc[0].logtype == -1) && (config.logsrc[0].logtype == -1)) config.logsrc[0].logtype = IPL_LOGIPF; openlogs(&config); if (!(ipmonopts & IPMON_SYSLOG)) { config.file = argv[optind]; config.log = config.file ? fopen(config.file, "a") : stdout; if (config.log == NULL) { (void) fprintf(stderr, "%s: fopen: %s\n", argv[optind], STRERROR(errno)); exit(1); /* NOTREACHED */ } setvbuf(config.log, NULL, _IONBF, 0); } else { config.log = NULL; } if (make_daemon && ((config.log != stdout) || (ipmonopts & IPMON_SYSLOG))) { #ifdef BSD daemon(0, !(ipmonopts & IPMON_SYSLOG)); #else int pid; switch (fork()) { case -1 : (void) fprintf(stderr, "%s: fork() failed: %s\n", argv[0], STRERROR(errno)); exit(1); /* NOTREACHED */ case 0 : break; default : exit(0); } setsid(); if ((ipmonopts & IPMON_SYSLOG)) close(2); #endif /* !BSD */ close(0); close(1); write_pid(pidfile); } signal(SIGHUP, handlehup); for (doread = 1; doread; ) doread = read_loginfo(&config); unload_config(); return(0); /* NOTREACHED */ } -static void openlogs(config_t *conf) +static void +openlogs(config_t *conf) { logsource_t *l; struct stat sb; int i; for (i = 0; i < 3; i++) { l = &conf->logsrc[i]; if (l->logtype == -1) continue; if (!strcmp(l->file, "-")) l->fd = 0; else { if ((l->fd= open(l->file, O_RDONLY)) == -1) { (void) fprintf(stderr, "%s: open: %s\n", l->file, STRERROR(errno)); exit(1); /* NOTREACHED */ } if (fstat(l->fd, &sb) == -1) { (void) fprintf(stderr, "%d: fstat: %s\n", l->fd, STRERROR(errno)); exit(1); /* NOTREACHED */ } l->regular = !S_ISCHR(sb.st_mode); if (l->regular) l->size = sb.st_size; FD_SET(l->fd, &conf->fdmr); if (l->fd > conf->maxfd) conf->maxfd = l->fd; } } } -static int read_loginfo(config_t *conf) +static int +read_loginfo(config_t *conf) { iplog_t buf[DEFAULT_IPFLOGSIZE/sizeof(iplog_t)+1]; int n, tr, nr, i; logsource_t *l; fd_set fdr; fdr = conf->fdmr; n = select(conf->maxfd + 1, &fdr, NULL, NULL, NULL); if (n == 0) return 1; if (n == -1) { if (errno == EINTR) return 1; return -1; } for (i = 0, nr = 0; i < 3; i++) { l = &conf->logsrc[i]; if ((l->logtype == -1) || !FD_ISSET(l->fd, &fdr)) continue; tr = 0; if (l->regular) { tr = (lseek(l->fd, 0, SEEK_CUR) < l->size); if (!tr && !(ipmonopts & IPMON_TAIL)) return 0; } n = 0; tr = read_log(l->fd, &n, (char *)buf, sizeof(buf)); if (donehup) { if (conf->file != NULL) { if (conf->log != NULL) { fclose(conf->log); conf->log = NULL; } conf->log = fopen(conf->file, "a"); } if (conf->bfile != NULL) { if (conf->blog != NULL) { fclose(conf->blog); conf->blog = NULL; } conf->blog = fopen(conf->bfile, "a"); } init_tabs(); if (conf->cfile != NULL) load_config(conf->cfile); donehup = 0; } switch (tr) { case -1 : if (ipmonopts & IPMON_SYSLOG) syslog(LOG_CRIT, "read: %m\n"); else { ipferror(l->fd, "read"); } return 0; case 1 : if (ipmonopts & IPMON_SYSLOG) syslog(LOG_CRIT, "aborting logging\n"); else if (conf->log != NULL) fprintf(conf->log, "aborting logging\n"); return 0; case 2 : break; case 0 : nr += tr; if (n > 0) { print_log(conf, l, (char *)buf, n); if (!(ipmonopts & IPMON_SYSLOG)) fflush(conf->log); } break; } } if (!nr && (ipmonopts & IPMON_TAIL)) sleep(1); return 1; } diff --git a/sbin/ipf/ipmon/ipmon_y.y b/sbin/ipf/ipmon/ipmon_y.y index 0aeb20a32519..d94bb1151af8 100644 --- a/sbin/ipf/ipmon/ipmon_y.y +++ b/sbin/ipf/ipmon/ipmon_y.y @@ -1,1052 +1,1038 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ %{ #include "ipf.h" #include #undef OPT_NAT #undef OPT_VERBOSE #include "ipmon_l.h" #include "ipmon.h" #include #define YYDEBUG 1 extern void yyerror(char *); extern int yyparse(void); extern int yylex(void); extern int yydebug; extern FILE *yyin; extern int yylineNum; extern int ipmonopts; typedef struct opt_s { struct opt_s *o_next; int o_line; int o_type; int o_num; char *o_str; struct in_addr o_ip; int o_logfac; int o_logpri; } opt_t; static void build_action(opt_t *, ipmon_doing_t *); static opt_t *new_opt(int); static void free_action(ipmon_action_t *); static void print_action(ipmon_action_t *); static int find_doing(char *); static ipmon_doing_t *build_doing(char *, char *); static void print_match(ipmon_action_t *); static int install_saver(char *, char *); static ipmon_action_t *alist = NULL; ipmon_saver_int_t *saverlist = NULL; %} %union { char *str; u_32_t num; struct in_addr addr; struct opt_s *opt; union i6addr ip6; struct ipmon_doing_s *ipmd; } %token YY_NUMBER YY_HEX %token YY_STR %token YY_IPV6 %token YY_COMMENT %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT %token YY_RANGE_OUT YY_RANGE_IN %token IPM_MATCH IPM_BODY IPM_COMMENT IPM_DIRECTION IPM_DSTIP IPM_DSTPORT %token IPM_EVERY IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT IPM_LOADACTION %token IPM_PACKET IPM_PACKETS IPM_POOL IPM_PROTOCOL IPM_RESULT IPM_RULE %token IPM_SECOND IPM_SECONDS IPM_SRCIP IPM_SRCPORT IPM_LOGTAG IPM_WITH %token IPM_DO IPM_DOING IPM_TYPE IPM_NAT %token IPM_STATE IPM_NATTAG IPM_IPF %type ipv4 %type direction dstip dstport every group interface %type protocol result rule srcip srcport logtag matching %type matchopt nattag type %type typeopt %type doopt doing %% file: action | file action ; action: line ';' | assign ';' | IPM_COMMENT | YY_COMMENT ; line: IPM_MATCH '{' matching ';' '}' IPM_DO '{' doing ';' '}' { build_action($3, $8); resetlexer(); } | IPM_LOADACTION YY_STR YY_STR { if (install_saver($2, $3)) yyerror("install saver"); } ; assign: YY_STR assigning YY_STR { set_variable($1, $3); resetlexer(); free($1); free($3); yyvarnext = 0; } ; assigning: '=' { yyvarnext = 1; } ; matching: matchopt { $$ = $1; } | matchopt ',' matching { $1->o_next = $3; $$ = $1; } ; matchopt: direction { $$ = $1; } | dstip { $$ = $1; } | dstport { $$ = $1; } | every { $$ = $1; } | group { $$ = $1; } | interface { $$ = $1; } | protocol { $$ = $1; } | result { $$ = $1; } | rule { $$ = $1; } | srcip { $$ = $1; } | srcport { $$ = $1; } | logtag { $$ = $1; } | nattag { $$ = $1; } | type { $$ = $1; } ; doing: doopt { $$ = $1; } | doopt ',' doing { $1->ipmd_next = $3; $$ = $1; } ; doopt: YY_STR { if (find_doing($1) != IPM_DOING) yyerror("unknown action"); } '(' YY_STR ')' { $$ = build_doing($1, $4); if ($$ == NULL) yyerror("action building"); } | YY_STR { if (find_doing($1) == IPM_DOING) $$ = build_doing($1, NULL); } ; direction: IPM_DIRECTION '=' IPM_IN { $$ = new_opt(IPM_DIRECTION); $$->o_num = IPM_IN; } | IPM_DIRECTION '=' IPM_OUT { $$ = new_opt(IPM_DIRECTION); $$->o_num = IPM_OUT; } ; dstip: IPM_DSTIP '=' ipv4 '/' YY_NUMBER { $$ = new_opt(IPM_DSTIP); $$->o_ip = $3; $$->o_num = $5; } ; dstport: IPM_DSTPORT '=' YY_NUMBER { $$ = new_opt(IPM_DSTPORT); $$->o_num = $3; } | IPM_DSTPORT '=' YY_STR { $$ = new_opt(IPM_DSTPORT); $$->o_str = $3; } ; every: IPM_EVERY IPM_SECOND { $$ = new_opt(IPM_SECOND); $$->o_num = 1; } | IPM_EVERY YY_NUMBER IPM_SECONDS { $$ = new_opt(IPM_SECOND); $$->o_num = $2; } | IPM_EVERY IPM_PACKET { $$ = new_opt(IPM_PACKET); $$->o_num = 1; } | IPM_EVERY YY_NUMBER IPM_PACKETS { $$ = new_opt(IPM_PACKET); $$->o_num = $2; } ; group: IPM_GROUP '=' YY_NUMBER { $$ = new_opt(IPM_GROUP); $$->o_num = $3; } | IPM_GROUP '=' YY_STR { $$ = new_opt(IPM_GROUP); $$->o_str = $3; } ; interface: IPM_INTERFACE '=' YY_STR { $$ = new_opt(IPM_INTERFACE); $$->o_str = $3; } ; logtag: IPM_LOGTAG '=' YY_NUMBER { $$ = new_opt(IPM_LOGTAG); $$->o_num = $3; } ; nattag: IPM_NATTAG '=' YY_STR { $$ = new_opt(IPM_NATTAG); $$->o_str = $3; } ; protocol: IPM_PROTOCOL '=' YY_NUMBER { $$ = new_opt(IPM_PROTOCOL); $$->o_num = $3; } | IPM_PROTOCOL '=' YY_STR { $$ = new_opt(IPM_PROTOCOL); $$->o_num = getproto($3); free($3); } ; result: IPM_RESULT '=' YY_STR { $$ = new_opt(IPM_RESULT); $$->o_str = $3; } ; rule: IPM_RULE '=' YY_NUMBER { $$ = new_opt(IPM_RULE); $$->o_num = YY_NUMBER; } ; srcip: IPM_SRCIP '=' ipv4 '/' YY_NUMBER { $$ = new_opt(IPM_SRCIP); $$->o_ip = $3; $$->o_num = $5; } ; srcport: IPM_SRCPORT '=' YY_NUMBER { $$ = new_opt(IPM_SRCPORT); $$->o_num = $3; } | IPM_SRCPORT '=' YY_STR { $$ = new_opt(IPM_SRCPORT); $$->o_str = $3; } ; type: IPM_TYPE '=' typeopt { $$ = new_opt(IPM_TYPE); $$->o_num = $3; } ; typeopt: IPM_IPF { $$ = IPL_MAGIC; } | IPM_NAT { $$ = IPL_MAGIC_NAT; } | IPM_STATE { $$ = IPL_MAGIC_STATE; } ; ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { yyerror("Invalid octet string for IP address"); return 0; } $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; $$.s_addr = htonl($$.s_addr); } %% static struct wordtab yywords[] = { { "body", IPM_BODY }, { "direction", IPM_DIRECTION }, { "do", IPM_DO }, { "dstip", IPM_DSTIP }, { "dstport", IPM_DSTPORT }, { "every", IPM_EVERY }, { "group", IPM_GROUP }, { "in", IPM_IN }, { "interface", IPM_INTERFACE }, { "ipf", IPM_IPF }, { "load_action",IPM_LOADACTION }, { "logtag", IPM_LOGTAG }, { "match", IPM_MATCH }, { "nat", IPM_NAT }, { "nattag", IPM_NATTAG }, { "no", IPM_NO }, { "out", IPM_OUT }, { "packet", IPM_PACKET }, { "packets", IPM_PACKETS }, { "protocol", IPM_PROTOCOL }, { "result", IPM_RESULT }, { "rule", IPM_RULE }, { "second", IPM_SECOND }, { "seconds", IPM_SECONDS }, { "srcip", IPM_SRCIP }, { "srcport", IPM_SRCPORT }, { "state", IPM_STATE }, { "with", IPM_WITH }, { NULL, 0 } }; static int macflags[17][2] = { { IPM_DIRECTION, IPMAC_DIRECTION }, { IPM_DSTIP, IPMAC_DSTIP }, { IPM_DSTPORT, IPMAC_DSTPORT }, { IPM_GROUP, IPMAC_GROUP }, { IPM_INTERFACE, IPMAC_INTERFACE }, { IPM_LOGTAG, IPMAC_LOGTAG }, { IPM_NATTAG, IPMAC_NATTAG }, { IPM_PACKET, IPMAC_EVERY }, { IPM_PROTOCOL, IPMAC_PROTOCOL }, { IPM_RESULT, IPMAC_RESULT }, { IPM_RULE, IPMAC_RULE }, { IPM_SECOND, IPMAC_EVERY }, { IPM_SRCIP, IPMAC_SRCIP }, { IPM_SRCPORT, IPMAC_SRCPORT }, { IPM_TYPE, IPMAC_TYPE }, { IPM_WITH, IPMAC_WITH }, { 0, 0 } }; static opt_t * -new_opt(type) - int type; +new_opt(int type) { opt_t *o; o = (opt_t *)calloc(1, sizeof(*o)); o->o_type = type; o->o_line = yylineNum; o->o_logfac = -1; o->o_logpri = -1; return o; } static void -build_action(olist, todo) - opt_t *olist; - ipmon_doing_t *todo; +build_action(opt_t *olist, ipmon_doing_t *todo) { ipmon_action_t *a; opt_t *o; int i; a = (ipmon_action_t *)calloc(1, sizeof(*a)); if (a == NULL) return; while ((o = olist) != NULL) { /* * Check to see if the same comparator is being used more than * once per matching statement. */ for (i = 0; macflags[i][0]; i++) if (macflags[i][0] == o->o_type) break; if (macflags[i][1] & a->ac_mflag) { fprintf(stderr, "%s redfined on line %d\n", yykeytostr(o->o_type), yylineNum); if (o->o_str != NULL) free(o->o_str); olist = o->o_next; free(o); continue; } a->ac_mflag |= macflags[i][1]; switch (o->o_type) { case IPM_DIRECTION : a->ac_direction = o->o_num; break; case IPM_DSTIP : a->ac_dip = o->o_ip.s_addr; a->ac_dmsk = htonl(0xffffffff << (32 - o->o_num)); break; case IPM_DSTPORT : a->ac_dport = htons(o->o_num); break; case IPM_INTERFACE : a->ac_iface = o->o_str; o->o_str = NULL; break; case IPM_GROUP : if (o->o_str != NULL) strncpy(a->ac_group, o->o_str, FR_GROUPLEN); else sprintf(a->ac_group, "%d", o->o_num); break; case IPM_LOGTAG : a->ac_logtag = o->o_num; break; case IPM_NATTAG : strncpy(a->ac_nattag, o->o_str, sizeof(a->ac_nattag)); break; case IPM_PACKET : a->ac_packet = o->o_num; break; case IPM_PROTOCOL : a->ac_proto = o->o_num; break; case IPM_RULE : a->ac_rule = o->o_num; break; case IPM_RESULT : if (!strcasecmp(o->o_str, "pass")) a->ac_result = IPMR_PASS; else if (!strcasecmp(o->o_str, "block")) a->ac_result = IPMR_BLOCK; else if (!strcasecmp(o->o_str, "nomatch")) a->ac_result = IPMR_NOMATCH; else if (!strcasecmp(o->o_str, "log")) a->ac_result = IPMR_LOG; break; case IPM_SECOND : a->ac_second = o->o_num; break; case IPM_SRCIP : a->ac_sip = o->o_ip.s_addr; a->ac_smsk = htonl(0xffffffff << (32 - o->o_num)); break; case IPM_SRCPORT : a->ac_sport = htons(o->o_num); break; case IPM_TYPE : a->ac_type = o->o_num; break; case IPM_WITH : break; default : break; } olist = o->o_next; if (o->o_str != NULL) free(o->o_str); free(o); } a->ac_doing = todo; a->ac_next = alist; alist = a; if (ipmonopts & IPMON_VERBOSE) print_action(a); } int -check_action(buf, log, opts, lvl) - char *buf, *log; - int opts, lvl; +check_action(char *buf, char *log, int opts, int lvl) { ipmon_action_t *a; struct timeval tv; ipmon_doing_t *d; ipmon_msg_t msg; ipflog_t *ipf; tcphdr_t *tcp; iplog_t *ipl; int matched; u_long t1; ip_t *ip; matched = 0; ipl = (iplog_t *)buf; ipf = (ipflog_t *)(ipl +1); ip = (ip_t *)(ipf + 1); tcp = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2)); msg.imm_data = ipl; msg.imm_dsize = ipl->ipl_dsize; msg.imm_when = ipl->ipl_time.tv_sec; msg.imm_msg = log; msg.imm_msglen = strlen(log); msg.imm_loglevel = lvl; for (a = alist; a != NULL; a = a->ac_next) { verbose(0, "== checking config rule\n"); if ((a->ac_mflag & IPMAC_DIRECTION) != 0) { if (a->ac_direction == IPM_IN) { if ((ipf->fl_flags & FR_INQUE) == 0) { verbose(8, "-- direction not in\n"); continue; } } else if (a->ac_direction == IPM_OUT) { if ((ipf->fl_flags & FR_OUTQUE) == 0) { verbose(8, "-- direction not out\n"); continue; } } } if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic)) { verbose(8, "-- type mismatch\n"); continue; } if ((a->ac_mflag & IPMAC_EVERY) != 0) { gettimeofday(&tv, NULL); t1 = tv.tv_sec - a->ac_lastsec; if (tv.tv_usec <= a->ac_lastusec) t1--; if (a->ac_second != 0) { if (t1 < a->ac_second) { verbose(8, "-- too soon\n"); continue; } a->ac_lastsec = tv.tv_sec; a->ac_lastusec = tv.tv_usec; } if (a->ac_packet != 0) { if (a->ac_pktcnt == 0) a->ac_pktcnt++; else if (a->ac_pktcnt == a->ac_packet) { a->ac_pktcnt = 0; verbose(8, "-- packet count\n"); continue; } else { a->ac_pktcnt++; verbose(8, "-- packet count\n"); continue; } } } if ((a->ac_mflag & IPMAC_DSTIP) != 0) { if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip) { verbose(8, "-- dstip wrong\n"); continue; } } if ((a->ac_mflag & IPMAC_DSTPORT) != 0) { if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP) { verbose(8, "-- not port protocol\n"); continue; } if (tcp->th_dport != a->ac_dport) { verbose(8, "-- dport mismatch\n"); continue; } } if ((a->ac_mflag & IPMAC_GROUP) != 0) { if (strncmp(a->ac_group, ipf->fl_group, FR_GROUPLEN) != 0) { verbose(8, "-- group mismatch\n"); continue; } } if ((a->ac_mflag & IPMAC_INTERFACE) != 0) { if (strcmp(a->ac_iface, ipf->fl_ifname)) { verbose(8, "-- ifname mismatch\n"); continue; } } if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) { if (a->ac_proto != ip->ip_p) { verbose(8, "-- protocol mismatch\n"); continue; } } if ((a->ac_mflag & IPMAC_RESULT) != 0) { if ((ipf->fl_flags & FF_LOGNOMATCH) != 0) { if (a->ac_result != IPMR_NOMATCH) { verbose(8, "-- ff-flags mismatch\n"); continue; } } else if (FR_ISPASS(ipf->fl_flags)) { if (a->ac_result != IPMR_PASS) { verbose(8, "-- pass mismatch\n"); continue; } } else if (FR_ISBLOCK(ipf->fl_flags)) { if (a->ac_result != IPMR_BLOCK) { verbose(8, "-- block mismatch\n"); continue; } } else { /* Log only */ if (a->ac_result != IPMR_LOG) { verbose(8, "-- log mismatch\n"); continue; } } } if ((a->ac_mflag & IPMAC_RULE) != 0) { if (a->ac_rule != ipf->fl_rule) { verbose(8, "-- rule mismatch\n"); continue; } } if ((a->ac_mflag & IPMAC_SRCIP) != 0) { if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip) { verbose(8, "-- srcip mismatch\n"); continue; } } if ((a->ac_mflag & IPMAC_SRCPORT) != 0) { if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP) { verbose(8, "-- port protocol mismatch\n"); continue; } if (tcp->th_sport != a->ac_sport) { verbose(8, "-- sport mismatch\n"); continue; } } if ((a->ac_mflag & IPMAC_LOGTAG) != 0) { if (a->ac_logtag != ipf->fl_logtag) { verbose(8, "-- logtag %d != %d\n", a->ac_logtag, ipf->fl_logtag); continue; } } if ((a->ac_mflag & IPMAC_NATTAG) != 0) { if (strncmp(a->ac_nattag, ipf->fl_nattag.ipt_tag, IPFTAG_LEN) != 0) { verbose(8, "-- nattag mismatch\n"); continue; } } matched = 1; verbose(8, "++ matched\n"); /* * It matched so now perform the saves */ for (d = a->ac_doing; d != NULL; d = d->ipmd_next) (*d->ipmd_store)(d->ipmd_token, &msg); } return matched; } static void -free_action(a) - ipmon_action_t *a; +free_action(ipmon_action_t *a) { ipmon_doing_t *d; while ((d = a->ac_doing) != NULL) { a->ac_doing = d->ipmd_next; (*d->ipmd_saver->ims_destroy)(d->ipmd_token); free(d); } if (a->ac_iface != NULL) { free(a->ac_iface); a->ac_iface = NULL; } a->ac_next = NULL; free(a); } int -load_config(file) - char *file; +load_config(char *file) { FILE *fp; char *s; unload_config(); s = getenv("YYDEBUG"); if (s != NULL) yydebug = atoi(s); else yydebug = 0; yylineNum = 1; (void) yysettab(yywords); fp = fopen(file, "r"); if (!fp) { perror("load_config:fopen:"); return -1; } yyin = fp; while (!feof(fp)) yyparse(); fclose(fp); return 0; } void -unload_config() +unload_config(void) { ipmon_saver_int_t *sav, **imsip; ipmon_saver_t *is; ipmon_action_t *a; while ((a = alist) != NULL) { alist = a->ac_next; free_action(a); } /* * Look for savers that have been added in dynamically from the * configuration file. */ for (imsip = &saverlist; (sav = *imsip) != NULL; ) { if (sav->imsi_handle == NULL) imsip = &sav->imsi_next; else { dlclose(sav->imsi_handle); *imsip = sav->imsi_next; is = sav->imsi_stor; free(sav); free(is->ims_name); free(is); } } } void -dump_config() +dump_config(void) { ipmon_action_t *a; for (a = alist; a != NULL; a = a->ac_next) { print_action(a); printf("#\n"); } } static void -print_action(a) - ipmon_action_t *a; +print_action(ipmon_action_t *a) { ipmon_doing_t *d; printf("match { "); print_match(a); printf("; }\n"); printf("do {"); for (d = a->ac_doing; d != NULL; d = d->ipmd_next) { printf("%s", d->ipmd_saver->ims_name); if (d->ipmd_saver->ims_print != NULL) { printf("(\""); (*d->ipmd_saver->ims_print)(d->ipmd_token); printf("\")"); } printf(";"); } printf("};\n"); } void * -add_doing(saver) - ipmon_saver_t *saver; +add_doing(ipmon_saver_t *saver) { ipmon_saver_int_t *it; if (find_doing(saver->ims_name) == IPM_DOING) return NULL; it = calloc(1, sizeof(*it)); if (it == NULL) return NULL; it->imsi_stor = saver; it->imsi_next = saverlist; saverlist = it; return it; } static int -find_doing(string) - char *string; +find_doing(char *string) { ipmon_saver_int_t *it; for (it = saverlist; it != NULL; it = it->imsi_next) { if (!strcmp(it->imsi_stor->ims_name, string)) return IPM_DOING; } return 0; } static ipmon_doing_t * -build_doing(target, options) - char *target; - char *options; +build_doing(char *target, char *options) { ipmon_saver_int_t *it; char *strarray[2]; ipmon_doing_t *d, *d1; ipmon_action_t *a; ipmon_saver_t *save; d = calloc(1, sizeof(*d)); if (d == NULL) return NULL; for (it = saverlist; it != NULL; it = it->imsi_next) { if (!strcmp(it->imsi_stor->ims_name, target)) break; } if (it == NULL) { free(d); return NULL; } strarray[0] = options; strarray[1] = NULL; d->ipmd_token = (*it->imsi_stor->ims_parse)(strarray); if (d->ipmd_token == NULL) { free(d); return NULL; } save = it->imsi_stor; d->ipmd_saver = save; d->ipmd_store = it->imsi_stor->ims_store; /* * Look for duplicate do-things that need to be dup'd */ for (a = alist; a != NULL; a = a->ac_next) { for (d1 = a->ac_doing; d1 != NULL; d1 = d1->ipmd_next) { if (save != d1->ipmd_saver) continue; if (save->ims_match == NULL || save->ims_dup == NULL) continue; if ((*save->ims_match)(d->ipmd_token, d1->ipmd_token)) continue; (*d->ipmd_saver->ims_destroy)(d->ipmd_token); d->ipmd_token = (*save->ims_dup)(d1->ipmd_token); break; } } return d; } static void -print_match(a) - ipmon_action_t *a; +print_match(ipmon_action_t *a) { char *coma = ""; if ((a->ac_mflag & IPMAC_DIRECTION) != 0) { printf("direction = "); if (a->ac_direction == IPM_IN) printf("in"); else if (a->ac_direction == IPM_OUT) printf("out"); coma = ", "; } if ((a->ac_mflag & IPMAC_DSTIP) != 0) { printf("%sdstip = ", coma); printhostmask(AF_INET, &a->ac_dip, &a->ac_dmsk); coma = ", "; } if ((a->ac_mflag & IPMAC_DSTPORT) != 0) { printf("%sdstport = %hu", coma, ntohs(a->ac_dport)); coma = ", "; } if ((a->ac_mflag & IPMAC_GROUP) != 0) { char group[FR_GROUPLEN+1]; strncpy(group, a->ac_group, FR_GROUPLEN); group[FR_GROUPLEN] = '\0'; printf("%sgroup = %s", coma, group); coma = ", "; } if ((a->ac_mflag & IPMAC_INTERFACE) != 0) { printf("%siface = %s", coma, a->ac_iface); coma = ", "; } if ((a->ac_mflag & IPMAC_LOGTAG) != 0) { printf("%slogtag = %u", coma, a->ac_logtag); coma = ", "; } if ((a->ac_mflag & IPMAC_NATTAG) != 0) { char tag[17]; strncpy(tag, a->ac_nattag, 16); tag[16] = '\0'; printf("%snattag = %s", coma, tag); coma = ", "; } if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) { printf("%sprotocol = %u", coma, a->ac_proto); coma = ", "; } if ((a->ac_mflag & IPMAC_RESULT) != 0) { printf("%sresult = ", coma); switch (a->ac_result) { case IPMR_LOG : printf("log"); break; case IPMR_PASS : printf("pass"); break; case IPMR_BLOCK : printf("block"); break; case IPMR_NOMATCH : printf("nomatch"); break; } coma = ", "; } if ((a->ac_mflag & IPMAC_RULE) != 0) { printf("%srule = %u", coma, a->ac_rule); coma = ", "; } if ((a->ac_mflag & IPMAC_EVERY) != 0) { if (a->ac_packet > 1) { printf("%severy %d packets", coma, a->ac_packet); coma = ", "; } else if (a->ac_packet == 1) { printf("%severy packet", coma); coma = ", "; } if (a->ac_second > 1) { printf("%severy %d seconds", coma, a->ac_second); coma = ", "; } else if (a->ac_second == 1) { printf("%severy second", coma); coma = ", "; } } if ((a->ac_mflag & IPMAC_SRCIP) != 0) { printf("%ssrcip = ", coma); printhostmask(AF_INET, &a->ac_sip, &a->ac_smsk); coma = ", "; } if ((a->ac_mflag & IPMAC_SRCPORT) != 0) { printf("%ssrcport = %hu", coma, ntohs(a->ac_sport)); coma = ", "; } if ((a->ac_mflag & IPMAC_TYPE) != 0) { printf("%stype = ", coma); switch (a->ac_type) { case IPL_LOGIPF : printf("ipf"); break; case IPL_LOGSTATE : printf("state"); break; case IPL_LOGNAT : printf("nat"); break; } coma = ", "; } if ((a->ac_mflag & IPMAC_WITH) != 0) { printf("%swith ", coma); coma = ", "; } } static int -install_saver(name, path) - char *name, *path; +install_saver(char *name, char *path) { ipmon_saver_int_t *isi; ipmon_saver_t *is; char nbuf[80]; if (find_doing(name) == IPM_DOING) return -1; isi = calloc(1, sizeof(*isi)); if (isi == NULL) return -1; is = calloc(1, sizeof(*is)); if (is == NULL) goto loaderror; is->ims_name = name; #ifdef RTLD_LAZY isi->imsi_handle = dlopen(path, RTLD_LAZY); #endif #ifdef DL_LAZY isi->imsi_handle = dlopen(path, DL_LAZY); #endif if (isi->imsi_handle == NULL) goto loaderror; snprintf(nbuf, sizeof(nbuf), "%sdup", name); is->ims_dup = (ims_dup_func_t)dlsym(isi->imsi_handle, nbuf); snprintf(nbuf, sizeof(nbuf), "%sdestroy", name); is->ims_destroy = (ims_destroy_func_t)dlsym(isi->imsi_handle, nbuf); if (is->ims_destroy == NULL) goto loaderror; snprintf(nbuf, sizeof(nbuf), "%smatch", name); is->ims_match = (ims_match_func_t)dlsym(isi->imsi_handle, nbuf); snprintf(nbuf, sizeof(nbuf), "%sparse", name); is->ims_parse = (ims_parse_func_t)dlsym(isi->imsi_handle, nbuf); if (is->ims_parse == NULL) goto loaderror; snprintf(nbuf, sizeof(nbuf), "%sprint", name); is->ims_print = (ims_print_func_t)dlsym(isi->imsi_handle, nbuf); if (is->ims_print == NULL) goto loaderror; snprintf(nbuf, sizeof(nbuf), "%sstore", name); is->ims_store = (ims_store_func_t)dlsym(isi->imsi_handle, nbuf); if (is->ims_store == NULL) goto loaderror; isi->imsi_stor = is; isi->imsi_next = saverlist; saverlist = isi; return 0; loaderror: if (isi->imsi_handle != NULL) dlclose(isi->imsi_handle); free(isi); if (is != NULL) free(is); return -1; } diff --git a/sbin/ipf/ipnat/ipnat.c b/sbin/ipf/ipnat/ipnat.c index 1ca6e776ffdf..54c770e1db26 100644 --- a/sbin/ipf/ipnat/ipnat.c +++ b/sbin/ipf/ipnat/ipnat.c @@ -1,842 +1,833 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) */ #include #include #include #include #include #if !defined(__SVR4) #include #else #include #endif #include #include #include #include #include #include #define _KERNEL #include #undef _KERNEL #include #include #if defined(sun) && defined(__SVR4) # include # include #endif #include #include #include #include #include #include #include #include #include #include # include #include "ipf.h" #include "netinet/ipl.h" #include "kmem.h" # define STRERROR(x) strerror(x) #if !defined(lint) static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #if SOLARIS #define bzero(a,b) memset(a,0,b) #endif int use_inet6 = 0; extern char *optarg; void dostats(int, natstat_t *, int, int, int *); void dotable(natstat_t *, int, int, int, char *); void flushtable(int, int, int *); void usage(char *); int main(int, char*[]); void showhostmap(natstat_t *nsp); void natstat_dead(natstat_t *, char *); void dostats_live(int, natstat_t *, int, int *); void showhostmap_dead(natstat_t *); void showhostmap_live(int, natstat_t *); void dostats_dead(natstat_t *, int, int *); int nat_matcharray(nat_t *, int *); int opts; int nohdrfields = 0; wordtab_t *nat_fields = NULL; -void usage(name) - char *name; +void +usage(char *name) { fprintf(stderr, "Usage: %s [-CFhlnrRsv] [-f filename]\n", name); exit(1); } -int main(argc, argv) - int argc; - char *argv[]; +int +main(int argc, char *argv[]) { int fd, c, mode, *natfilter; char *file, *core, *kernel; natstat_t ns, *nsp; ipfobj_t obj; fd = -1; opts = 0; nsp = &ns; file = NULL; core = NULL; kernel = NULL; mode = O_RDWR; natfilter = NULL; assigndefined(getenv("IPNAT_PREDEFINED")); while ((c = getopt(argc, argv, "CdFf:hlm:M:N:nO:prRsv")) != -1) switch (c) { case 'C' : opts |= OPT_CLEAR; break; case 'd' : opts |= OPT_DEBUG; break; case 'f' : file = optarg; break; case 'F' : opts |= OPT_FLUSH; break; case 'h' : opts |=OPT_HITS; break; case 'l' : opts |= OPT_LIST; mode = O_RDONLY; break; case 'm' : natfilter = parseipfexpr(optarg, NULL); break; case 'M' : core = optarg; break; case 'N' : kernel = optarg; break; case 'n' : opts |= OPT_DONOTHING|OPT_DONTOPEN; mode = O_RDONLY; break; case 'O' : nat_fields = parsefields(natfields, optarg); break; case 'p' : opts |= OPT_PURGE; break; case 'R' : opts |= OPT_NORESOLVE; break; case 'r' : opts |= OPT_REMOVE; break; case 's' : opts |= OPT_STAT; mode = O_RDONLY; break; case 'v' : opts |= OPT_VERBOSE; break; default : usage(argv[0]); } if (((opts & OPT_PURGE) != 0) && ((opts & OPT_REMOVE) == 0)) { (void) fprintf(stderr, "%s: -p must be used with -r\n", argv[0]); exit(1); } initparse(); if ((kernel != NULL) || (core != NULL)) { (void) setgid(getgid()); (void) setuid(getuid()); } if (!(opts & OPT_DONOTHING)) { if (((fd = open(IPNAT_NAME, mode)) == -1) && ((fd = open(IPNAT_NAME, O_RDONLY)) == -1)) { (void) fprintf(stderr, "%s: open: %s\n", IPNAT_NAME, STRERROR(errno)); exit(1); } } bzero((char *)&ns, sizeof(ns)); if ((opts & OPT_DONOTHING) == 0) { if (checkrev(IPL_NAME) == -1) { fprintf(stderr, "User/kernel version check failed\n"); exit(1); } } if (!(opts & OPT_DONOTHING) && (kernel == NULL) && (core == NULL)) { bzero((char *)&obj, sizeof(obj)); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_NATSTAT; obj.ipfo_size = sizeof(*nsp); obj.ipfo_ptr = (void *)nsp; if (ioctl(fd, SIOCGNATS, &obj) == -1) { ipferror(fd, "ioctl(SIOCGNATS)"); exit(1); } (void) setgid(getgid()); (void) setuid(getuid()); } else if ((kernel != NULL) || (core != NULL)) { if (openkmem(kernel, core) == -1) exit(1); natstat_dead(nsp, kernel); if (opts & (OPT_LIST|OPT_STAT)) dostats(fd, nsp, opts, 0, natfilter); exit(0); } if (opts & (OPT_FLUSH|OPT_CLEAR)) flushtable(fd, opts, natfilter); if (file) { return ipnat_parsefile(fd, ipnat_addrule, ioctl, file); } if (opts & (OPT_LIST|OPT_STAT)) dostats(fd, nsp, opts, 1, natfilter); return 0; } /* * Read NAT statistic information in using a symbol table and memory file * rather than doing ioctl's. */ -void natstat_dead(nsp, kernel) - natstat_t *nsp; - char *kernel; +void +natstat_dead(natstat_t *nsp, char *kernel) { struct nlist nat_nlist[10] = { { "nat_table" }, /* 0 */ { "nat_list" }, { "maptable" }, { "ipf_nattable_sz" }, { "ipf_natrules_sz" }, { "ipf_rdrrules_sz" }, /* 5 */ { "ipf_hostmap_sz" }, { "nat_instances" }, { NULL } }; void *tables[2]; if (nlist(kernel, nat_nlist) == -1) { fprintf(stderr, "nlist error\n"); return; } /* * Normally the ioctl copies all of these values into the structure * for us, before returning it to userland, so here we must copy each * one in individually. */ kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables)); nsp->ns_side[0].ns_table = tables[0]; nsp->ns_side[1].ns_table = tables[1]; kmemcpy((char *)&nsp->ns_list, nat_nlist[1].n_value, sizeof(nsp->ns_list)); kmemcpy((char *)&nsp->ns_maptable, nat_nlist[2].n_value, sizeof(nsp->ns_maptable)); kmemcpy((char *)&nsp->ns_nattab_sz, nat_nlist[3].n_value, sizeof(nsp->ns_nattab_sz)); kmemcpy((char *)&nsp->ns_rultab_sz, nat_nlist[4].n_value, sizeof(nsp->ns_rultab_sz)); kmemcpy((char *)&nsp->ns_rdrtab_sz, nat_nlist[5].n_value, sizeof(nsp->ns_rdrtab_sz)); kmemcpy((char *)&nsp->ns_hostmap_sz, nat_nlist[6].n_value, sizeof(nsp->ns_hostmap_sz)); kmemcpy((char *)&nsp->ns_instances, nat_nlist[7].n_value, sizeof(nsp->ns_instances)); } /* * Issue an ioctl to flush either the NAT rules table or the active mapping * table or both. */ -void flushtable(fd, opts, match) - int fd, opts, *match; +void +flushtable(int fd, int opts, int *match) { int n = 0; if (opts & OPT_FLUSH) { n = 0; if (!(opts & OPT_DONOTHING)) { if (match != NULL) { ipfobj_t obj; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_size = match[0] * sizeof(int); obj.ipfo_type = IPFOBJ_IPFEXPR; obj.ipfo_ptr = match; if (ioctl(fd, SIOCMATCHFLUSH, &obj) == -1) { ipferror(fd, "ioctl(SIOCMATCHFLUSH)"); n = -1; } else { n = obj.ipfo_retval; } } else if (ioctl(fd, SIOCIPFFL, &n) == -1) { ipferror(fd, "ioctl(SIOCIPFFL)"); n = -1; } } if (n >= 0) printf("%d entries flushed from NAT table\n", n); } if (opts & OPT_CLEAR) { n = 1; if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1) ipferror(fd, "ioctl(SIOCCNATL)"); else printf("%d entries flushed from NAT list\n", n); } } /* * Display NAT statistics. */ -void dostats_dead(nsp, opts, filter) - natstat_t *nsp; - int opts, *filter; +void +dostats_dead(natstat_t *nsp, int opts, int *filter) { nat_t *np, nat; ipnat_t ipn; int i; if (nat_fields == NULL) { printf("List of active MAP/Redirect filters:\n"); while (nsp->ns_list) { if (kmemcpy((char *)&ipn, (long)nsp->ns_list, sizeof(ipn))) { perror("kmemcpy"); break; } if (opts & OPT_HITS) printf("%lu ", ipn.in_hits); printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); nsp->ns_list = ipn.in_next; } } if (nat_fields == NULL) { printf("\nList of active sessions:\n"); } else if (nohdrfields == 0) { for (i = 0; nat_fields[i].w_value != 0; i++) { printfieldhdr(natfields, nat_fields + i); if (nat_fields[i + 1].w_value != 0) printf("\t"); } printf("\n"); } for (np = nsp->ns_instances; np; np = nat.nat_next) { if (kmemcpy((char *)&nat, (long)np, sizeof(nat))) break; if ((filter != NULL) && (nat_matcharray(&nat, filter) == 0)) continue; if (nat_fields != NULL) { for (i = 0; nat_fields[i].w_value != 0; i++) { printnatfield(&nat, nat_fields[i].w_value); if (nat_fields[i + 1].w_value != 0) printf("\t"); } printf("\n"); } else { printactivenat(&nat, opts, nsp->ns_ticks); if (nat.nat_aps) { int proto; if (nat.nat_dir & NAT_OUTBOUND) proto = nat.nat_pr[1]; else proto = nat.nat_pr[0]; printaps(nat.nat_aps, opts, proto); } } } if (opts & OPT_VERBOSE) showhostmap_dead(nsp); } -void dotable(nsp, fd, alive, which, side) - natstat_t *nsp; - int fd, alive, which; - char *side; +void +dotable(natstat_t *nsp, int fd, int alive, int which, char *side) { int sz, i, used, maxlen, minlen, totallen; ipftable_t table; u_int *buckets; ipfobj_t obj; sz = sizeof(*buckets) * nsp->ns_nattab_sz; buckets = (u_int *)malloc(sz); if (buckets == NULL) { fprintf(stderr, "cannot allocate memory (%d) for buckets\n", sz); return; } obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_GTABLE; obj.ipfo_size = sizeof(table); obj.ipfo_ptr = &table; if (which == 0) { table.ita_type = IPFTABLE_BUCKETS_NATIN; } else if (which == 1) { table.ita_type = IPFTABLE_BUCKETS_NATOUT; } table.ita_table = buckets; if (alive) { if (ioctl(fd, SIOCGTABL, &obj) != 0) { ipferror(fd, "SIOCFTABL"); free(buckets); return; } } else { if (kmemcpy((char *)buckets, (u_long)nsp->ns_nattab_sz, sz)) { free(buckets); return; } } minlen = nsp->ns_side[which].ns_inuse; totallen = 0; maxlen = 0; used = 0; for (i = 0; i < nsp->ns_nattab_sz; i++) { if (buckets[i] > maxlen) maxlen = buckets[i]; if (buckets[i] < minlen) minlen = buckets[i]; if (buckets[i] != 0) used++; totallen += buckets[i]; } printf("%d%%\thash efficiency %s\n", totallen ? used * 100 / totallen : 0, side); printf("%2.2f%%\tbucket usage %s\n", ((float)used / nsp->ns_nattab_sz) * 100.0, side); printf("%d\tminimal length %s\n", minlen, side); printf("%d\tmaximal length %s\n", maxlen, side); printf("%.3f\taverage length %s\n", used ? ((float)totallen / used) : 0.0, side); free(buckets); } -void dostats(fd, nsp, opts, alive, filter) - natstat_t *nsp; - int fd, opts, alive, *filter; +void +dostats(int fd, natstat_t *nsp, int opts, int alive, int *filter) { /* * Show statistics ? */ if (opts & OPT_STAT) { printnatside("in", &nsp->ns_side[0]); dotable(nsp, fd, alive, 0, "in"); printnatside("out", &nsp->ns_side[1]); dotable(nsp, fd, alive, 1, "out"); printf("%lu\tlog successes\n", nsp->ns_side[0].ns_log); printf("%lu\tlog failures\n", nsp->ns_side[1].ns_log); printf("%lu\tadded in\n%lu\tadded out\n", nsp->ns_side[0].ns_added, nsp->ns_side[1].ns_added); printf("%u\tactive\n", nsp->ns_active); printf("%lu\ttransparent adds\n", nsp->ns_addtrpnt); printf("%lu\tdivert build\n", nsp->ns_divert_build); printf("%lu\texpired\n", nsp->ns_expire); printf("%lu\tflush all\n", nsp->ns_flush_all); printf("%lu\tflush closing\n", nsp->ns_flush_closing); printf("%lu\tflush queue\n", nsp->ns_flush_queue); printf("%lu\tflush state\n", nsp->ns_flush_state); printf("%lu\tflush timeout\n", nsp->ns_flush_timeout); printf("%lu\thostmap new\n", nsp->ns_hm_new); printf("%lu\thostmap fails\n", nsp->ns_hm_newfail); printf("%lu\thostmap add\n", nsp->ns_hm_addref); printf("%lu\thostmap NULL rule\n", nsp->ns_hm_nullnp); printf("%lu\tlog ok\n", nsp->ns_log_ok); printf("%lu\tlog fail\n", nsp->ns_log_fail); printf("%u\torphan count\n", nsp->ns_orphans); printf("%u\trule count\n", nsp->ns_rules); printf("%u\tmap rules\n", nsp->ns_rules_map); printf("%u\trdr rules\n", nsp->ns_rules_rdr); printf("%u\twilds\n", nsp->ns_wilds); if (opts & OPT_VERBOSE) printf("list %p\n", nsp->ns_list); } if (opts & OPT_LIST) { if (alive) dostats_live(fd, nsp, opts, filter); else dostats_dead(nsp, opts, filter); } } /* * Display NAT statistics. */ -void dostats_live(fd, nsp, opts, filter) - natstat_t *nsp; - int fd, opts, *filter; +void +dostats_live(int fd, natstat_t *nsp, int opts, int *filter) { ipfgeniter_t iter; char buffer[2000]; ipfobj_t obj; ipnat_t *ipn; nat_t nat; int i; bzero((char *)&obj, sizeof(obj)); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_GENITER; obj.ipfo_size = sizeof(iter); obj.ipfo_ptr = &iter; iter.igi_type = IPFGENITER_IPNAT; iter.igi_nitems = 1; iter.igi_data = buffer; ipn = (ipnat_t *)buffer; /* * Show list of NAT rules and NAT sessions ? */ if (nat_fields == NULL) { printf("List of active MAP/Redirect filters:\n"); while (nsp->ns_list) { if (ioctl(fd, SIOCGENITER, &obj) == -1) break; if (opts & OPT_HITS) printf("%lu ", ipn->in_hits); printnat(ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); nsp->ns_list = ipn->in_next; } } if (nat_fields == NULL) { printf("\nList of active sessions:\n"); } else if (nohdrfields == 0) { for (i = 0; nat_fields[i].w_value != 0; i++) { printfieldhdr(natfields, nat_fields + i); if (nat_fields[i + 1].w_value != 0) printf("\t"); } printf("\n"); } i = IPFGENITER_IPNAT; (void) ioctl(fd,SIOCIPFDELTOK, &i); iter.igi_type = IPFGENITER_NAT; iter.igi_nitems = 1; iter.igi_data = &nat; while (nsp->ns_instances != NULL) { if (ioctl(fd, SIOCGENITER, &obj) == -1) break; if ((filter != NULL) && (nat_matcharray(&nat, filter) == 0)) continue; if (nat_fields != NULL) { for (i = 0; nat_fields[i].w_value != 0; i++) { printnatfield(&nat, nat_fields[i].w_value); if (nat_fields[i + 1].w_value != 0) printf("\t"); } printf("\n"); } else { printactivenat(&nat, opts, nsp->ns_ticks); if (nat.nat_aps) { int proto; if (nat.nat_dir & NAT_OUTBOUND) proto = nat.nat_pr[1]; else proto = nat.nat_pr[0]; printaps(nat.nat_aps, opts, proto); } } nsp->ns_instances = nat.nat_next; } if (opts & OPT_VERBOSE) showhostmap_live(fd, nsp); i = IPFGENITER_NAT; (void) ioctl(fd,SIOCIPFDELTOK, &i); } /* * Display the active host mapping table. */ -void showhostmap_dead(nsp) - natstat_t *nsp; +void +showhostmap_dead(natstat_t *nsp) { hostmap_t hm, *hmp, **maptable; u_int hv; printf("\nList of active host mappings:\n"); maptable = (hostmap_t **)malloc(sizeof(hostmap_t *) * nsp->ns_hostmap_sz); if (kmemcpy((char *)maptable, (u_long)nsp->ns_maptable, sizeof(hostmap_t *) * nsp->ns_hostmap_sz)) { perror("kmemcpy (maptable)"); return; } for (hv = 0; hv < nsp->ns_hostmap_sz; hv++) { hmp = maptable[hv]; while (hmp) { if (kmemcpy((char *)&hm, (u_long)hmp, sizeof(hm))) { perror("kmemcpy (hostmap)"); return; } printhostmap(&hm, hv); hmp = hm.hm_next; } } free(maptable); } /* * Display the active host mapping table. */ -void showhostmap_live(fd, nsp) - int fd; - natstat_t *nsp; +void +showhostmap_live(int fd, natstat_t *nsp) { ipfgeniter_t iter; hostmap_t hm; ipfobj_t obj; int i; bzero((char *)&obj, sizeof(obj)); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_GENITER; obj.ipfo_size = sizeof(iter); obj.ipfo_ptr = &iter; iter.igi_type = IPFGENITER_HOSTMAP; iter.igi_nitems = 1; iter.igi_data = &hm; printf("\nList of active host mappings:\n"); while (nsp->ns_maplist != NULL) { if (ioctl(fd, SIOCGENITER, &obj) == -1) break; printhostmap(&hm, hm.hm_hv); nsp->ns_maplist = hm.hm_next; } i = IPFGENITER_HOSTMAP; (void) ioctl(fd,SIOCIPFDELTOK, &i); } -int nat_matcharray(nat, array) - nat_t *nat; - int *array; +int +nat_matcharray(nat_t *nat, int *array) { int i, n, *x, rv, p; ipfexp_t *e; rv = 0; n = array[0]; x = array + 1; for (; n > 0; x += 3 + x[3], rv = 0) { e = (ipfexp_t *)x; if (e->ipfe_cmd == IPF_EXP_END) break; n -= e->ipfe_size; p = e->ipfe_cmd >> 16; if ((p != 0) && (p != nat->nat_pr[1])) break; switch (e->ipfe_cmd) { case IPF_EXP_IP_PR : for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= (nat->nat_pr[1] == e->ipfe_arg0[i]); } break; case IPF_EXP_IP_SRCADDR : if (nat->nat_v[0] != 4) break; for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= ((nat->nat_osrcaddr & e->ipfe_arg0[i * 2 + 1]) == e->ipfe_arg0[i * 2]) || ((nat->nat_nsrcaddr & e->ipfe_arg0[i * 2 + 1]) == e->ipfe_arg0[i * 2]); } break; case IPF_EXP_IP_DSTADDR : if (nat->nat_v[0] != 4) break; for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= ((nat->nat_odstaddr & e->ipfe_arg0[i * 2 + 1]) == e->ipfe_arg0[i * 2]) || ((nat->nat_ndstaddr & e->ipfe_arg0[i * 2 + 1]) == e->ipfe_arg0[i * 2]); } break; case IPF_EXP_IP_ADDR : if (nat->nat_v[0] != 4) break; for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= ((nat->nat_osrcaddr & e->ipfe_arg0[i * 2 + 1]) == e->ipfe_arg0[i * 2]) || ((nat->nat_nsrcaddr & e->ipfe_arg0[i * 2 + 1]) == e->ipfe_arg0[i * 2]) || ((nat->nat_odstaddr & e->ipfe_arg0[i * 2 + 1]) == e->ipfe_arg0[i * 2]) || ((nat->nat_ndstaddr & e->ipfe_arg0[i * 2 + 1]) == e->ipfe_arg0[i * 2]); } break; #ifdef USE_INET6 case IPF_EXP_IP6_SRCADDR : if (nat->nat_v[0] != 6) break; for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= IP6_MASKEQ(&nat->nat_osrc6, &e->ipfe_arg0[i * 8 + 4], &e->ipfe_arg0[i * 8]) || IP6_MASKEQ(&nat->nat_nsrc6, &e->ipfe_arg0[i * 8 + 4], &e->ipfe_arg0[i * 8]); } break; case IPF_EXP_IP6_DSTADDR : if (nat->nat_v[0] != 6) break; for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= IP6_MASKEQ(&nat->nat_odst6, &e->ipfe_arg0[i * 8 + 4], &e->ipfe_arg0[i * 8]) || IP6_MASKEQ(&nat->nat_ndst6, &e->ipfe_arg0[i * 8 + 4], &e->ipfe_arg0[i * 8]); } break; case IPF_EXP_IP6_ADDR : if (nat->nat_v[0] != 6) break; for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= IP6_MASKEQ(&nat->nat_osrc6, &e->ipfe_arg0[i * 8 + 4], &e->ipfe_arg0[i * 8]) || IP6_MASKEQ(&nat->nat_nsrc6, &e->ipfe_arg0[i * 8 + 4], &e->ipfe_arg0[i * 8]) || IP6_MASKEQ(&nat->nat_odst6, &e->ipfe_arg0[i * 8 + 4], &e->ipfe_arg0[i * 8]) || IP6_MASKEQ(&nat->nat_ndst6, &e->ipfe_arg0[i * 8 + 4], &e->ipfe_arg0[i * 8]); } break; #endif case IPF_EXP_UDP_PORT : case IPF_EXP_TCP_PORT : for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= (nat->nat_osport == e->ipfe_arg0[i]) || (nat->nat_nsport == e->ipfe_arg0[i]) || (nat->nat_odport == e->ipfe_arg0[i]) || (nat->nat_ndport == e->ipfe_arg0[i]); } break; case IPF_EXP_UDP_SPORT : case IPF_EXP_TCP_SPORT : for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= (nat->nat_osport == e->ipfe_arg0[i]) || (nat->nat_nsport == e->ipfe_arg0[i]); } break; case IPF_EXP_UDP_DPORT : case IPF_EXP_TCP_DPORT : for (i = 0; !rv && i < e->ipfe_narg; i++) { rv |= (nat->nat_odport == e->ipfe_arg0[i]) || (nat->nat_ndport == e->ipfe_arg0[i]); } break; } rv ^= e->ipfe_not; if (rv == 0) break; } return rv; } diff --git a/sbin/ipf/ipnat/ipnat_y.y b/sbin/ipf/ipnat/ipnat_y.y index a6a5a0e49d76..51f13d5fc6a1 100644 --- a/sbin/ipf/ipnat/ipnat_y.y +++ b/sbin/ipf/ipnat/ipnat_y.y @@ -1,1774 +1,1746 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ %{ #include #include #include #include #include #if !defined(__SVR4) && !defined(__GNUC__) #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipf.h" #include "netinet/ipl.h" #include "ipnat_l.h" #define YYDEBUG 1 extern void yyerror(char *); extern int yyparse(void); extern int yylex(void); extern int yydebug; extern FILE *yyin; extern int yylineNum; static ipnat_t *nattop = NULL; static ipnat_t *nat = NULL; static int natfd = -1; static ioctlfunc_t natioctlfunc = NULL; static addfunc_t nataddfunc = NULL; static int suggest_port = 0; static proxyrule_t *prules = NULL; static int parser_error = 0; static void newnatrule(void); static void setnatproto(int); static void setmapifnames(void); static void setrdrifnames(void); static void proxy_setconfig(int); static void proxy_unsetconfig(void); static namelist_t *proxy_dns_add_pass(char *, char *); static namelist_t *proxy_dns_add_block(char *, char *); static void proxy_addconfig(char *, int, char *, namelist_t *); static void proxy_loadconfig(int, ioctlfunc_t, char *, int, char *, namelist_t *); static void proxy_loadrules(int, ioctlfunc_t, proxyrule_t *); static void setmapifnames(void); static void setrdrifnames(void); static void setifname(ipnat_t **, int, char *); static int addname(ipnat_t **, char *); %} %union { char *str; u_32_t num; struct { i6addr_t a; int f; } ipa; frentry_t fr; frtuc_t *frt; u_short port; struct { int p1; int p2; int pc; } pc; struct { i6addr_t a; i6addr_t m; int t; /* Address type */ int u; int f; /* Family */ int v; /* IP version */ int s; /* 0 = number, 1 = text */ int n; /* number */ } ipp; union i6addr ip6; namelist_t *names; }; %token YY_NUMBER YY_HEX %token YY_STR %token YY_COMMENT %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT %token YY_RANGE_OUT YY_RANGE_IN %token YY_IPV6 %token IPNY_MAPBLOCK IPNY_RDR IPNY_PORT IPNY_PORTS IPNY_AUTO IPNY_RANGE %token IPNY_MAP IPNY_BIMAP IPNY_FROM IPNY_TO IPNY_MASK IPNY_PORTMAP IPNY_ANY %token IPNY_ROUNDROBIN IPNY_FRAG IPNY_AGE IPNY_ICMPIDMAP IPNY_PROXY %token IPNY_TCP IPNY_UDP IPNY_TCPUDP IPNY_STICKY IPNY_MSSCLAMP IPNY_TAG %token IPNY_TLATE IPNY_POOL IPNY_HASH IPNY_NO IPNY_REWRITE IPNY_PROTO %token IPNY_ON IPNY_SRC IPNY_DST IPNY_IN IPNY_OUT IPNY_DIVERT %token IPNY_CONFIG IPNY_ALLOW IPNY_DENY IPNY_DNS IPNY_INET IPNY_INET6 %token IPNY_SEQUENTIAL IPNY_DSTLIST IPNY_PURGE %type portspec %type hexnumber compare range proto %type saddr daddr sobject dobject mapfrom rdrfrom dip %type hostname ipv4 ipaddr %type addr rhsaddr rhdaddr erhdaddr %type portstuff portpair comaports srcports dstports %type dnslines dnsline %% file: line | assign | file line | file assign | file pconf ';' ; line: xx rule { int err; while ((nat = nattop) != NULL) { if (nat->in_v[0] == 0) nat->in_v[0] = 4; if (nat->in_v[1] == 0) nat->in_v[1] = nat->in_v[0]; nattop = nat->in_next; err = (*nataddfunc)(natfd, natioctlfunc, nat); free(nat); if (err != 0) { parser_error = err; break; } } if (parser_error == 0 && prules != NULL) { proxy_loadrules(natfd, natioctlfunc, prules); prules = NULL; } resetlexer(); } | YY_COMMENT ; assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); resetlexer(); free($1); free($3); yyvarnext = 0; } ; assigning: '=' { yyvarnext = 1; } ; xx: { newnatrule(); } ; rule: map eol | mapblock eol | redir eol | rewrite ';' | divert ';' ; no: IPNY_NO { nat->in_flags |= IPN_NO; } ; eol: | ';' ; map: mapit ifnames addr tlate rhsaddr proxy mapoptions { if ($3.f != 0 && $3.f != $5.f && $5.f != 0) yyerror("3.address family mismatch"); if (nat->in_v[0] == 0 && $5.v != 0) nat->in_v[0] = $5.v; else if (nat->in_v[0] == 0 && $3.v != 0) nat->in_v[0] = $3.v; if (nat->in_v[1] == 0 && $5.v != 0) nat->in_v[1] = $5.v; else if (nat->in_v[1] == 0 && $3.v != 0) nat->in_v[1] = $3.v; nat->in_osrcatype = $3.t; bcopy(&$3.a, &nat->in_osrc.na_addr[0], sizeof($3.a)); bcopy(&$3.m, &nat->in_osrc.na_addr[1], sizeof($3.a)); nat->in_nsrcatype = $5.t; nat->in_nsrcafunc = $5.u; bcopy(&$5.a, &nat->in_nsrc.na_addr[0], sizeof($5.a)); bcopy(&$5.m, &nat->in_nsrc.na_addr[1], sizeof($5.a)); setmapifnames(); } | mapit ifnames addr tlate rhsaddr mapport mapoptions { if ($3.f != $5.f && $3.f != 0 && $5.f != 0) yyerror("4.address family mismatch"); if (nat->in_v[1] == 0 && $5.v != 0) nat->in_v[1] = $5.v; else if (nat->in_v[0] == 0 && $3.v != 0) nat->in_v[0] = $3.v; if (nat->in_v[0] == 0 && $5.v != 0) nat->in_v[0] = $5.v; else if (nat->in_v[1] == 0 && $3.v != 0) nat->in_v[1] = $3.v; nat->in_osrcatype = $3.t; bcopy(&$3.a, &nat->in_osrc.na_addr[0], sizeof($3.a)); bcopy(&$3.m, &nat->in_osrc.na_addr[1], sizeof($3.a)); nat->in_nsrcatype = $5.t; nat->in_nsrcafunc = $5.u; bcopy(&$5.a, &nat->in_nsrc.na_addr[0], sizeof($5.a)); bcopy(&$5.m, &nat->in_nsrc.na_addr[1], sizeof($5.a)); setmapifnames(); } | no mapit ifnames addr setproto ';' { if (nat->in_v[0] == 0) nat->in_v[0] = $4.v; nat->in_osrcatype = $4.t; bcopy(&$4.a, &nat->in_osrc.na_addr[0], sizeof($4.a)); bcopy(&$4.m, &nat->in_osrc.na_addr[1], sizeof($4.a)); setmapifnames(); } | mapit ifnames mapfrom tlate rhsaddr proxy mapoptions { if ($3 != 0 && $5.f != 0 && $3 != $5.f) yyerror("5.address family mismatch"); if (nat->in_v[0] == 0 && $5.v != 0) nat->in_v[0] = $5.v; else if (nat->in_v[0] == 0 && $3 != 0) nat->in_v[0] = ftov($3); if (nat->in_v[1] == 0 && $5.v != 0) nat->in_v[1] = $5.v; else if (nat->in_v[1] == 0 && $3 != 0) nat->in_v[1] = ftov($3); nat->in_nsrcatype = $5.t; nat->in_nsrcafunc = $5.u; bcopy(&$5.a, &nat->in_nsrc.na_addr[0], sizeof($5.a)); bcopy(&$5.m, &nat->in_nsrc.na_addr[1], sizeof($5.a)); setmapifnames(); } | no mapit ifnames mapfrom setproto ';' { nat->in_v[0] = ftov($4); setmapifnames(); } | mapit ifnames mapfrom tlate rhsaddr mapport mapoptions { if ($3 != 0 && $5.f != 0 && $3 != $5.f) yyerror("6.address family mismatch"); if (nat->in_v[0] == 0 && $5.v != 0) nat->in_v[0] = $5.v; else if (nat->in_v[0] == 0 && $3 != 0) nat->in_v[0] = ftov($3); if (nat->in_v[1] == 0 && $5.v != 0) nat->in_v[1] = $5.v; else if (nat->in_v[1] == 0 && $3 != 0) nat->in_v[1] = ftov($3); nat->in_nsrcatype = $5.t; nat->in_nsrcafunc = $5.u; bcopy(&$5.a, &nat->in_nsrc.na_addr[0], sizeof($5.a)); bcopy(&$5.m, &nat->in_nsrc.na_addr[1], sizeof($5.a)); setmapifnames(); } ; mapblock: mapblockit ifnames addr tlate addr ports mapoptions { if ($3.f != 0 && $5.f != 0 && $3.f != $5.f) yyerror("7.address family mismatch"); if (nat->in_v[0] == 0 && $5.v != 0) nat->in_v[0] = $5.v; else if (nat->in_v[0] == 0 && $3.v != 0) nat->in_v[0] = $3.v; if (nat->in_v[1] == 0 && $5.v != 0) nat->in_v[1] = $5.v; else if (nat->in_v[1] == 0 && $3.v != 0) nat->in_v[1] = $3.v; nat->in_osrcatype = $3.t; bcopy(&$3.a, &nat->in_osrc.na_addr[0], sizeof($3.a)); bcopy(&$3.m, &nat->in_osrc.na_addr[1], sizeof($3.a)); nat->in_nsrcatype = $5.t; nat->in_nsrcafunc = $5.u; bcopy(&$5.a, &nat->in_nsrc.na_addr[0], sizeof($5.a)); bcopy(&$5.m, &nat->in_nsrc.na_addr[1], sizeof($5.a)); setmapifnames(); } | no mapblockit ifnames { yyexpectaddr = 1; } addr setproto ';' { if (nat->in_v[0] == 0) nat->in_v[0] = $5.v; if (nat->in_v[1] == 0) nat->in_v[1] = $5.v; nat->in_osrcatype = $5.t; bcopy(&$5.a, &nat->in_osrc.na_addr[0], sizeof($5.a)); bcopy(&$5.m, &nat->in_osrc.na_addr[1], sizeof($5.a)); setmapifnames(); } ; redir: rdrit ifnames addr dport tlate dip nport setproto rdroptions { if ($6 != 0 && $3.f != 0 && $6 != $3.f) yyerror("21.address family mismatch"); if (nat->in_v[0] == 0) { if ($3.v != AF_UNSPEC) nat->in_v[0] = ftov($3.f); else nat->in_v[0] = ftov($6); } nat->in_odstatype = $3.t; bcopy(&$3.a, &nat->in_odst.na_addr[0], sizeof($3.a)); bcopy(&$3.m, &nat->in_odst.na_addr[1], sizeof($3.a)); setrdrifnames(); } | no rdrit ifnames addr dport setproto ';' { if (nat->in_v[0] == 0) nat->in_v[0] = ftov($4.f); nat->in_odstatype = $4.t; bcopy(&$4.a, &nat->in_odst.na_addr[0], sizeof($4.a)); bcopy(&$4.m, &nat->in_odst.na_addr[1], sizeof($4.a)); setrdrifnames(); } | rdrit ifnames rdrfrom tlate dip nport setproto rdroptions { if ($5 != 0 && $3 != 0 && $5 != $3) yyerror("20.address family mismatch"); if (nat->in_v[0] == 0) { if ($3 != AF_UNSPEC) nat->in_v[0] = ftov($3); else nat->in_v[0] = ftov($5); } setrdrifnames(); } | no rdrit ifnames rdrfrom setproto ';' { nat->in_v[0] = ftov($4); setrdrifnames(); } ; rewrite: IPNY_REWRITE oninout rwrproto mapfrom tlate newdst newopts { if (nat->in_v[0] == 0) nat->in_v[0] = ftov($4); if (nat->in_redir & NAT_MAP) setmapifnames(); else setrdrifnames(); nat->in_redir |= NAT_REWRITE; } ; divert: IPNY_DIVERT oninout rwrproto mapfrom tlate divdst newopts { if (nat->in_v[0] == 0) nat->in_v[0] = ftov($4); if (nat->in_redir & NAT_MAP) { setmapifnames(); nat->in_pr[0] = IPPROTO_UDP; } else { setrdrifnames(); nat->in_pr[1] = IPPROTO_UDP; } nat->in_flags &= ~IPN_TCP; } ; tlate: IPNY_TLATE { yyexpectaddr = 1; } ; pconf: IPNY_PROXY { yysetdict(proxies); } IPNY_DNS '/' proto IPNY_CONFIG YY_STR '{' { proxy_setconfig(IPNY_DNS); } dnslines ';' '}' { proxy_addconfig("dns", $5, $7, $10); proxy_unsetconfig(); } ; dnslines: dnsline { $$ = $1; } | dnslines ';' dnsline { $$ = $1; $1->na_next = $3; } ; dnsline: IPNY_ALLOW YY_STR { $$ = proxy_dns_add_pass(NULL, $2); } | IPNY_DENY YY_STR { $$ = proxy_dns_add_block(NULL, $2); } | IPNY_ALLOW '.' YY_STR { $$ = proxy_dns_add_pass(".", $3); } | IPNY_DENY '.' YY_STR { $$ = proxy_dns_add_block(".", $3); } ; oninout: inout IPNY_ON ifnames { ; } ; inout: IPNY_IN { nat->in_redir = NAT_REDIRECT; } | IPNY_OUT { nat->in_redir = NAT_MAP; } ; rwrproto: | IPNY_PROTO setproto ; newdst: src rhsaddr srcports dst erhdaddr dstports { nat->in_nsrc.na_addr[0] = $2.a; nat->in_nsrc.na_addr[1] = $2.m; nat->in_nsrc.na_atype = $2.t; if ($2.t == FRI_LOOKUP) { nat->in_nsrc.na_type = $2.u; nat->in_nsrc.na_subtype = $2.s; nat->in_nsrc.na_num = $2.n; } nat->in_nsports[0] = $3.p1; nat->in_nsports[1] = $3.p2; nat->in_ndst.na_addr[0] = $5.a; nat->in_ndst.na_addr[1] = $5.m; nat->in_ndst.na_atype = $5.t; if ($5.t == FRI_LOOKUP) { nat->in_ndst.na_type = $5.u; nat->in_ndst.na_subtype = $5.s; nat->in_ndst.na_num = $5.n; } nat->in_ndports[0] = $6.p1; nat->in_ndports[1] = $6.p2; } ; divdst: src addr ',' portspec dst addr ',' portspec IPNY_UDP { nat->in_nsrc.na_addr[0] = $2.a; if ($2.m.in4.s_addr != 0xffffffff) yyerror("divert must have /32 dest"); nat->in_nsrc.na_addr[1] = $2.m; nat->in_nsports[0] = $4; nat->in_nsports[1] = $4; nat->in_ndst.na_addr[0] = $6.a; nat->in_ndst.na_addr[1] = $6.m; if ($6.m.in4.s_addr != 0xffffffff) yyerror("divert must have /32 dest"); nat->in_ndports[0] = $8; nat->in_ndports[1] = $8; nat->in_redir |= NAT_DIVERTUDP; } ; src: IPNY_SRC { yyexpectaddr = 1; } ; dst: IPNY_DST { yyexpectaddr = 1; } ; srcports: comaports { $$.p1 = $1.p1; $$.p2 = $1.p2; } | IPNY_PORT '=' portspec { $$.p1 = $3; $$.p2 = $3; nat->in_flags |= IPN_FIXEDSPORT; } ; dstports: comaports { $$.p1 = $1.p1; $$.p2 = $1.p2; } | IPNY_PORT '=' portspec { $$.p1 = $3; $$.p2 = $3; nat->in_flags |= IPN_FIXEDDPORT; } ; comaports: { $$.p1 = 0; $$.p2 = 0; } | ',' { if (!(nat->in_flags & IPN_TCPUDP)) yyerror("must be TCP/UDP for ports"); } portpair { $$.p1 = $3.p1; $$.p2 = $3.p2; } ; proxy: | IPNY_PROXY port portspec YY_STR '/' proto { int pos; pos = addname(&nat, $4); nat->in_plabel = pos; if (nat->in_dcmp == 0) { nat->in_odport = $3; } else if ($3 != nat->in_odport) { yyerror("proxy port numbers not consistant"); } nat->in_ndport = $3; setnatproto($6); free($4); } | IPNY_PROXY port YY_STR YY_STR '/' proto { int pnum, pos; pos = addname(&nat, $4); nat->in_plabel = pos; pnum = getportproto($3, $6); if (pnum == -1) yyerror("invalid port number"); nat->in_odport = ntohs(pnum); nat->in_ndport = ntohs(pnum); setnatproto($6); free($3); free($4); } | IPNY_PROXY port portspec YY_STR '/' proto IPNY_CONFIG YY_STR { int pos; pos = addname(&nat, $4); nat->in_plabel = pos; if (nat->in_dcmp == 0) { nat->in_odport = $3; } else if ($3 != nat->in_odport) { yyerror("proxy port numbers not consistant"); } nat->in_ndport = $3; setnatproto($6); nat->in_pconfig = addname(&nat, $8); free($4); free($8); } | IPNY_PROXY port YY_STR YY_STR '/' proto IPNY_CONFIG YY_STR { int pnum, pos; pos = addname(&nat, $4); nat->in_plabel = pos; pnum = getportproto($3, $6); if (pnum == -1) yyerror("invalid port number"); nat->in_odport = ntohs(pnum); nat->in_ndport = ntohs(pnum); setnatproto($6); pos = addname(&nat, $8); nat->in_pconfig = pos; free($3); free($4); free($8); } ; setproto: | proto { if (nat->in_pr[0] != 0 || nat->in_pr[1] != 0 || nat->in_flags & IPN_TCPUDP) yyerror("protocol set twice"); setnatproto($1); } | IPNY_TCPUDP { if (nat->in_pr[0] != 0 || nat->in_pr[1] != 0 || nat->in_flags & IPN_TCPUDP) yyerror("protocol set twice"); nat->in_flags |= IPN_TCPUDP; nat->in_pr[0] = 0; nat->in_pr[1] = 0; } | IPNY_TCP '/' IPNY_UDP { if (nat->in_pr[0] != 0 || nat->in_pr[1] != 0 || nat->in_flags & IPN_TCPUDP) yyerror("protocol set twice"); nat->in_flags |= IPN_TCPUDP; nat->in_pr[0] = 0; nat->in_pr[1] = 0; } ; rhsaddr: addr { $$ = $1; yyexpectaddr = 0; } | hostname '-' { yyexpectaddr = 1; } hostname { $$.t = FRI_RANGE; if ($1.f != $4.f) yyerror("8.address family " "mismatch"); $$.f = $1.f; $$.v = ftov($1.f); $$.a = $1.a; $$.m = $4.a; nat->in_flags |= IPN_SIPRANGE; yyexpectaddr = 0; } | IPNY_RANGE hostname '-' { yyexpectaddr = 1; } hostname { $$.t = FRI_RANGE; if ($2.f != $5.f) yyerror("9.address family " "mismatch"); $$.f = $2.f; $$.v = ftov($2.f); $$.a = $2.a; $$.m = $5.a; nat->in_flags |= IPN_SIPRANGE; yyexpectaddr = 0; } ; dip: hostname ',' { yyexpectaddr = 1; } hostname { nat->in_flags |= IPN_SPLIT; if ($1.f != $4.f) yyerror("10.address family " "mismatch"); $$ = $1.f; nat->in_ndstip6 = $1.a; nat->in_ndstmsk6 = $4.a; nat->in_ndstatype = FRI_SPLIT; yyexpectaddr = 0; } | rhdaddr { int bits; nat->in_ndstip6 = $1.a; nat->in_ndstmsk6 = $1.m; nat->in_ndst.na_atype = $1.t; yyexpectaddr = 0; if ($1.f == AF_INET) bits = count4bits($1.m.in4.s_addr); else bits = count6bits($1.m.i6); if (($1.f == AF_INET) && (bits != 0) && (bits != 32)) { yyerror("dest ip bitmask not /32"); } else if (($1.f == AF_INET6) && (bits != 0) && (bits != 128)) { yyerror("dest ip bitmask not /128"); } $$ = $1.f; } ; rhdaddr: addr { $$ = $1; yyexpectaddr = 0; } | hostname '-' hostname { bzero(&$$, sizeof($$)); $$.t = FRI_RANGE; if ($1.f != 0 && $3.f != 0 && $1.f != $3.f) yyerror("11.address family " "mismatch"); $$.a = $1.a; $$.m = $3.a; nat->in_flags |= IPN_DIPRANGE; yyexpectaddr = 0; } | IPNY_RANGE hostname '-' hostname { bzero(&$$, sizeof($$)); $$.t = FRI_RANGE; if ($2.f != 0 && $4.f != 0 && $2.f != $4.f) yyerror("12.address family " "mismatch"); $$.a = $2.a; $$.m = $4.a; nat->in_flags |= IPN_DIPRANGE; yyexpectaddr = 0; } ; erhdaddr: rhdaddr { $$ = $1; } | IPNY_DSTLIST '/' YY_NUMBER { $$.t = FRI_LOOKUP; $$.u = IPLT_DSTLIST; $$.s = 0; $$.n = $3; } | IPNY_DSTLIST '/' YY_STR { $$.t = FRI_LOOKUP; $$.u = IPLT_DSTLIST; $$.s = 1; $$.n = addname(&nat, $3); } ; port: IPNY_PORT { suggest_port = 1; } ; portspec: YY_NUMBER { if ($1 > 65535) /* Unsigned */ yyerror("invalid port number"); else $$ = $1; } | YY_STR { if (getport(NULL, $1, &($$), NULL) == -1) yyerror("invalid port number"); $$ = ntohs($$); } ; portpair: portspec { $$.p1 = $1; $$.p2 = $1; } | portspec '-' portspec { $$.p1 = $1; $$.p2 = $3; } | portspec ':' portspec { $$.p1 = $1; $$.p2 = $3; } ; dport: | port portpair { nat->in_odport = $2.p1; if ($2.p2 == 0) nat->in_dtop = $2.p1; else nat->in_dtop = $2.p2; } ; nport: | port portpair { nat->in_dpmin = $2.p1; nat->in_dpnext = $2.p1; nat->in_dpmax = $2.p2; nat->in_ndport = $2.p1; if (nat->in_dtop == 0) nat->in_dtop = $2.p2; } | port '=' portspec { nat->in_dpmin = $3; nat->in_dpnext = $3; nat->in_ndport = $3; if (nat->in_dtop == 0) nat->in_dtop = nat->in_odport; nat->in_flags |= IPN_FIXEDDPORT; } ; ports: | IPNY_PORTS YY_NUMBER { nat->in_spmin = $2; } | IPNY_PORTS IPNY_AUTO { nat->in_flags |= IPN_AUTOPORTMAP; } ; mapit: IPNY_MAP { nat->in_redir = NAT_MAP; } | IPNY_BIMAP { nat->in_redir = NAT_BIMAP; } ; rdrit: IPNY_RDR { nat->in_redir = NAT_REDIRECT; } ; mapblockit: IPNY_MAPBLOCK { nat->in_redir = NAT_MAPBLK; } ; mapfrom: from sobject to dobject { if ($2 != 0 && $4 != 0 && $2 != $4) yyerror("13.address family " "mismatch"); $$ = $2; } | from sobject '!' to dobject { if ($2 != 0 && $5 != 0 && $2 != $5) yyerror("14.address family " "mismatch"); nat->in_flags |= IPN_NOTDST; $$ = $2; } | from sobject to '!' dobject { if ($2 != 0 && $5 != 0 && $2 != $5) yyerror("15.address family " "mismatch"); nat->in_flags |= IPN_NOTDST; $$ = $2; } ; rdrfrom: from sobject to dobject { if ($2 != 0 && $4 != 0 && $2 != $4) yyerror("16.address family " "mismatch"); $$ = $2; } | '!' from sobject to dobject { if ($3 != 0 && $5 != 0 && $3 != $5) yyerror("17.address family " "mismatch"); nat->in_flags |= IPN_NOTSRC; $$ = $3; } | from '!' sobject to dobject { if ($3 != 0 && $5 != 0 && $3 != $5) yyerror("18.address family " "mismatch"); nat->in_flags |= IPN_NOTSRC; $$ = $3; } ; from: IPNY_FROM { nat->in_flags |= IPN_FILTER; yyexpectaddr = 1; } ; to: IPNY_TO { yyexpectaddr = 1; } ; ifnames: ifname family { yyexpectaddr = 1; } | ifname ',' otherifname family { yyexpectaddr = 1; } ; ifname: YY_STR { setifname(&nat, 0, $1); free($1); } ; family: | IPNY_INET { nat->in_v[0] = 4; nat->in_v[1] = 4; } | IPNY_INET6 { nat->in_v[0] = 6; nat->in_v[1] = 6; } ; otherifname: YY_STR { setifname(&nat, 1, $1); free($1); } ; mapport: IPNY_PORTMAP tcpudp portpair sequential { nat->in_spmin = $3.p1; nat->in_spmax = $3.p2; } | IPNY_PORTMAP portpair tcpudp sequential { nat->in_spmin = $2.p1; nat->in_spmax = $2.p2; } | IPNY_PORTMAP tcpudp IPNY_AUTO sequential { nat->in_flags |= IPN_AUTOPORTMAP; nat->in_spmin = 1024; nat->in_spmax = 65535; } | IPNY_ICMPIDMAP YY_STR portpair sequential { if (strcmp($2, "icmp") != 0 && strcmp($2, "ipv6-icmp") != 0) { yyerror("icmpidmap not followed by icmp"); } free($2); if ($3.p1 < 0 || $3.p1 > 65535) yyerror("invalid 1st ICMP Id number"); if ($3.p2 < 0 || $3.p2 > 65535) yyerror("invalid 2nd ICMP Id number"); if (strcmp($2, "ipv6-icmp") == 0) { nat->in_pr[0] = IPPROTO_ICMPV6; nat->in_pr[1] = IPPROTO_ICMPV6; } else { nat->in_pr[0] = IPPROTO_ICMP; nat->in_pr[1] = IPPROTO_ICMP; } nat->in_flags = IPN_ICMPQUERY; nat->in_spmin = $3.p1; nat->in_spmax = $3.p2; } ; sobject: saddr { $$ = $1; } | saddr port portstuff { nat->in_osport = $3.p1; nat->in_stop = $3.p2; nat->in_scmp = $3.pc; $$ = $1; } ; saddr: addr { nat->in_osrcatype = $1.t; bcopy(&$1.a, &nat->in_osrc.na_addr[0], sizeof($1.a)); bcopy(&$1.m, &nat->in_osrc.na_addr[1], sizeof($1.m)); $$ = $1.f; } ; dobject: daddr { $$ = $1; } | daddr port portstuff { nat->in_odport = $3.p1; nat->in_dtop = $3.p2; nat->in_dcmp = $3.pc; $$ = $1; } ; daddr: addr { nat->in_odstatype = $1.t; bcopy(&$1.a, &nat->in_odst.na_addr[0], sizeof($1.a)); bcopy(&$1.m, &nat->in_odst.na_addr[1], sizeof($1.m)); $$ = $1.f; } ; addr: IPNY_ANY { yyexpectaddr = 0; bzero(&$$, sizeof($$)); $$.t = FRI_NORMAL; } | hostname { bzero(&$$, sizeof($$)); $$.a = $1.a; $$.t = FRI_NORMAL; $$.v = ftov($1.f); $$.f = $1.f; if ($$.f == AF_INET) { $$.m.in4.s_addr = 0xffffffff; } else if ($$.f == AF_INET6) { $$.m.i6[0] = 0xffffffff; $$.m.i6[1] = 0xffffffff; $$.m.i6[2] = 0xffffffff; $$.m.i6[3] = 0xffffffff; } yyexpectaddr = 0; } | hostname slash YY_NUMBER { bzero(&$$, sizeof($$)); $$.a = $1.a; $$.f = $1.f; $$.v = ftov($1.f); $$.t = FRI_NORMAL; ntomask($$.f, $3, (u_32_t *)&$$.m); $$.a.i6[0] &= $$.m.i6[0]; $$.a.i6[1] &= $$.m.i6[1]; $$.a.i6[2] &= $$.m.i6[2]; $$.a.i6[3] &= $$.m.i6[3]; yyexpectaddr = 0; } | hostname slash ipaddr { bzero(&$$, sizeof($$)); if ($1.f != $3.f) { yyerror("1.address family " "mismatch"); } $$.a = $1.a; $$.m = $3.a; $$.t = FRI_NORMAL; $$.a.i6[0] &= $$.m.i6[0]; $$.a.i6[1] &= $$.m.i6[1]; $$.a.i6[2] &= $$.m.i6[2]; $$.a.i6[3] &= $$.m.i6[3]; $$.f = $1.f; $$.v = ftov($1.f); yyexpectaddr = 0; } | hostname slash hexnumber { bzero(&$$, sizeof($$)); $$.a = $1.a; $$.m.in4.s_addr = htonl($3); $$.t = FRI_NORMAL; $$.a.in4.s_addr &= $$.m.in4.s_addr; $$.f = $1.f; $$.v = ftov($1.f); if ($$.f == AF_INET6) yyerror("incorrect inet6 mask"); } | hostname mask ipaddr { bzero(&$$, sizeof($$)); if ($1.f != $3.f) { yyerror("2.address family " "mismatch"); } $$.a = $1.a; $$.m = $3.a; $$.t = FRI_NORMAL; $$.a.i6[0] &= $$.m.i6[0]; $$.a.i6[1] &= $$.m.i6[1]; $$.a.i6[2] &= $$.m.i6[2]; $$.a.i6[3] &= $$.m.i6[3]; $$.f = $1.f; $$.v = ftov($1.f); yyexpectaddr = 0; } | hostname mask hexnumber { bzero(&$$, sizeof($$)); $$.a = $1.a; $$.m.in4.s_addr = htonl($3); $$.t = FRI_NORMAL; $$.a.in4.s_addr &= $$.m.in4.s_addr; $$.f = AF_INET; $$.v = 4; } | pool slash YY_NUMBER { bzero(&$$, sizeof($$)); $$.a.iplookupnum = $3; $$.a.iplookuptype = IPLT_POOL; $$.a.iplookupsubtype = 0; $$.t = FRI_LOOKUP; } | pool slash YY_STR { bzero(&$$, sizeof($$)); $$.a.iplookupname = addname(&nat,$3); $$.a.iplookuptype = IPLT_POOL; $$.a.iplookupsubtype = 1; $$.t = FRI_LOOKUP; } | hash slash YY_NUMBER { bzero(&$$, sizeof($$)); $$.a.iplookupnum = $3; $$.a.iplookuptype = IPLT_HASH; $$.a.iplookupsubtype = 0; $$.t = FRI_LOOKUP; } | hash slash YY_STR { bzero(&$$, sizeof($$)); $$.a.iplookupname = addname(&nat,$3); $$.a.iplookuptype = IPLT_HASH; $$.a.iplookupsubtype = 1; $$.t = FRI_LOOKUP; } ; slash: '/' { yyexpectaddr = 0; } ; mask: IPNY_MASK { yyexpectaddr = 0; } ; pool: IPNY_POOL { if (!(nat->in_flags & IPN_FILTER)) { yyerror("Can only use pool with from/to rules\n"); } yyexpectaddr = 0; yyresetdict(); } ; hash: IPNY_HASH { if (!(nat->in_flags & IPN_FILTER)) { yyerror("Can only use hash with from/to rules\n"); } yyexpectaddr = 0; yyresetdict(); } ; portstuff: compare portspec { $$.pc = $1; $$.p1 = $2; $$.p2 = 0; } | portspec range portspec { $$.pc = $2; $$.p1 = $1; $$.p2 = $3; } ; mapoptions: rr frag age mssclamp nattag setproto purge ; rdroptions: rr frag age sticky mssclamp rdrproxy nattag purge ; nattag: | IPNY_TAG YY_STR { strncpy(nat->in_tag.ipt_tag, $2, sizeof(nat->in_tag.ipt_tag)); } rr: | IPNY_ROUNDROBIN { nat->in_flags |= IPN_ROUNDR; } ; frag: | IPNY_FRAG { nat->in_flags |= IPN_FRAG; } ; age: | IPNY_AGE YY_NUMBER { nat->in_age[0] = $2; nat->in_age[1] = $2; } | IPNY_AGE YY_NUMBER '/' YY_NUMBER { nat->in_age[0] = $2; nat->in_age[1] = $4; } ; sticky: | IPNY_STICKY { if (!(nat->in_flags & IPN_ROUNDR) && !(nat->in_flags & IPN_SPLIT)) { FPRINTF(stderr, "'sticky' for use with round-robin/IP splitting only\n"); } else nat->in_flags |= IPN_STICKY; } ; mssclamp: | IPNY_MSSCLAMP YY_NUMBER { nat->in_mssclamp = $2; } ; tcpudp: IPNY_TCP { setnatproto(IPPROTO_TCP); } | IPNY_UDP { setnatproto(IPPROTO_UDP); } | IPNY_TCPUDP { nat->in_flags |= IPN_TCPUDP; nat->in_pr[0] = 0; nat->in_pr[1] = 0; } | IPNY_TCP '/' IPNY_UDP { nat->in_flags |= IPN_TCPUDP; nat->in_pr[0] = 0; nat->in_pr[1] = 0; } ; sequential: | IPNY_SEQUENTIAL { nat->in_flags |= IPN_SEQUENTIAL; } ; purge: | IPNY_PURGE { nat->in_flags |= IPN_PURGE; } ; rdrproxy: IPNY_PROXY YY_STR { int pos; pos = addname(&nat, $2); nat->in_plabel = pos; nat->in_odport = nat->in_dpnext; nat->in_dtop = nat->in_odport; free($2); } | proxy { if (nat->in_plabel != -1) { nat->in_ndport = nat->in_odport; nat->in_dpmin = nat->in_odport; nat->in_dpmax = nat->in_dpmin; nat->in_dtop = nat->in_dpmin; nat->in_dpnext = nat->in_dpmin; } } ; newopts: | IPNY_PURGE { nat->in_flags |= IPN_PURGE; } ; proto: YY_NUMBER { $$ = $1; if ($$ != IPPROTO_TCP && $$ != IPPROTO_UDP) suggest_port = 0; } | IPNY_TCP { $$ = IPPROTO_TCP; } | IPNY_UDP { $$ = IPPROTO_UDP; } | YY_STR { $$ = getproto($1); free($1); if ($$ == -1) yyerror("unknown protocol"); if ($$ != IPPROTO_TCP && $$ != IPPROTO_UDP) suggest_port = 0; } ; hexnumber: YY_HEX { $$ = $1; } ; hostname: YY_STR { i6addr_t addr; int family; #ifdef USE_INET6 if (nat->in_v[0] == 6) family = AF_INET6; else #endif family = AF_INET; memset(&($$), 0, sizeof($$)); memset(&addr, 0, sizeof(addr)); $$.f = family; if (gethost(family, $1, &addr) == 0) { $$.a = addr; } else { FPRINTF(stderr, "Unknown host '%s'\n", $1); } free($1); } | YY_NUMBER { memset(&($$), 0, sizeof($$)); $$.a.in4.s_addr = htonl($1); if ($$.a.in4.s_addr != 0) $$.f = AF_INET; } | ipv4 { $$ = $1; } | YY_IPV6 { memset(&($$), 0, sizeof($$)); $$.a = $1; $$.f = AF_INET6; } | YY_NUMBER YY_IPV6 { memset(&($$), 0, sizeof($$)); $$.a = $2; $$.f = AF_INET6; } ; compare: '=' { $$ = FR_EQUAL; } | YY_CMP_EQ { $$ = FR_EQUAL; } | YY_CMP_NE { $$ = FR_NEQUAL; } | YY_CMP_LT { $$ = FR_LESST; } | YY_CMP_LE { $$ = FR_LESSTE; } | YY_CMP_GT { $$ = FR_GREATERT; } | YY_CMP_GE { $$ = FR_GREATERTE; } range: YY_RANGE_OUT { $$ = FR_OUTRANGE; } | YY_RANGE_IN { $$ = FR_INRANGE; } | ':' { $$ = FR_INCRANGE; } ; ipaddr: ipv4 { $$ = $1; } | YY_IPV6 { $$.a = $1; $$.f = AF_INET6; } ; ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { yyerror("Invalid octet string for IP address"); return 0; } bzero((char *)&$$, sizeof($$)); $$.a.in4.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; $$.a.in4.s_addr = htonl($$.a.in4.s_addr); $$.f = AF_INET; } ; %% static wordtab_t proxies[] = { { "dns", IPNY_DNS } }; static wordtab_t dnswords[] = { { "allow", IPNY_ALLOW }, { "block", IPNY_DENY }, { "deny", IPNY_DENY }, { "drop", IPNY_DENY }, { "pass", IPNY_ALLOW }, }; static wordtab_t yywords[] = { { "age", IPNY_AGE }, { "any", IPNY_ANY }, { "auto", IPNY_AUTO }, { "bimap", IPNY_BIMAP }, { "config", IPNY_CONFIG }, { "divert", IPNY_DIVERT }, { "dst", IPNY_DST }, { "dstlist", IPNY_DSTLIST }, { "frag", IPNY_FRAG }, { "from", IPNY_FROM }, { "hash", IPNY_HASH }, { "icmpidmap", IPNY_ICMPIDMAP }, { "in", IPNY_IN }, { "inet", IPNY_INET }, { "inet6", IPNY_INET6 }, { "mask", IPNY_MASK }, { "map", IPNY_MAP }, { "map-block", IPNY_MAPBLOCK }, { "mssclamp", IPNY_MSSCLAMP }, { "netmask", IPNY_MASK }, { "no", IPNY_NO }, { "on", IPNY_ON }, { "out", IPNY_OUT }, { "pool", IPNY_POOL }, { "port", IPNY_PORT }, { "portmap", IPNY_PORTMAP }, { "ports", IPNY_PORTS }, { "proto", IPNY_PROTO }, { "proxy", IPNY_PROXY }, { "purge", IPNY_PURGE }, { "range", IPNY_RANGE }, { "rewrite", IPNY_REWRITE }, { "rdr", IPNY_RDR }, { "round-robin",IPNY_ROUNDROBIN }, { "sequential", IPNY_SEQUENTIAL }, { "src", IPNY_SRC }, { "sticky", IPNY_STICKY }, { "tag", IPNY_TAG }, { "tcp", IPNY_TCP }, { "tcpudp", IPNY_TCPUDP }, { "to", IPNY_TO }, { "udp", IPNY_UDP }, { "-", '-' }, { "->", IPNY_TLATE }, { "eq", YY_CMP_EQ }, { "ne", YY_CMP_NE }, { "lt", YY_CMP_LT }, { "gt", YY_CMP_GT }, { "le", YY_CMP_LE }, { "ge", YY_CMP_GE }, { NULL, 0 } }; int -ipnat_parsefile(fd, addfunc, ioctlfunc, filename) - int fd; - addfunc_t addfunc; - ioctlfunc_t ioctlfunc; - char *filename; +ipnat_parsefile(int fd, addfunc_t addfunc, ioctlfunc_t ioctlfunc, + char *filename) { FILE *fp = NULL; int rval; char *s; yylineNum = 1; (void) yysettab(yywords); s = getenv("YYDEBUG"); if (s) yydebug = atoi(s); else yydebug = 0; if (strcmp(filename, "-")) { fp = fopen(filename, "r"); if (!fp) { FPRINTF(stderr, "fopen(%s) failed: %s\n", filename, STRERROR(errno)); return -1; } } else fp = stdin; while ((rval = ipnat_parsesome(fd, addfunc, ioctlfunc, fp)) == 0) ; if (fp != NULL) fclose(fp); if (rval == -1) rval = 0; else if (rval != 0) rval = 1; return rval; } int -ipnat_parsesome(fd, addfunc, ioctlfunc, fp) - int fd; - addfunc_t addfunc; - ioctlfunc_t ioctlfunc; - FILE *fp; +ipnat_parsesome(int fd, addfunc_t addfunc, ioctlfunc_t ioctlfunc, + FILE *fp) { char *s; int i; natfd = fd; parser_error = 0; nataddfunc = addfunc; natioctlfunc = ioctlfunc; if (feof(fp)) return -1; i = fgetc(fp); if (i == EOF) return -1; if (ungetc(i, fp) == EOF) return -1; if (feof(fp)) return -1; s = getenv("YYDEBUG"); if (s) yydebug = atoi(s); else yydebug = 0; yyin = fp; yyparse(); return parser_error; } static void -newnatrule() +newnatrule(void) { ipnat_t *n; n = calloc(1, sizeof(*n)); if (n == NULL) return; if (nat == NULL) { nattop = nat = n; n->in_pnext = &nattop; } else { nat->in_next = n; n->in_pnext = &nat->in_next; nat = n; } n->in_flineno = yylineNum; n->in_ifnames[0] = -1; n->in_ifnames[1] = -1; n->in_plabel = -1; n->in_pconfig = -1; n->in_size = sizeof(*n); suggest_port = 0; } static void -setnatproto(p) - int p; +setnatproto(int p) { nat->in_pr[0] = p; nat->in_pr[1] = p; switch (p) { case IPPROTO_TCP : nat->in_flags |= IPN_TCP; nat->in_flags &= ~IPN_UDP; break; case IPPROTO_UDP : nat->in_flags |= IPN_UDP; nat->in_flags &= ~IPN_TCP; break; #ifdef USE_INET6 case IPPROTO_ICMPV6 : #endif case IPPROTO_ICMP : nat->in_flags &= ~IPN_TCPUDP; if (!(nat->in_flags & IPN_ICMPQUERY) && !(nat->in_redir & NAT_DIVERTUDP)) { nat->in_dcmp = 0; nat->in_scmp = 0; nat->in_dpmin = 0; nat->in_dpmax = 0; nat->in_dpnext = 0; nat->in_spmin = 0; nat->in_spmax = 0; nat->in_spnext = 0; } break; default : if ((nat->in_redir & NAT_MAPBLK) == 0) { nat->in_flags &= ~IPN_TCPUDP; nat->in_dcmp = 0; nat->in_scmp = 0; nat->in_dpmin = 0; nat->in_dpmax = 0; nat->in_dpnext = 0; nat->in_spmin = 0; nat->in_spmax = 0; nat->in_spnext = 0; } break; } if ((nat->in_flags & (IPN_TCP|IPN_UDP)) == 0) { nat->in_stop = 0; nat->in_dtop = 0; nat->in_osport = 0; nat->in_odport = 0; nat->in_stop = 0; nat->in_osport = 0; nat->in_dtop = 0; nat->in_odport = 0; } if ((nat->in_flags & (IPN_TCPUDP|IPN_FIXEDDPORT)) == IPN_FIXEDDPORT) nat->in_flags &= ~IPN_FIXEDDPORT; } int -ipnat_addrule(fd, ioctlfunc, ptr) - int fd; - ioctlfunc_t ioctlfunc; - void *ptr; +ipnat_addrule(int fd, ioctlfunc_t ioctlfunc, void *ptr) { ioctlcmd_t add, del; ipfobj_t obj; ipnat_t *ipn; ipn = ptr; bzero((char *)&obj, sizeof(obj)); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_size = ipn->in_size; obj.ipfo_type = IPFOBJ_IPNAT; obj.ipfo_ptr = ptr; if ((opts & OPT_DONOTHING) != 0) fd = -1; if (opts & OPT_ZERORULEST) { add = SIOCZRLST; del = 0; } else if (opts & OPT_PURGE) { add = 0; del = SIOCPURGENAT; } else { add = SIOCADNAT; del = SIOCRMNAT; } if ((opts & OPT_VERBOSE) != 0) printnat(ipn, opts); if (opts & OPT_DEBUG) binprint(ipn, ipn->in_size); if ((opts & OPT_ZERORULEST) != 0) { if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { if ((opts & OPT_DONOTHING) == 0) { char msg[80]; snprintf(msg, sizeof(msg), "%d:ioctl(zero nat rule)", ipn->in_flineno); return ipf_perror_fd(fd, ioctlfunc, msg); } } else { PRINTF("hits %lu ", ipn->in_hits); #ifdef USE_QUAD_T PRINTF("bytes %"PRIu64" ", ipn->in_bytes[0] + ipn->in_bytes[1]); #else PRINTF("bytes %lu ", ipn->in_bytes[0] + ipn->in_bytes[1]); #endif printnat(ipn, opts); } } else if ((opts & OPT_REMOVE) != 0) { if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) { if ((opts & OPT_DONOTHING) == 0) { char msg[80]; snprintf(msg, sizeof(msg), "%d:ioctl(delete nat rule)", ipn->in_flineno); return ipf_perror_fd(fd, ioctlfunc, msg); } } } else { if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { if ((opts & OPT_DONOTHING) == 0) { char msg[80]; snprintf(msg, sizeof(msg), "%d:ioctl(add/insert nat rule)", ipn->in_flineno); if (errno == EEXIST) { int strlen_msg = strlen(msg); snprintf(msg + strlen_msg, sizeof(msg) -strlen_msg, "(line %d)", ipn->in_flineno); } return ipf_perror_fd(fd, ioctlfunc, msg); } } } return 0; } static void setmapifnames() { if (nat->in_ifnames[1] == -1) nat->in_ifnames[1] = nat->in_ifnames[0]; if ((suggest_port == 1) && (nat->in_flags & IPN_TCPUDP) == 0) nat->in_flags |= IPN_TCPUDP; if ((nat->in_flags & IPN_TCPUDP) == 0) setnatproto(nat->in_pr[1]); if (((nat->in_redir & NAT_MAPBLK) != 0) || ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) nat_setgroupmap(nat); } static void -setrdrifnames() +setrdrifnames(void) { if ((suggest_port == 1) && (nat->in_flags & IPN_TCPUDP) == 0) nat->in_flags |= IPN_TCPUDP; if ((nat->in_pr[0] == 0) && ((nat->in_flags & IPN_TCPUDP) == 0) && (nat->in_dpmin != 0 || nat->in_dpmax != 0 || nat->in_dpnext != 0)) setnatproto(IPPROTO_TCP); if (nat->in_ifnames[1] == -1) nat->in_ifnames[1] = nat->in_ifnames[0]; } static void -proxy_setconfig(proxy) - int proxy; +proxy_setconfig(int proxy) { if (proxy == IPNY_DNS) { yysetfixeddict(dnswords); } } static void -proxy_unsetconfig() +proxy_unsetconfig(void) { yyresetdict(); } static namelist_t * -proxy_dns_add_pass(prefix, name) - char *prefix, *name; +proxy_dns_add_pass(char *prefix, char *name) { namelist_t *n; n = calloc(1, sizeof(*n)); if (n != NULL) { if (prefix == NULL || *prefix == '\0') { n->na_name = strdup(name); } else { n->na_name = malloc(strlen(name) + strlen(prefix) + 1); strcpy(n->na_name, prefix); strcat(n->na_name, name); } } return n; } static namelist_t * -proxy_dns_add_block(prefix, name) - char *prefix, *name; +proxy_dns_add_block(char *prefix, char *name) { namelist_t *n; n = calloc(1, sizeof(*n)); if (n != NULL) { if (prefix == NULL || *prefix == '\0') { n->na_name = strdup(name); } else { n->na_name = malloc(strlen(name) + strlen(prefix) + 1); strcpy(n->na_name, prefix); strcat(n->na_name, name); } n->na_value = 1; } return n; } static void -proxy_addconfig(proxy, proto, conf, list) - char *proxy, *conf; - int proto; - namelist_t *list; +proxy_addconfig(char *proxy, int proto, char *conf, namelist_t *list) { proxyrule_t *pr; pr = calloc(1, sizeof(*pr)); if (pr != NULL) { pr->pr_proto = proto; pr->pr_proxy = proxy; pr->pr_conf = conf; pr->pr_names = list; pr->pr_next = prules; prules = pr; } } static void -proxy_loadrules(fd, ioctlfunc, rules) - int fd; - ioctlfunc_t ioctlfunc; - proxyrule_t *rules; +proxy_loadrules(int fd, ioctlfunc_t ioctlfunc, proxyrule_t *rules) { proxyrule_t *pr; while ((pr = rules) != NULL) { proxy_loadconfig(fd, ioctlfunc, pr->pr_proxy, pr->pr_proto, pr->pr_conf, pr->pr_names); rules = pr->pr_next; free(pr->pr_conf); free(pr); } } static void -proxy_loadconfig(fd, ioctlfunc, proxy, proto, conf, list) - int fd; - ioctlfunc_t ioctlfunc; - char *proxy, *conf; - int proto; - namelist_t *list; +proxy_loadconfig(int fd, ioctlfunc_t ioctlfunc, char *proxy, int proto, + char *conf, namelist_t *list) { namelist_t *na; ipfobj_t obj; ap_ctl_t pcmd; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_PROXYCTL; obj.ipfo_size = sizeof(pcmd); obj.ipfo_ptr = &pcmd; while ((na = list) != NULL) { if ((opts & OPT_REMOVE) != 0) pcmd.apc_cmd = APC_CMD_DEL; else pcmd.apc_cmd = APC_CMD_ADD; pcmd.apc_dsize = strlen(na->na_name) + 1; pcmd.apc_data = na->na_name; pcmd.apc_arg = na->na_value; pcmd.apc_p = proto; strncpy(pcmd.apc_label, proxy, APR_LABELLEN); pcmd.apc_label[APR_LABELLEN - 1] = '\0'; strncpy(pcmd.apc_config, conf, APR_LABELLEN); pcmd.apc_config[APR_LABELLEN - 1] = '\0'; if ((*ioctlfunc)(fd, SIOCPROXY, (void *)&obj) == -1) { if ((opts & OPT_DONOTHING) == 0) { char msg[80]; snprintf(msg, sizeof(msg), "%d:ioctl(add/remove proxy rule)", yylineNum); ipf_perror_fd(fd, ioctlfunc, msg); return; } } list = na->na_next; free(na->na_name); free(na); } } static void -setifname(np, idx, name) - ipnat_t **np; - int idx; - char *name; +setifname(ipnat_t **np, int idx, char *name) { int pos; pos = addname(np, name); if (pos == -1) return; (*np)->in_ifnames[idx] = pos; } static int -addname(np, name) - ipnat_t **np; - char *name; +addname(ipnat_t **np, char *name) { ipnat_t *n; int nlen; int pos; nlen = strlen(name) + 1; n = realloc(*np, (*np)->in_size + nlen); if (*np == nattop) nattop = n; *np = n; if (n == NULL) return -1; if (n->in_pnext != NULL) *n->in_pnext = n; n->in_size += nlen; pos = n->in_namelen; n->in_namelen += nlen; strcpy(n->in_names + pos, name); n->in_names[n->in_namelen] = '\0'; return pos; } diff --git a/sbin/ipf/ippool/ippool.c b/sbin/ipf/ippool/ippool.c index 98666f9868fd..b339c617c3de 100644 --- a/sbin/ipf/ippool/ippool.c +++ b/sbin/ipf/ippool/ippool.c @@ -1,1145 +1,1114 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include #include #include #include # include #include #include #include #include #include #include #include #include #include #include #include # include #include "ipf.h" #include "netinet/ipl.h" #include "netinet/ip_lookup.h" #include "netinet/ip_pool.h" #include "netinet/ip_htable.h" #include "kmem.h" extern int ippool_yyparse(void); extern int ippool_yydebug; extern FILE *ippool_yyin; extern char *optarg; extern int lineNum; void usage(char *); int main(int, char **); int poolcommand(int, int, char *[]); int poolnodecommand(int, int, char *[]); int loadpoolfile(int, char *[], char *); int poollist(int, char *[]); void poollist_dead(int, char *, int, char *, char *); void poollist_live(int, char *, int, int); int poolflush(int, char *[]); int poolstats(int, char *[]); int gettype(char *, u_int *); int getrole(char *); int setnodeaddr(int, int, void *ptr, char *arg); void showpools_live(int, int, ipf_pool_stat_t *, char *); void showhashs_live(int, int, iphtstat_t *, char *); void showdstls_live(int, int, ipf_dstl_stat_t *, char *); int opts = 0; int fd = -1; int use_inet6 = 0; wordtab_t *pool_fields = NULL; int nohdrfields = 0; void -usage(prog) - char *prog; +usage(char *prog) { fprintf(stderr, "Usage:\t%s\n", prog); fprintf(stderr, "\t-a [-dnv] -m [-o ] [-t type] [-T ttl] -i [/netmask]\n"); fprintf(stderr, "\t-A [-dnv] [-m ] [-o ] [-S ] [-t ]\n"); fprintf(stderr, "\t-f [-dnuvR]\n"); fprintf(stderr, "\t-F [-dv] [-o ] [-t ]\n"); fprintf(stderr, "\t-l [-dv] [-m ] [-t ] [-o ] [-M ] [-N ]\n"); fprintf(stderr, "\t-r [-dnv] [-m ] [-o ] [-t type] -i [/netmask]\n"); fprintf(stderr, "\t-R [-dnv] [-m ] [-o ] [-t ]\n"); fprintf(stderr, "\t-s [-dtv]\n"); exit(1); } int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { int err = 1; if (argc < 2) usage(argv[0]); assigndefined(getenv("IPPOOL_PREDEFINED")); switch (getopt(argc, argv, "aAf:FlrRs")) { case 'a' : err = poolnodecommand(0, argc, argv); break; case 'A' : err = poolcommand(0, argc, argv); break; case 'f' : err = loadpoolfile(argc, argv, optarg); break; case 'F' : err = poolflush(argc, argv); break; case 'l' : err = poollist(argc, argv); break; case 'r' : err = poolnodecommand(1, argc, argv); break; case 'R' : err = poolcommand(1, argc, argv); break; case 's' : err = poolstats(argc, argv); break; default : exit(1); } if (err != 0) exit(1); return 0; } int -poolnodecommand(remove, argc, argv) - int remove, argc; - char *argv[]; +poolnodecommand(int remove, int argc, char *argv[]) { int err = 0, c, ipset, role, type = IPLT_POOL, ttl = 0; char *poolname = NULL; ip_pool_node_t pnode; iphtent_t hnode; void *ptr = &pnode; ipset = 0; role = IPL_LOGIPF; bzero((char *)&pnode, sizeof(pnode)); bzero((char *)&hnode, sizeof(hnode)); while ((c = getopt(argc, argv, "di:m:no:t:T:v")) != -1) switch (c) { case 'd' : opts |= OPT_DEBUG; ippool_yydebug++; break; case 'i' : if (setnodeaddr(type, role, ptr, optarg) == 0) ipset = 1; break; case 'm' : poolname = optarg; break; case 'n' : opts |= OPT_DONOTHING|OPT_DONTOPEN; break; case 'o' : if (ipset == 1) { fprintf(stderr, "cannot set role after ip address\n"); return -1; } role = getrole(optarg); if (role == IPL_LOGNONE) return -1; break; case 't' : if (ipset == 1) { fprintf(stderr, "cannot set type after ip address\n"); return -1; } type = gettype(optarg, NULL); switch (type) { case IPLT_NONE : fprintf(stderr, "unknown type '%s'\n", optarg); return -1; case IPLT_HASH : ptr = &hnode; break; case IPLT_POOL : default : break; } break; case 'T' : if (remove == 0) { ttl = atoi(optarg); if (ttl < 0) { fprintf(stderr, "cannot set negative ttl\n"); return -1; } } else { usage(argv[0]); } break; case 'v' : opts |= OPT_VERBOSE; break; default : usage(argv[0]); break; /* keep compiler happy */ } if (argc - 1 - optind > 0) usage(argv[0]); if (argv[optind] != NULL && ipset == 0) { if (setnodeaddr(type, role, ptr, argv[optind]) == 0) ipset = 1; } if (opts & OPT_DEBUG) fprintf(stderr, "poolnodecommand: opts = %#x\n", opts); if (ipset == 0) { fprintf(stderr, "no IP address given with -i\n"); return -1; } if (poolname == NULL) { fprintf(stderr, "poolname not given with add/remove node\n"); return -1; } switch (type) { case IPLT_POOL : if (remove == 0) err = load_poolnode(role, poolname, &pnode, ttl, ioctl); else err = remove_poolnode(role, poolname, &pnode, ioctl); break; case IPLT_HASH : if (remove == 0) err = load_hashnode(role, poolname, &hnode, ttl, ioctl); else err = remove_hashnode(role, poolname, &hnode, ioctl); break; default : break; } return err; } int -poolcommand(remove, argc, argv) - int remove, argc; - char *argv[]; +poolcommand(int remove, int argc, char *argv[]) { int type, role, c, err; char *poolname, *typearg = NULL; iphtable_t iph; ip_pool_t pool; err = 1; role = 0; type = 0; poolname = NULL; role = IPL_LOGIPF; bzero((char *)&iph, sizeof(iph)); bzero((char *)&pool, sizeof(pool)); while ((c = getopt(argc, argv, "dm:no:S:vt:")) != -1) switch (c) { case 'd' : opts |= OPT_DEBUG; ippool_yydebug++; break; case 'm' : poolname = optarg; break; case 'n' : opts |= OPT_DONOTHING|OPT_DONTOPEN; break; case 'o' : role = getrole(optarg); if (role == IPL_LOGNONE) { fprintf(stderr, "unknown role '%s'\n", optarg); return -1; } break; case 'S' : if (remove == 0) iph.iph_seed = atoi(optarg); else usage(argv[0]); break; case 't' : type = gettype(optarg, &iph.iph_type); typearg = optarg; break; case 'v' : opts |= OPT_VERBOSE; break; default : usage(argv[0]); break; /* keep compiler happy */ } if (argc - 1 - optind > 0) usage(argv[0]); if (opts & OPT_DEBUG) fprintf(stderr, "poolcommand: opts = %#x\n", opts); if (poolname == NULL) { fprintf(stderr, "poolname not given with add/remove pool\n"); return -1; } if (type == IPLT_NONE && remove == 0) { if (typearg == NULL) { fprintf(stderr, "type must be specified\n"); usage(argv[0]); } else { fprintf(stderr, "unknown type '%s'\n", typearg); } return -1; } if (type == IPLT_HASH || (type == IPLT_NONE && remove == 1)) { strncpy(iph.iph_name, poolname, sizeof(iph.iph_name)); iph.iph_name[sizeof(iph.iph_name) - 1] = '\0'; iph.iph_unit = role; } if (type == IPLT_POOL || (type == IPLT_NONE && remove == 1)) { strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name)); pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0'; pool.ipo_unit = role; } if (remove == 0) { switch (type) { case IPLT_HASH : err = load_hash(&iph, NULL, ioctl); break; case IPLT_POOL : err = load_pool(&pool, ioctl); break; } } else { switch (type) { case IPLT_HASH : err = remove_hash(&iph, ioctl); break; case IPLT_POOL : err = remove_pool(&pool, ioctl); break; case IPLT_NONE : err = 1; { int err_h, err_p; err_h = remove_hash(&iph, ioctl); err_p = remove_pool(&pool, ioctl); if (err_h == 0 || err_p == 0) err = 0; } break; } } return err; } int -loadpoolfile(argc, argv, infile) - int argc; - char *argv[], *infile; +loadpoolfile(int argc, char *argv[], char *infile) { int c; while ((c = getopt(argc, argv, "dnuvf:")) != -1) switch (c) { case 'd' : opts |= OPT_DEBUG; ippool_yydebug++; break; case 'f' : if (loadpoolfile(argc, argv, optarg) != 0) return(-1); break; case 'n' : opts |= OPT_DONOTHING|OPT_DONTOPEN; break; case 'u' : opts |= OPT_REMOVE; break; case 'v' : opts |= OPT_VERBOSE; break; default : usage(argv[0]); break; /* keep compiler happy */ } if (argc - 1 - optind > 0) usage(argv[0]); if (opts & OPT_DEBUG) fprintf(stderr, "loadpoolfile: opts = %#x\n", opts); if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) { fd = open(IPLOOKUP_NAME, O_RDWR); if (fd == -1) { perror("open(IPLOOKUP_NAME)"); exit(1); } } if (ippool_parsefile(fd, infile, ioctl) != 0) return -1; return 0; } int -poolstats(argc, argv) - int argc; - char *argv[]; +poolstats(int argc, char *argv[]) { int c, type, role; ipf_pool_stat_t plstat; ipf_dstl_stat_t dlstat; iphtstat_t htstat; iplookupop_t op; type = IPLT_ALL; role = IPL_LOGALL; bzero((char *)&op, sizeof(op)); while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1) switch (c) { case 'd' : opts |= OPT_DEBUG; break; case 'o' : role = getrole(optarg); if (role == IPL_LOGNONE) { fprintf(stderr, "unknown role '%s'\n", optarg); return -1; } break; case 't' : type = gettype(optarg, NULL); if (type != IPLT_POOL) { fprintf(stderr, "-s not supported for this type yet\n"); return -1; } break; case 'v' : opts |= OPT_VERBOSE; break; default : usage(argv[0]); break; /* keep compiler happy */ } if (argc - 1 - optind > 0) usage(argv[0]); if (opts & OPT_DEBUG) fprintf(stderr, "poolstats: opts = %#x\n", opts); if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) { fd = open(IPLOOKUP_NAME, O_RDWR); if (fd == -1) { perror("open(IPLOOKUP_NAME)"); exit(1); } } if (type == IPLT_ALL || type == IPLT_POOL) { op.iplo_type = IPLT_POOL; op.iplo_struct = &plstat; op.iplo_size = sizeof(plstat); if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) { c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { ipferror(fd, "ioctl(S0IOCLOOKUPSTAT)"); return -1; } printf("%lu\taddress pools\n", plstat.ipls_pools); printf("%lu\taddress pool nodes\n", plstat.ipls_nodes); } } if (type == IPLT_ALL || type == IPLT_HASH) { op.iplo_type = IPLT_HASH; op.iplo_struct = &htstat; op.iplo_size = sizeof(htstat); if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) { c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); return -1; } printf("%lu\thash tables\n", htstat.iphs_numtables); printf("%lu\thash table nodes\n", htstat.iphs_numnodes); printf("%lu\thash table no memory \n", htstat.iphs_nomem); } } if (type == IPLT_ALL || type == IPLT_DSTLIST) { op.iplo_type = IPLT_DSTLIST; op.iplo_struct = &dlstat; op.iplo_size = sizeof(dlstat); if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) { c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); return -1; } printf("%u\tdestination lists\n", dlstat.ipls_numlists); printf("%u\tdestination list nodes\n", dlstat.ipls_numnodes); printf("%lu\tdestination list no memory\n", dlstat.ipls_nomem); printf("%u\tdestination list zombies\n", dlstat.ipls_numdereflists); printf("%u\tdesetination list node zombies\n", dlstat.ipls_numderefnodes); } } return 0; } int -poolflush(argc, argv) - int argc; - char *argv[]; +poolflush(int argc, char *argv[]) { int c, role, type, arg; iplookupflush_t flush; arg = IPLT_ALL; type = IPLT_ALL; role = IPL_LOGALL; while ((c = getopt(argc, argv, "do:t:v")) != -1) switch (c) { case 'd' : opts |= OPT_DEBUG; break; case 'o' : role = getrole(optarg); if (role == IPL_LOGNONE) { fprintf(stderr, "unknown role '%s'\n", optarg); return -1; } break; case 't' : type = gettype(optarg, NULL); if (type == IPLT_NONE) { fprintf(stderr, "unknown type '%s'\n", optarg); return -1; } break; case 'v' : opts |= OPT_VERBOSE; break; default : usage(argv[0]); break; /* keep compiler happy */ } if (argc - optind > 0) usage(argv[0]); if (opts & OPT_DEBUG) fprintf(stderr, "poolflush: opts = %#x\n", opts); if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) { fd = open(IPLOOKUP_NAME, O_RDWR); if (fd == -1) { perror("open(IPLOOKUP_NAME)"); exit(1); } } bzero((char *)&flush, sizeof(flush)); flush.iplf_type = type; flush.iplf_unit = role; flush.iplf_arg = arg; if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) { if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) { ipferror(fd, "ioctl(SIOCLOOKUPFLUSH)"); exit(1); } } printf("%u object%s flushed\n", flush.iplf_count, (flush.iplf_count == 1) ? "" : "s"); return 0; } int -getrole(rolename) - char *rolename; +getrole(char *rolename) { int role; if (!strcasecmp(rolename, "ipf")) { role = IPL_LOGIPF; #if 0 } else if (!strcasecmp(rolename, "nat")) { role = IPL_LOGNAT; } else if (!strcasecmp(rolename, "state")) { role = IPL_LOGSTATE; } else if (!strcasecmp(rolename, "auth")) { role = IPL_LOGAUTH; } else if (!strcasecmp(rolename, "sync")) { role = IPL_LOGSYNC; } else if (!strcasecmp(rolename, "scan")) { role = IPL_LOGSCAN; } else if (!strcasecmp(rolename, "pool")) { role = IPL_LOGLOOKUP; } else if (!strcasecmp(rolename, "count")) { role = IPL_LOGCOUNT; #endif } else { role = IPL_LOGNONE; } return role; } int -gettype(typename, minor) - char *typename; - u_int *minor; +gettype(char *typename, u_int *minor) { int type; if (!strcasecmp(typename, "tree") || !strcasecmp(typename, "pool")) { type = IPLT_POOL; } else if (!strcasecmp(typename, "hash")) { type = IPLT_HASH; if (minor != NULL) *minor = IPHASH_LOOKUP; } else if (!strcasecmp(typename, "group-map")) { type = IPLT_HASH; if (minor != NULL) *minor = IPHASH_GROUPMAP; } else { type = IPLT_NONE; } return type; } int -poollist(argc, argv) - int argc; - char *argv[]; +poollist(int argc, char *argv[]) { char *kernel, *core, *poolname; int c, role, type, live_kernel; iplookupop_t op; core = NULL; kernel = NULL; live_kernel = 1; type = IPLT_ALL; poolname = NULL; role = IPL_LOGALL; while ((c = getopt(argc, argv, "dm:M:N:o:t:v")) != -1) switch (c) { case 'd' : opts |= OPT_DEBUG; break; case 'm' : poolname = optarg; break; case 'M' : live_kernel = 0; core = optarg; break; case 'N' : live_kernel = 0; kernel = optarg; break; case 'o' : role = getrole(optarg); if (role == IPL_LOGNONE) { fprintf(stderr, "unknown role '%s'\n", optarg); return -1; } break; #if 0 case 'O' : /* XXX This option does not work. This function as */ /* XXX used by state and nat can be used to format */ /* XXX output especially useful for scripting. It */ /* XXX is left here with the intention of making */ /* XXX it work for the same purpose at some point. */ pool_fields = parsefields(poolfields, optarg); break; #endif case 't' : type = gettype(optarg, NULL); if (type == IPLT_NONE) { fprintf(stderr, "unknown type '%s'\n", optarg); return -1; } break; case 'v' : opts |= OPT_VERBOSE; break; default : usage(argv[0]); break; /* keep compiler happy */ } if (argc - optind > 0) usage(argv[0]); if (opts & OPT_DEBUG) fprintf(stderr, "poollist: opts = %#x\n", opts); if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) { fd = open(IPLOOKUP_NAME, O_RDWR); if (fd == -1) { perror("open(IPLOOKUP_NAME)"); exit(1); } } bzero((char *)&op, sizeof(op)); if (poolname != NULL) { strncpy(op.iplo_name, poolname, sizeof(op.iplo_name)); op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; } op.iplo_unit = role; if (live_kernel) poollist_live(role, poolname, type, fd); else poollist_dead(role, poolname, type, kernel, core); return 0; } void -poollist_dead(role, poolname, type, kernel, core) - int role, type; - char *poolname, *kernel, *core; +poollist_dead(int role, char *poolname, int type, char *kernel, char *core) { iphtable_t *hptr; ip_pool_t *ptr; if (openkmem(kernel, core) == -1) exit(-1); if (type == IPLT_ALL || type == IPLT_POOL) { ip_pool_t *pools[IPL_LOGSIZE]; struct nlist names[2] = { { "ip_pool_list" } , { "" } }; if (nlist(kernel, names) != 1) return; bzero(&pools, sizeof(pools)); if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools))) return; if (role != IPL_LOGALL) { ptr = pools[role]; while (ptr != NULL) { ptr = printpool(ptr, kmemcpywrap, poolname, opts, pool_fields); } } else { for (role = 0; role <= IPL_LOGMAX; role++) { ptr = pools[role]; while (ptr != NULL) { ptr = printpool(ptr, kmemcpywrap, poolname, opts, pool_fields); } } role = IPL_LOGALL; } } if (type == IPLT_ALL || type == IPLT_HASH) { iphtable_t *tables[IPL_LOGSIZE]; struct nlist names[2] = { { "ipf_htables" } , { "" } }; if (nlist(kernel, names) != 1) return; bzero(&tables, sizeof(tables)); if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables))) return; if (role != IPL_LOGALL) { hptr = tables[role]; while (hptr != NULL) { hptr = printhash(hptr, kmemcpywrap, poolname, opts, pool_fields); } } else { for (role = 0; role <= IPL_LOGMAX; role++) { hptr = tables[role]; while (hptr != NULL) { hptr = printhash(hptr, kmemcpywrap, poolname, opts, pool_fields); } } } } } void -poollist_live(role, poolname, type, fd) - int role, type, fd; - char *poolname; +poollist_live(int role, char *poolname, int type, int fd) { ipf_pool_stat_t plstat; iplookupop_t op; int c; if (type == IPLT_ALL || type == IPLT_POOL) { op.iplo_type = IPLT_POOL; op.iplo_size = sizeof(plstat); op.iplo_struct = &plstat; op.iplo_name[0] = '\0'; op.iplo_arg = 0; if (role != IPL_LOGALL) { op.iplo_unit = role; c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); return; } showpools_live(fd, role, &plstat, poolname); } else { for (role = -1; role <= IPL_LOGMAX; role++) { op.iplo_unit = role; c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); return; } showpools_live(fd, role, &plstat, poolname); } role = IPL_LOGALL; } } if (type == IPLT_ALL || type == IPLT_HASH) { iphtstat_t htstat; op.iplo_type = IPLT_HASH; op.iplo_size = sizeof(htstat); op.iplo_struct = &htstat; op.iplo_name[0] = '\0'; op.iplo_arg = 0; if (role != IPL_LOGALL) { op.iplo_unit = role; c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); return; } showhashs_live(fd, role, &htstat, poolname); } else { for (role = 0; role <= IPL_LOGMAX; role++) { op.iplo_unit = role; c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); return; } showhashs_live(fd, role, &htstat, poolname); } role = IPL_LOGALL; } } if (type == IPLT_ALL || type == IPLT_DSTLIST) { ipf_dstl_stat_t dlstat; op.iplo_type = IPLT_DSTLIST; op.iplo_size = sizeof(dlstat); op.iplo_struct = &dlstat; op.iplo_name[0] = '\0'; op.iplo_arg = 0; if (role != IPL_LOGALL) { op.iplo_unit = role; c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); return; } showdstls_live(fd, role, &dlstat, poolname); } else { for (role = 0; role <= IPL_LOGMAX; role++) { op.iplo_unit = role; c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); return; } showdstls_live(fd, role, &dlstat, poolname); } role = IPL_LOGALL; } } } void -showpools_live(fd, role, plstp, poolname) - int fd, role; - ipf_pool_stat_t *plstp; - char *poolname; +showpools_live(int fd, int role, ipf_pool_stat_t *plstp, char *poolname) { ipflookupiter_t iter; ip_pool_t pool; ipfobj_t obj; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_LOOKUPITER; obj.ipfo_size = sizeof(iter); obj.ipfo_ptr = &iter; iter.ili_type = IPLT_POOL; iter.ili_otype = IPFLOOKUPITER_LIST; iter.ili_ival = IPFGENITER_LOOKUP; iter.ili_nitems = 1; iter.ili_data = &pool; iter.ili_unit = role; *iter.ili_name = '\0'; bzero((char *)&pool, sizeof(pool)); while (plstp->ipls_list[role + 1] != NULL) { if (ioctl(fd, SIOCLOOKUPITER, &obj)) { ipferror(fd, "ioctl(SIOCLOOKUPITER)"); break; } if (((pool.ipo_flags & IPOOL_DELETE) == 0) || ((opts & OPT_DEBUG) != 0)) printpool_live(&pool, fd, poolname, opts, pool_fields); plstp->ipls_list[role + 1] = pool.ipo_next; } } void -showhashs_live(fd, role, htstp, poolname) - int fd, role; - iphtstat_t *htstp; - char *poolname; +showhashs_live(int fd, int role, iphtstat_t *htstp, char *poolname) { ipflookupiter_t iter; iphtable_t table; ipfobj_t obj; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_LOOKUPITER; obj.ipfo_size = sizeof(iter); obj.ipfo_ptr = &iter; iter.ili_type = IPLT_HASH; iter.ili_otype = IPFLOOKUPITER_LIST; iter.ili_ival = IPFGENITER_LOOKUP; iter.ili_nitems = 1; iter.ili_data = &table; iter.ili_unit = role; *iter.ili_name = '\0'; while (htstp->iphs_tables != NULL) { if (ioctl(fd, SIOCLOOKUPITER, &obj)) { ipferror(fd, "ioctl(SIOCLOOKUPITER)"); break; } printhash_live(&table, fd, poolname, opts, pool_fields); htstp->iphs_tables = table.iph_next; } } void -showdstls_live(fd, role, dlstp, poolname) - int fd, role; - ipf_dstl_stat_t *dlstp; - char *poolname; +showdstls_live(int fd, int role, ipf_dstl_stat_t *dlstp, char *poolname) { ipflookupiter_t iter; ippool_dst_t table; ipfobj_t obj; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_LOOKUPITER; obj.ipfo_size = sizeof(iter); obj.ipfo_ptr = &iter; iter.ili_type = IPLT_DSTLIST; iter.ili_otype = IPFLOOKUPITER_LIST; iter.ili_ival = IPFGENITER_LOOKUP; iter.ili_nitems = 1; iter.ili_data = &table; iter.ili_unit = role; *iter.ili_name = '\0'; while (dlstp->ipls_list[role] != NULL) { if (ioctl(fd, SIOCLOOKUPITER, &obj)) { ipferror(fd, "ioctl(SIOCLOOKUPITER)"); break; } printdstl_live(&table, fd, poolname, opts, pool_fields); dlstp->ipls_list[role] = table.ipld_next; } } int setnodeaddr(int type, int role, void *ptr, char *arg) { struct in_addr mask; sa_family_t family; char *s; if (strchr(arg, ':') == NULL) { family = AF_INET; s = strchr(arg, '/'); if (s == NULL) mask.s_addr = 0xffffffff; else if (strchr(s, '.') == NULL) { if (ntomask(AF_INET, atoi(s + 1), &mask.s_addr) != 0) return -1; } else { mask.s_addr = inet_addr(s + 1); } if (s != NULL) *s = '\0'; } else { family = AF_INET6; /* XXX for now we use mask for IPv6 prefix length */ /* XXX mask should be a union with prefix */ /* XXX Currently address handling is sloppy. */ if ((s = strchr(arg, '/')) == NULL) mask.s_addr = 128; else mask.s_addr = atoi(s + 1); } if (type == IPLT_POOL) { ip_pool_node_t *node = ptr; node->ipn_addr.adf_family = family; #ifdef USE_INET6 if (node->ipn_addr.adf_family == AF_INET) { #endif node->ipn_addr.adf_len = offsetof(addrfamily_t, adf_addr) + sizeof(struct in_addr); node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg); #ifdef USE_INET6 } else { node->ipn_addr.adf_len = offsetof(addrfamily_t, adf_addr) + sizeof(struct in6_addr); inet_pton(AF_INET6, arg, &node->ipn_addr.adf_addr.in6.s6_addr); } #endif node->ipn_mask.adf_len = node->ipn_addr.adf_len; node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr; } else if (type == IPLT_HASH) { iphtent_t *node = ptr; node->ipe_family = family; node->ipe_unit = role; #ifdef USE_INET6 if (node->ipe_family == AF_INET) { #endif node->ipe_addr.in4.s_addr = inet_addr(arg); node->ipe_mask.in4.s_addr = mask.s_addr; #ifdef USE_INET6 } else { inet_pton(AF_INET6, arg, &node->ipe_addr.in6.__u6_addr.__u6_addr32); node->ipe_mask.in6.__u6_addr.__u6_addr32[0] = mask.s_addr; node->ipe_mask.in6.__u6_addr.__u6_addr32[1] = node->ipe_mask.in6.__u6_addr.__u6_addr32[2] = node->ipe_mask.in6.__u6_addr.__u6_addr32[3] = 0; } #endif } return 0; } diff --git a/sbin/ipf/ippool/ippool_y.y b/sbin/ipf/ippool/ippool_y.y index 03ee1731f24f..5ec9b6ef0083 100644 --- a/sbin/ipf/ippool/ippool_y.y +++ b/sbin/ipf/ippool/ippool_y.y @@ -1,832 +1,824 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ %{ #include #include #include #include # include #include #include #include #include #include #include #include #include #include #include #include #include "ipf.h" #include "netinet/ip_lookup.h" #include "netinet/ip_pool.h" #include "netinet/ip_htable.h" #include "netinet/ip_dstlist.h" #include "ippool_l.h" #include "kmem.h" #define YYDEBUG 1 #define YYSTACKSIZE 0x00ffffff extern int yyparse(void); extern int yydebug; extern FILE *yyin; static iphtable_t ipht; static iphtent_t iphte; static ip_pool_t iplo; static ippool_dst_t ipld; static ioctlfunc_t poolioctl = NULL; static char poolname[FR_GROUPLEN]; static iphtent_t *add_htablehosts(char *); static ip_pool_node_t *add_poolhosts(char *); static ip_pool_node_t *read_whoisfile(char *); static void setadflen(addrfamily_t *); %} %union { char *str; u_32_t num; struct in_addr ip4; struct alist_s *alist; addrfamily_t adrmsk[2]; iphtent_t *ipe; ip_pool_node_t *ipp; ipf_dstnode_t *ipd; addrfamily_t ipa; i6addr_t ip6; } %token YY_NUMBER YY_HEX %token YY_STR %token YY_IPV6 %token YY_COMMENT %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT %token YY_RANGE_OUT YY_RANGE_IN %token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT IPT_ALL %token IPT_TABLE IPT_GROUPMAP IPT_HASH IPT_SRCHASH IPT_DSTHASH %token IPT_ROLE IPT_TYPE IPT_TREE %token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME IPT_POLICY %token IPT_POOL IPT_DSTLIST IPT_ROUNDROBIN %token IPT_WEIGHTED IPT_RANDOM IPT_CONNECTION %token IPT_WHOIS IPT_FILE %type role table inout unit dstopts weighting %type ipftree range addrlist %type addrmask %type ipfgroup ipfhash hashlist hashentry %type groupentry setgrouplist grouplist %type ipaddr mask %type ipv4 %type number setgroup name %type dstentry dstentries dstlist %% file: line | assign | file line | file assign ; line: table role ipftree eol { ip_pool_node_t *n; iplo.ipo_unit = $2; iplo.ipo_list = $3; load_pool(&iplo, poolioctl); while ((n = $3) != NULL) { $3 = n->ipn_next; free(n); } resetlexer(); use_inet6 = 0; } | table role ipfhash eol { iphtent_t *h; ipht.iph_unit = $2; ipht.iph_type = IPHASH_LOOKUP; load_hash(&ipht, $3, poolioctl); while ((h = $3) != NULL) { $3 = h->ipe_next; free(h); } resetlexer(); use_inet6 = 0; } | groupmap role number ipfgroup eol { iphtent_t *h; ipht.iph_unit = $2; strncpy(ipht.iph_name, $3, sizeof(ipht.iph_name)); ipht.iph_type = IPHASH_GROUPMAP; load_hash(&ipht, $4, poolioctl); while ((h = $4) != NULL) { $4 = h->ipe_next; free(h); } resetlexer(); use_inet6 = 0; } | YY_COMMENT | poolline eol ; eol: ';' ; assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); resetlexer(); free($1); free($3); yyvarnext = 0; } ; assigning: '=' { yyvarnext = 1; } ; table: IPT_TABLE { bzero((char *)&ipht, sizeof(ipht)); bzero((char *)&iphte, sizeof(iphte)); bzero((char *)&iplo, sizeof(iplo)); bzero((char *)&ipld, sizeof(ipld)); *ipht.iph_name = '\0'; iplo.ipo_flags = IPHASH_ANON; iplo.ipo_name[0] = '\0'; } ; groupmap: IPT_GROUPMAP inout { bzero((char *)&ipht, sizeof(ipht)); bzero((char *)&iphte, sizeof(iphte)); *ipht.iph_name = '\0'; ipht.iph_unit = IPHASH_GROUPMAP; ipht.iph_flags = $2; } ; inout: IPT_IN { $$ = FR_INQUE; } | IPT_OUT { $$ = FR_OUTQUE; } ; role: IPT_ROLE '=' unit { $$ = $3; } ; unit: IPT_IPF { $$ = IPL_LOGIPF; } | IPT_NAT { $$ = IPL_LOGNAT; } | IPT_AUTH { $$ = IPL_LOGAUTH; } | IPT_COUNT { $$ = IPL_LOGCOUNT; } | IPT_ALL { $$ = IPL_LOGALL; } ; ipftree: IPT_TYPE '=' IPT_TREE number start addrlist end { strncpy(iplo.ipo_name, $4, sizeof(iplo.ipo_name)); $$ = $6; } ; ipfhash: IPT_TYPE '=' IPT_HASH number hashopts start hashlist end { strncpy(ipht.iph_name, $4, sizeof(ipht.iph_name)); $$ = $7; } ; ipfgroup: setgroup hashopts start grouplist end { iphtent_t *e; for (e = $4; e != NULL; e = e->ipe_next) if (e->ipe_group[0] == '\0') strncpy(e->ipe_group, $1, FR_GROUPLEN); $$ = $4; free($1); } | hashopts start setgrouplist end { $$ = $3; } ; number: IPT_NUM '=' YY_NUMBER { snprintf(poolname, sizeof(poolname), "%u", $3); $$ = poolname; } | IPT_NAME '=' YY_STR { strncpy(poolname, $3, FR_GROUPLEN); poolname[FR_GROUPLEN-1]='\0'; free($3); $$ = poolname; } | { $$ = ""; } ; setgroup: IPT_GROUP '=' YY_STR { char tmp[FR_GROUPLEN+1]; strncpy(tmp, $3, FR_GROUPLEN); $$ = strdup(tmp); free($3); } | IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1]; snprintf(tmp, sizeof(tmp), "%u", $3); $$ = strdup(tmp); } ; hashopts: | size | seed | size seed ; addrlist: ';' { $$ = NULL; } | range next addrlist { $$ = $1; while ($1->ipn_next != NULL) $1 = $1->ipn_next; $1->ipn_next = $3; } | range next { $$ = $1; } ; grouplist: ';' { $$ = NULL; } | groupentry next grouplist { $$ = $1; $1->ipe_next = $3; } | addrmask next grouplist { $$ = calloc(1, sizeof(iphtent_t)); $$->ipe_addr = $1[0].adf_addr; $$->ipe_mask = $1[1].adf_addr; $$->ipe_family = $1[0].adf_family; $$->ipe_next = $3; } | groupentry next { $$ = $1; } | addrmask next { $$ = calloc(1, sizeof(iphtent_t)); $$->ipe_addr = $1[0].adf_addr; $$->ipe_mask = $1[1].adf_addr; #ifdef USE_INET6 if (use_inet6) $$->ipe_family = AF_INET6; else #endif $$->ipe_family = AF_INET; } | YY_STR { $$ = add_htablehosts($1); free($1); } ; setgrouplist: ';' { $$ = NULL; } | groupentry next { $$ = $1; } | groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; } ; groupentry: addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t)); $$->ipe_addr = $1[0].adf_addr; $$->ipe_mask = $1[1].adf_addr; strncpy($$->ipe_group, $3, FR_GROUPLEN); #ifdef USE_INET6 if (use_inet6) $$->ipe_family = AF_INET6; else #endif $$->ipe_family = AF_INET; free($3); } ; range: addrmask { $$ = calloc(1, sizeof(*$$)); $$->ipn_info = 0; $$->ipn_addr = $1[0]; $$->ipn_mask = $1[1]; #ifdef USE_INET6 if (use_inet6) $$->ipn_addr.adf_family = AF_INET6; else #endif $$->ipn_addr.adf_family = AF_INET; } | '!' addrmask { $$ = calloc(1, sizeof(*$$)); $$->ipn_info = 1; $$->ipn_addr = $2[0]; $$->ipn_mask = $2[1]; #ifdef USE_INET6 if (use_inet6) $$->ipn_addr.adf_family = AF_INET6; else #endif $$->ipn_addr.adf_family = AF_INET; } | YY_STR { $$ = add_poolhosts($1); free($1); } | IPT_WHOIS IPT_FILE YY_STR { $$ = read_whoisfile($3); free($3); } ; hashlist: ';' { $$ = NULL; } | hashentry next { $$ = $1; } | hashentry next hashlist { $1->ipe_next = $3; $$ = $1; } ; hashentry: addrmask { $$ = calloc(1, sizeof(iphtent_t)); $$->ipe_addr = $1[0].adf_addr; $$->ipe_mask = $1[1].adf_addr; #ifdef USE_INET6 if (use_inet6) $$->ipe_family = AF_INET6; else #endif $$->ipe_family = AF_INET; } | YY_STR { $$ = add_htablehosts($1); free($1); } ; addrmask: ipaddr '/' mask { $$[0] = $1; setadflen(&$$[0]); $$[1] = $3; $$[1].adf_len = $$[0].adf_len; } | ipaddr { $$[0] = $1; setadflen(&$$[1]); $$[1].adf_len = $$[0].adf_len; #ifdef USE_INET6 if (use_inet6) memset(&$$[1].adf_addr, 0xff, sizeof($$[1].adf_addr.in6)); else #endif memset(&$$[1].adf_addr, 0xff, sizeof($$[1].adf_addr.in4)); } ; ipaddr: ipv4 { $$.adf_addr.in4 = $1; $$.adf_family = AF_INET; setadflen(&$$); use_inet6 = 0; } | YY_NUMBER { $$.adf_addr.in4.s_addr = htonl($1); $$.adf_family = AF_INET; setadflen(&$$); use_inet6 = 0; } | YY_IPV6 { $$.adf_addr = $1; $$.adf_family = AF_INET6; setadflen(&$$); use_inet6 = 1; } ; mask: YY_NUMBER { bzero(&$$, sizeof($$)); if (use_inet6) { if (ntomask(AF_INET6, $1, (u_32_t *)&$$.adf_addr) == -1) yyerror("bad bitmask"); } else { if (ntomask(AF_INET, $1, (u_32_t *)&$$.adf_addr.in4) == -1) yyerror("bad bitmask"); } } | ipv4 { bzero(&$$, sizeof($$)); $$.adf_addr.in4 = $1; } | YY_IPV6 { bzero(&$$, sizeof($$)); $$.adf_addr = $1; } ; size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; } ; seed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; } ; ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { yyerror("Invalid octet string for IP address"); return 0; } $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; $$.s_addr = htonl($$.s_addr); } ; next: ';' { yyexpectaddr = 1; } ; start: '{' { yyexpectaddr = 1; } ; end: '}' { yyexpectaddr = 0; } ; poolline: IPT_POOL unit '/' IPT_DSTLIST '(' name ';' dstopts ')' start dstlist end { bzero((char *)&ipld, sizeof(ipld)); strncpy(ipld.ipld_name, $6, sizeof(ipld.ipld_name)); ipld.ipld_unit = $2; ipld.ipld_policy = $8; load_dstlist(&ipld, poolioctl, $11); resetlexer(); use_inet6 = 0; free($6); } | IPT_POOL unit '/' IPT_TREE '(' name ';' ')' start addrlist end { bzero((char *)&iplo, sizeof(iplo)); strncpy(iplo.ipo_name, $6, sizeof(iplo.ipo_name)); iplo.ipo_list = $10; iplo.ipo_unit = $2; load_pool(&iplo, poolioctl); resetlexer(); use_inet6 = 0; free($6); } | IPT_POOL '(' name ';' ')' start addrlist end { bzero((char *)&iplo, sizeof(iplo)); strncpy(iplo.ipo_name, $3, sizeof(iplo.ipo_name)); iplo.ipo_list = $7; iplo.ipo_unit = IPL_LOGALL; load_pool(&iplo, poolioctl); resetlexer(); use_inet6 = 0; free($3); } | IPT_POOL unit '/' IPT_HASH '(' name ';' hashoptlist ')' start hashlist end { iphtent_t *h; bzero((char *)&ipht, sizeof(ipht)); strncpy(ipht.iph_name, $6, sizeof(ipht.iph_name)); ipht.iph_unit = $2; load_hash(&ipht, $11, poolioctl); while ((h = ipht.iph_list) != NULL) { ipht.iph_list = h->ipe_next; free(h); } resetlexer(); use_inet6 = 0; free($6); } | IPT_GROUPMAP '(' name ';' inout ';' ')' start setgrouplist end { iphtent_t *h; bzero((char *)&ipht, sizeof(ipht)); strncpy(ipht.iph_name, $3, sizeof(ipht.iph_name)); ipht.iph_type = IPHASH_GROUPMAP; ipht.iph_unit = IPL_LOGIPF; ipht.iph_flags = $5; load_hash(&ipht, $9, poolioctl); while ((h = ipht.iph_list) != NULL) { ipht.iph_list = h->ipe_next; free(h); } resetlexer(); use_inet6 = 0; free($3); } ; name: IPT_NAME YY_STR { $$ = $2; } | IPT_NUM YY_NUMBER { char name[80]; snprintf(name, sizeof(name), "%d", $2); $$ = strdup(name); } ; hashoptlist: | hashopt ';' | hashoptlist ';' hashopt ';' ; hashopt: IPT_SIZE YY_NUMBER | IPT_SEED YY_NUMBER ; dstlist: dstentries { $$ = $1; } | ';' { $$ = NULL; } ; dstentries: dstentry next { $$ = $1; } | dstentry next dstentries { $1->ipfd_next = $3; $$ = $1; } ; dstentry: YY_STR ':' ipaddr { int size = sizeof(*$$) + strlen($1) + 1; $$ = calloc(1, size); if ($$ != NULL) { $$->ipfd_dest.fd_name = strlen($1) + 1; bcopy($1, $$->ipfd_names, $$->ipfd_dest.fd_name); $$->ipfd_dest.fd_addr = $3; $$->ipfd_size = size; } free($1); } | ipaddr { $$ = calloc(1, sizeof(*$$)); if ($$ != NULL) { $$->ipfd_dest.fd_name = -1; $$->ipfd_dest.fd_addr = $1; $$->ipfd_size = sizeof(*$$); } } ; dstopts: { $$ = IPLDP_NONE; } | IPT_POLICY IPT_ROUNDROBIN ';' { $$ = IPLDP_ROUNDROBIN; } | IPT_POLICY IPT_WEIGHTED weighting ';' { $$ = $3; } | IPT_POLICY IPT_RANDOM ';' { $$ = IPLDP_RANDOM; } | IPT_POLICY IPT_HASH ';' { $$ = IPLDP_HASHED; } | IPT_POLICY IPT_SRCHASH ';' { $$ = IPLDP_SRCHASH; } | IPT_POLICY IPT_DSTHASH ';' { $$ = IPLDP_DSTHASH; } ; weighting: IPT_CONNECTION { $$ = IPLDP_CONNECTION; } ; %% static wordtab_t yywords[] = { { "all", IPT_ALL }, { "auth", IPT_AUTH }, { "connection", IPT_CONNECTION }, { "count", IPT_COUNT }, { "dst-hash", IPT_DSTHASH }, { "dstlist", IPT_DSTLIST }, { "file", IPT_FILE }, { "group", IPT_GROUP }, { "group-map", IPT_GROUPMAP }, { "hash", IPT_HASH }, { "in", IPT_IN }, { "ipf", IPT_IPF }, { "name", IPT_NAME }, { "nat", IPT_NAT }, { "number", IPT_NUM }, { "out", IPT_OUT }, { "policy", IPT_POLICY }, { "pool", IPT_POOL }, { "random", IPT_RANDOM }, { "round-robin", IPT_ROUNDROBIN }, { "role", IPT_ROLE }, { "seed", IPT_SEED }, { "size", IPT_SIZE }, { "src-hash", IPT_SRCHASH }, { "table", IPT_TABLE }, { "tree", IPT_TREE }, { "type", IPT_TYPE }, { "weighted", IPT_WEIGHTED }, { "whois", IPT_WHOIS }, { NULL, 0 } }; -int ippool_parsefile(fd, filename, iocfunc) -int fd; -char *filename; -ioctlfunc_t iocfunc; +int +ippool_parsefile(int fd, char *filename, ioctlfunc_t iocfunc) { FILE *fp = NULL; char *s; yylineNum = 1; (void) yysettab(yywords); s = getenv("YYDEBUG"); if (s) yydebug = atoi(s); else yydebug = 0; if (strcmp(filename, "-")) { fp = fopen(filename, "r"); if (!fp) { fprintf(stderr, "fopen(%s) failed: %s\n", filename, STRERROR(errno)); return -1; } } else fp = stdin; while (ippool_parsesome(fd, fp, iocfunc) == 1) ; if (fp != NULL) fclose(fp); return 0; } -int ippool_parsesome(fd, fp, iocfunc) -int fd; -FILE *fp; -ioctlfunc_t iocfunc; +int +ippool_parsesome(int fd, FILE *fp, ioctlfunc_t iocfunc) { char *s; int i; poolioctl = iocfunc; if (feof(fp)) return 0; i = fgetc(fp); if (i == EOF) return 0; if (ungetc(i, fp) == EOF) return 0; if (feof(fp)) return 0; s = getenv("YYDEBUG"); if (s) yydebug = atoi(s); else yydebug = 0; yyin = fp; yyparse(); return 1; } static iphtent_t * -add_htablehosts(url) -char *url; +add_htablehosts(char *url) { iphtent_t *htop, *hbot, *h; alist_t *a, *hlist; if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) { hlist = load_url(url); } else { use_inet6 = 0; hlist = calloc(1, sizeof(*hlist)); if (hlist == NULL) return NULL; if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) { yyerror("Unknown hostname"); } } hbot = NULL; htop = NULL; for (a = hlist; a != NULL; a = a->al_next) { h = calloc(1, sizeof(*h)); if (h == NULL) break; h->ipe_family = a->al_family; h->ipe_addr = a->al_i6addr; h->ipe_mask = a->al_i6mask; if (hbot != NULL) hbot->ipe_next = h; else htop = h; hbot = h; } alist_free(hlist); return htop; } static ip_pool_node_t * -add_poolhosts(url) -char *url; +add_poolhosts(char *url) { ip_pool_node_t *ptop, *pbot, *p; alist_t *a, *hlist; if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) { hlist = load_url(url); } else { use_inet6 = 0; hlist = calloc(1, sizeof(*hlist)); if (hlist == NULL) return NULL; if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) { yyerror("Unknown hostname"); } } pbot = NULL; ptop = NULL; for (a = hlist; a != NULL; a = a->al_next) { p = calloc(1, sizeof(*p)); if (p == NULL) break; p->ipn_mask.adf_addr = a->al_i6mask; if (a->al_family == AF_INET) { p->ipn_addr.adf_family = AF_INET; #ifdef USE_INET6 } else if (a->al_family == AF_INET6) { p->ipn_addr.adf_family = AF_INET6; #endif } setadflen(&p->ipn_addr); p->ipn_addr.adf_addr = a->al_i6addr; p->ipn_info = a->al_not; p->ipn_mask.adf_len = p->ipn_addr.adf_len; if (pbot != NULL) pbot->ipn_next = p; else ptop = p; pbot = p; } alist_free(hlist); return ptop; } ip_pool_node_t * -read_whoisfile(file) - char *file; +read_whoisfile(char *file) { ip_pool_node_t *ntop, *ipn, node, *last; char line[1024]; FILE *fp; fp = fopen(file, "r"); if (fp == NULL) return NULL; last = NULL; ntop = NULL; while (fgets(line, sizeof(line) - 1, fp) != NULL) { line[sizeof(line) - 1] = '\0'; if (parsewhoisline(line, &node.ipn_addr, &node.ipn_mask)) continue; ipn = calloc(1, sizeof(*ipn)); if (ipn == NULL) continue; ipn->ipn_addr = node.ipn_addr; ipn->ipn_mask = node.ipn_mask; if (last == NULL) ntop = ipn; else last->ipn_next = ipn; last = ipn; } fclose(fp); return ntop; } static void -setadflen(afp) - addrfamily_t *afp; +setadflen(addrfamily_t *afp) { afp->adf_len = offsetof(addrfamily_t, adf_addr); switch (afp->adf_family) { case AF_INET : afp->adf_len += sizeof(struct in_addr); break; #ifdef USE_INET6 case AF_INET6 : afp->adf_len += sizeof(struct in6_addr); break; #endif default : break; } } diff --git a/sbin/ipf/ipscan/ipscan_y.y b/sbin/ipf/ipscan/ipscan_y.y index b36b66db2b97..134dbc70f048 100644 --- a/sbin/ipf/ipscan/ipscan_y.y +++ b/sbin/ipf/ipscan/ipscan_y.y @@ -1,572 +1,569 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ %{ #include #include #include "ipf.h" #include "opts.h" #include "kmem.h" #include "ipscan_l.h" #include "netinet/ip_scan.h" #include #define YYDEBUG 1 extern char *optarg; extern void yyerror(char *); extern int yyparse(void); extern int yylex(void); extern int yydebug; extern FILE *yyin; extern int yylineNum; extern void printbuf(char *, int, int); void printent(ipscan_t *); void showlist(void); int getportnum(char *); struct in_addr gethostip(char *); struct in_addr combine(int, int, int, int); char **makepair(char *, char *); void addtag(char *, char **, char **, struct action *); int cram(char *, char *); void usage(char *); int main(int, char **); int opts = 0; int fd = -1; %} %union { char *str; char **astr; u_32_t num; struct in_addr ipa; struct action act; union i6addr ip6; } %type tag %type action redirect result %type ipaddr %type portnum %type matchup onehalf twohalves %token YY_NUMBER YY_HEX %token YY_STR %token YY_COMMENT %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT %token YY_RANGE_OUT YY_RANGE_IN %token YY_IPV6 %token IPSL_START IPSL_STARTGROUP IPSL_CONTENT %token IPSL_CLOSE IPSL_TRACK IPSL_EOF IPSL_REDIRECT IPSL_ELSE %% file: line ';' | assign ';' | file line ';' | file assign ';' | YY_COMMENT ; line: IPSL_START dline | IPSL_STARTGROUP gline | IPSL_CONTENT oline ; dline: cline { resetlexer(); } | sline { resetlexer(); } | csline { resetlexer(); } ; gline: YY_STR ':' glist '=' action ; oline: cline | sline | csline ; assign: YY_STR assigning YY_STR { set_variable($1, $3); resetlexer(); free($1); free($3); yyvarnext = 0; } ; assigning: '=' { yyvarnext = 1; } ; cline: tag ':' matchup '=' action { addtag($1, $3, NULL, &$5); } ; sline: tag ':' '(' ')' ',' matchup '=' action { addtag($1, NULL, $6, &$8); } ; csline: tag ':' matchup ',' matchup '=' action { addtag($1, $3, $5, &$7); } ; glist: YY_STR | glist ',' YY_STR ; tag: YY_STR { $$ = $1; } ; matchup: onehalf { $$ = $1; } | twohalves { $$ = $1; } ; action: result { $$.act_val = $1.act_val; $$.act_ip = $1.act_ip; $$.act_port = $1.act_port; } | result IPSL_ELSE result { $$.act_val = $1.act_val; $$.act_else = $3.act_val; if ($1.act_val == IPSL_REDIRECT) { $$.act_ip = $1.act_ip; $$.act_port = $1.act_port; } if ($3.act_val == IPSL_REDIRECT) { $$.act_eip = $3.act_eip; $$.act_eport = $3.act_eport; } } result: IPSL_CLOSE { $$.act_val = IPSL_CLOSE; } | IPSL_TRACK { $$.act_val = IPSL_TRACK; } | redirect { $$.act_val = IPSL_REDIRECT; $$.act_ip = $1.act_ip; $$.act_port = $1.act_port; } ; onehalf: '(' YY_STR ')' { $$ = makepair($2, NULL); } ; twohalves: '(' YY_STR ',' YY_STR ')' { $$ = makepair($2, $4); } ; redirect: IPSL_REDIRECT '(' ipaddr ')' { $$.act_ip = $3; $$.act_port = 0; } | IPSL_REDIRECT '(' ipaddr ',' portnum ')' { $$.act_ip = $3; $$.act_port = $5; } ; ipaddr: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER { $$ = combine($1,$3,$5,$7); } | YY_STR { $$ = gethostip($1); free($1); } ; portnum: YY_NUMBER { $$ = htons($1); } | YY_STR { $$ = getportnum($1); free($1); } ; %% static struct wordtab yywords[] = { { "close", IPSL_CLOSE }, { "content", IPSL_CONTENT }, { "else", IPSL_ELSE }, { "start-group", IPSL_STARTGROUP }, { "redirect", IPSL_REDIRECT }, { "start", IPSL_START }, { "track", IPSL_TRACK }, { NULL, 0 } }; -int cram(dst, src) -char *dst; -char *src; +int +cram(char *dst, char *src) { char c, *s, *t, *u; int i, j, k; c = *src; s = src + 1; t = strchr(s, c); *t = '\0'; for (u = dst, i = 0; (i <= ISC_TLEN) && (s < t); ) { c = *s++; if (c == '\\') { if (s >= t) break; j = k = 0; do { c = *s++; if (j && (!ISDIGIT(c) || (c > '7') || (k >= 248))) { *u++ = k, i++; j = k = 0; s--; break; } i++; if (ISALPHA(c) || (c > '7')) { switch (c) { case 'n' : *u++ = '\n'; break; case 'r' : *u++ = '\r'; break; case 't' : *u++ = '\t'; break; default : *u++ = c; break; } } else if (ISDIGIT(c)) { j = 1; k <<= 3; k |= (c - '0'); i--; } else *u++ = c; } while ((i <= ISC_TLEN) && (s <= t) && (j > 0)); } else *u++ = c, i++; } return i; } -void printent(isc) -ipscan_t *isc; +void +printent(ipscan_t *isc) { char buf[ISC_TLEN+1]; u_char *u; int i, j; buf[ISC_TLEN] = '\0'; bcopy(isc->ipsc_ctxt, buf, ISC_TLEN); printf("%s : (\"", isc->ipsc_tag); printbuf(isc->ipsc_ctxt, isc->ipsc_clen, 0); bcopy(isc->ipsc_cmsk, buf, ISC_TLEN); printf("\", \"%s\"), (\"", buf); printbuf(isc->ipsc_stxt, isc->ipsc_slen, 0); bcopy(isc->ipsc_smsk, buf, ISC_TLEN); printf("\", \"%s\") = ", buf); switch (isc->ipsc_action) { case ISC_A_TRACK : printf("track"); break; case ISC_A_REDIRECT : printf("redirect"); printf("(%s", inet_ntoa(isc->ipsc_ip)); if (isc->ipsc_port) printf(",%d", isc->ipsc_port); printf(")"); break; case ISC_A_CLOSE : printf("close"); break; default : break; } if (isc->ipsc_else != ISC_A_NONE) { printf(" else "); switch (isc->ipsc_else) { case ISC_A_TRACK : printf("track"); break; case ISC_A_REDIRECT : printf("redirect"); printf("(%s", inet_ntoa(isc->ipsc_eip)); if (isc->ipsc_eport) printf(",%d", isc->ipsc_eport); printf(")"); break; case ISC_A_CLOSE : printf("close"); break; default : break; } } printf("\n"); if (opts & OPT_DEBUG) { for (u = (u_char *)isc, i = sizeof(*isc); i; ) { printf("#"); for (j = 32; (j > 0) && (i > 0); j--, i--) printf("%s%02x", (j & 7) ? "" : " ", *u++); printf("\n"); } } if (opts & OPT_VERBOSE) { printf("# hits %d active %d fref %d sref %d\n", isc->ipsc_hits, isc->ipsc_active, isc->ipsc_fref, isc->ipsc_sref); } } -void addtag(tstr, cp, sp, act) -char *tstr; -char **cp, **sp; -struct action *act; +void +addtag(char *tstr, char **cp, char **sp, struct action *act) { ipscan_t isc, *iscp; bzero((char *)&isc, sizeof(isc)); strncpy(isc.ipsc_tag, tstr, sizeof(isc.ipsc_tag)); isc.ipsc_tag[sizeof(isc.ipsc_tag) - 1] = '\0'; if (cp) { isc.ipsc_clen = cram(isc.ipsc_ctxt, cp[0]); if (cp[1]) { if (cram(isc.ipsc_cmsk, cp[1]) != isc.ipsc_clen) { fprintf(stderr, "client text/mask strings different length\n"); return; } } } if (sp) { isc.ipsc_slen = cram(isc.ipsc_stxt, sp[0]); if (sp[1]) { if (cram(isc.ipsc_smsk, sp[1]) != isc.ipsc_slen) { fprintf(stderr, "server text/mask strings different length\n"); return; } } } if (act->act_val == IPSL_CLOSE) { isc.ipsc_action = ISC_A_CLOSE; } else if (act->act_val == IPSL_TRACK) { isc.ipsc_action = ISC_A_TRACK; } else if (act->act_val == IPSL_REDIRECT) { isc.ipsc_action = ISC_A_REDIRECT; isc.ipsc_ip = act->act_ip; isc.ipsc_port = act->act_port; fprintf(stderr, "%d: redirect unsupported\n", yylineNum + 1); } if (act->act_else == IPSL_CLOSE) { isc.ipsc_else = ISC_A_CLOSE; } else if (act->act_else == IPSL_TRACK) { isc.ipsc_else = ISC_A_TRACK; } else if (act->act_else == IPSL_REDIRECT) { isc.ipsc_else = ISC_A_REDIRECT; isc.ipsc_eip = act->act_eip; isc.ipsc_eport = act->act_eport; fprintf(stderr, "%d: redirect unsupported\n", yylineNum + 1); } if (!(opts & OPT_DONOTHING)) { iscp = &isc; if (opts & OPT_REMOVE) { if (ioctl(fd, SIOCRMSCA, &iscp) == -1) perror("SIOCADSCA"); } else { if (ioctl(fd, SIOCADSCA, &iscp) == -1) perror("SIOCADSCA"); } } if (opts & OPT_VERBOSE) printent(&isc); } -char **makepair(s1, s2) -char *s1, *s2; +char ** +makepair(char *s1, char *s2) { char **a; a = malloc(sizeof(char *) * 2); a[0] = s1; a[1] = s2; return a; } -struct in_addr combine(a1, a2, a3, a4) -int a1, a2, a3, a4; +struct in_addr +combine(int a1, int a2, int a3, int a4) { struct in_addr in; a1 &= 0xff; in.s_addr = a1 << 24; a2 &= 0xff; in.s_addr |= (a2 << 16); a3 &= 0xff; in.s_addr |= (a3 << 8); a4 &= 0xff; in.s_addr |= a4; in.s_addr = htonl(in.s_addr); return in; } -struct in_addr gethostip(host) -char *host; +struct in_addr +gethostip(char *host) { struct hostent *hp; struct in_addr in; in.s_addr = 0; hp = gethostbyname(host); if (!hp) return in; bcopy(hp->h_addr, (char *)&in, sizeof(in)); return in; } -int getportnum(port) -char *port; +int +getportnum(char *port) { struct servent *s; s = getservbyname(port, "tcp"); if (s == NULL) return -1; return s->s_port; } -void showlist() +void +showlist(void) { ipscanstat_t ipsc, *ipscp = &ipsc; ipscan_t isc; if (ioctl(fd, SIOCGSCST, &ipscp) == -1) perror("ioctl(SIOCGSCST)"); else if (opts & OPT_SHOWLIST) { while (ipsc.iscs_list != NULL) { if (kmemcpy((char *)&isc, (u_long)ipsc.iscs_list, sizeof(isc)) == -1) { perror("kmemcpy"); break; } else { printent(&isc); ipsc.iscs_list = isc.ipsc_next; } } } else { printf("scan entries loaded\t%d\n", ipsc.iscs_entries); printf("scan entries matches\t%ld\n", ipsc.iscs_acted); printf("negative matches\t%ld\n", ipsc.iscs_else); } } -void usage(prog) -char *prog; +void +usage(char *prog) { fprintf(stderr, "Usage:\t%s [-dnrv] -f \n", prog); fprintf(stderr, "\t%s [-dlv]\n", prog); exit(1); } -int main(argc, argv) -int argc; -char *argv[]; +int +main(int argc, char *argv[]) { FILE *fp = NULL; int c; (void) yysettab(yywords); if (argc < 2) usage(argv[0]); while ((c = getopt(argc, argv, "df:lnrsv")) != -1) switch (c) { case 'd' : opts |= OPT_DEBUG; yydebug++; break; case 'f' : if (!strcmp(optarg, "-")) fp = stdin; else { fp = fopen(optarg, "r"); if (!fp) { perror("open"); exit(1); } } yyin = fp; break; case 'l' : opts |= OPT_SHOWLIST; break; case 'n' : opts |= OPT_DONOTHING; break; case 'r' : opts |= OPT_REMOVE; break; case 's' : opts |= OPT_STAT; break; case 'v' : opts |= OPT_VERBOSE; break; } if (!(opts & OPT_DONOTHING)) { fd = open(IPL_SCAN, O_RDWR); if (fd == -1) { perror("open(IPL_SCAN)"); exit(1); } } if (fp != NULL) { yylineNum = 1; while (!feof(fp)) yyparse(); fclose(fp); exit(0); } if (opts & (OPT_SHOWLIST|OPT_STAT)) { showlist(); exit(0); } exit(1); } diff --git a/sbin/ipf/ipsend/44arp.c b/sbin/ipf/ipsend/44arp.c index 80521ad15084..9f82ed6a741d 100644 --- a/sbin/ipf/ipsend/44arp.c +++ b/sbin/ipf/ipsend/44arp.c @@ -1,118 +1,116 @@ /* $FreeBSD$ */ /* * Based upon 4.4BSD's /usr/sbin/arp */ #include #include #include #include #include #include #include # include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipsend.h" #include "iplang/iplang.h" /* * lookup host and return * its IP address in address * (4 bytes) */ -int resolve(host, address) - char *host, *address; +int resolve(char *host, char *address) { struct hostent *hp; u_long add; add = inet_addr(host); if (add == -1) { if (!(hp = gethostbyname(host))) { fprintf(stderr, "unknown host: %s\n", host); return -1; } bcopy((char *)hp->h_addr, (char *)address, 4); return 0; } bcopy((char*)&add, address, 4); return 0; } -int arp(addr, eaddr) - char *addr, *eaddr; +int arp(char *addr, char *eaddr) { int mib[6]; size_t needed; char *lim, *buf, *next; struct rt_msghdr *rtm; struct sockaddr_in *sin; struct sockaddr_dl *sdl; #ifdef IPSEND if (arp_getipv4(addr, ether) == 0) return 0; #endif if (!addr) return -1; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = AF_INET; mib[4] = NET_RT_FLAGS; #ifdef RTF_LLINFO mib[5] = RTF_LLINFO; #else mib[5] = 0; #endif if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) { perror("route-sysctl-estimate"); exit(-1); } if ((buf = malloc(needed)) == NULL) { perror("malloc"); exit(-1); } if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) { perror("actual retrieval of routing table"); exit(-1); } lim = buf + needed; for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next; sin = (struct sockaddr_in *)(rtm + 1); sdl = (struct sockaddr_dl *)(sin + 1); if (!bcmp(addr, (char *)&sin->sin_addr, sizeof(struct in_addr))) { bcopy(LLADDR(sdl), eaddr, sdl->sdl_alen); return 0; } } return -1; } diff --git a/sbin/ipf/ipsend/arp.c b/sbin/ipf/ipsend/arp.c index 31b70d3e8987..e6bbedb9ec50 100644 --- a/sbin/ipf/ipsend/arp.c +++ b/sbin/ipf/ipsend/arp.c @@ -1,135 +1,134 @@ /* $FreeBSD$ */ /* * arp.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) static const char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include # include #include #include #include #include #include # include #include #include #include #include #include #include #include #include "ipsend.h" #include "iplang/iplang.h" /* * lookup host and return * its IP address in address * (4 bytes) */ -int resolve(host, address) - char *host, *address; +int resolve(char *host, char *address) { struct hostent *hp; u_long add; add = inet_addr(host); if (add == -1) { if (!(hp = gethostbyname(host))) { fprintf(stderr, "unknown host: %s\n", host); return -1; } bcopy((char *)hp->h_addr, (char *)address, 4); return 0; } bcopy((char*)&add, address, 4); return 0; } /* * ARP for the MAC address corresponding * to the IP address. This taken from * some BSD program, I cant remember which. */ int arp(ip, ether) char *ip; char *ether; { static int sfd = -1; static char ethersave[6], ipsave[4]; struct arpreq ar; struct sockaddr_in *sin, san; struct hostent *hp; int fd; #ifdef IPSEND if (arp_getipv4(ip, ether) == 0) return 0; #endif if (!bcmp(ipsave, ip, 4)) { bcopy(ethersave, ether, 6); return 0; } fd = -1; bzero((char *)&ar, sizeof(ar)); sin = (struct sockaddr_in *)&ar.arp_pa; sin->sin_family = AF_INET; bcopy(ip, (char *)&sin->sin_addr.s_addr, 4); if ((hp = gethostbyaddr(ip, 4, AF_INET))) # if SOLARIS && (SOLARIS2 >= 10) if (!(ether_hostton(hp->h_name, (struct ether_addr *)ether))) # else if (!(ether_hostton(hp->h_name, ether))) # endif goto savearp; if (sfd == -1) if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("arp: socket"); return -1; } tryagain: if (ioctl(sfd, SIOCGARP, (caddr_t)&ar) == -1) { if (fd == -1) { bzero((char *)&san, sizeof(san)); san.sin_family = AF_INET; san.sin_port = htons(1); bcopy(ip, &san.sin_addr.s_addr, 4); fd = socket(AF_INET, SOCK_DGRAM, 0); (void) sendto(fd, ip, 4, 0, (struct sockaddr *)&san, sizeof(san)); sleep(1); (void) close(fd); goto tryagain; } fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); if (errno != ENXIO) perror("SIOCGARP"); return -1; } if ((ar.arp_ha.sa_data[0] == 0) && (ar.arp_ha.sa_data[1] == 0) && (ar.arp_ha.sa_data[2] == 0) && (ar.arp_ha.sa_data[3] == 0) && (ar.arp_ha.sa_data[4] == 0) && (ar.arp_ha.sa_data[5] == 0)) { fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); return -1; } bcopy(ar.arp_ha.sa_data, ether, 6); savearp: bcopy(ether, ethersave, 6); bcopy(ip, ipsave, 4); return 0; } diff --git a/sbin/ipf/ipsend/dlcommon.c b/sbin/ipf/ipsend/dlcommon.c index efb82df9ad32..86554660240d 100644 --- a/sbin/ipf/ipsend/dlcommon.c +++ b/sbin/ipf/ipsend/dlcommon.c @@ -1,1379 +1,1283 @@ /* $FreeBSD$ */ /* * Common (shared) DLPI test routines. * Mostly pretty boring boilerplate sorta stuff. * These can be split into individual library routines later * but it's just convenient to keep them in a single file * while they're being developed. * * Not supported: * Connection Oriented stuff * QOS stuff */ /* typedef unsigned long ulong; */ #include #include #include # include #include #include #include #include "dltest.h" #define CASERET(s) case s: return ("s") char *dlprim(); char *dlstate(); char *dlerrno(); char *dlpromisclevel(); char *dlservicemode(); char *dlstyle(); char *dlmactype(); void -dlinforeq(fd) - int fd; +dlinforeq(int fd) { dl_info_req_t info_req; struct strbuf ctl; int flags; info_req.dl_primitive = DL_INFO_REQ; ctl.maxlen = 0; ctl.len = sizeof (info_req); ctl.buf = (char *) &info_req; flags = RS_HIPRI; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlinforeq: putmsg"); } void -dlinfoack(fd, bufp) - int fd; - char *bufp; +dlinfoack(int fd, char *bufp) { union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = MAXDLBUF; ctl.len = 0; ctl.buf = bufp; strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlinfoack"); dlp = (union DL_primitives *) ctl.buf; expecting(DL_INFO_ACK, dlp); if (ctl.len < sizeof (dl_info_ack_t)) err("dlinfoack: response ctl.len too short: %d", ctl.len); if (flags != RS_HIPRI) err("dlinfoack: DL_INFO_ACK was not M_PCPROTO"); if (ctl.len < sizeof (dl_info_ack_t)) err("dlinfoack: short response ctl.len: %d", ctl.len); } void -dlattachreq(fd, ppa) - int fd; - u_long ppa; +dlattachreq(int fd, u_long ppa) { dl_attach_req_t attach_req; struct strbuf ctl; int flags; attach_req.dl_primitive = DL_ATTACH_REQ; attach_req.dl_ppa = ppa; ctl.maxlen = 0; ctl.len = sizeof (attach_req); ctl.buf = (char *) &attach_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlattachreq: putmsg"); } void -dlenabmultireq(fd, addr, length) - int fd; - char *addr; - int length; +dlenabmultireq(int fd, char *addr, int length) { long buf[MAXDLBUF]; union DL_primitives *dlp; struct strbuf ctl; int flags; dlp = (union DL_primitives*) buf; dlp->enabmulti_req.dl_primitive = DL_ENABMULTI_REQ; dlp->enabmulti_req.dl_addr_length = length; dlp->enabmulti_req.dl_addr_offset = sizeof (dl_enabmulti_req_t); (void) memcpy((char*)OFFADDR(buf, sizeof (dl_enabmulti_req_t)), addr, length); ctl.maxlen = 0; ctl.len = sizeof (dl_enabmulti_req_t) + length; ctl.buf = (char*) buf; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlenabmultireq: putmsg"); } void -dldisabmultireq(fd, addr, length) - int fd; - char *addr; - int length; +dldisabmultireq(int fd, char *addr, int length) { long buf[MAXDLBUF]; union DL_primitives *dlp; struct strbuf ctl; int flags; dlp = (union DL_primitives*) buf; dlp->disabmulti_req.dl_primitive = DL_ENABMULTI_REQ; dlp->disabmulti_req.dl_addr_length = length; dlp->disabmulti_req.dl_addr_offset = sizeof (dl_disabmulti_req_t); (void) memcpy((char*)OFFADDR(buf, sizeof (dl_disabmulti_req_t)), addr, length); ctl.maxlen = 0; ctl.len = sizeof (dl_disabmulti_req_t) + length; ctl.buf = (char*) buf; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dldisabmultireq: putmsg"); } void -dlpromisconreq(fd, level) - int fd; - u_long level; +dlpromisconreq(int fd, u_long level) { dl_promiscon_req_t promiscon_req; struct strbuf ctl; int flags; promiscon_req.dl_primitive = DL_PROMISCON_REQ; promiscon_req.dl_level = level; ctl.maxlen = 0; ctl.len = sizeof (promiscon_req); ctl.buf = (char *) &promiscon_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlpromiscon: putmsg"); } void -dlpromiscoff(fd, level) - int fd; - u_long level; +dlpromiscoff(int fd, u_long level) { dl_promiscoff_req_t promiscoff_req; struct strbuf ctl; int flags; promiscoff_req.dl_primitive = DL_PROMISCOFF_REQ; promiscoff_req.dl_level = level; ctl.maxlen = 0; ctl.len = sizeof (promiscoff_req); ctl.buf = (char *) &promiscoff_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlpromiscoff: putmsg"); } void -dlphysaddrreq(fd, addrtype) - int fd; - u_long addrtype; +dlphysaddrreq(int fd, u_long addrtype) { dl_phys_addr_req_t phys_addr_req; struct strbuf ctl; int flags; phys_addr_req.dl_primitive = DL_PHYS_ADDR_REQ; phys_addr_req.dl_addr_type = addrtype; ctl.maxlen = 0; ctl.len = sizeof (phys_addr_req); ctl.buf = (char *) &phys_addr_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlphysaddrreq: putmsg"); } void -dlsetphysaddrreq(fd, addr, length) - int fd; - char *addr; - int length; +dlsetphysaddrreq(int fd, char *addr, int length) { long buf[MAXDLBUF]; union DL_primitives *dlp; struct strbuf ctl; int flags; dlp = (union DL_primitives*) buf; dlp->set_physaddr_req.dl_primitive = DL_ENABMULTI_REQ; dlp->set_physaddr_req.dl_addr_length = length; dlp->set_physaddr_req.dl_addr_offset = sizeof (dl_set_phys_addr_req_t); (void) memcpy((char*)OFFADDR(buf, sizeof (dl_set_phys_addr_req_t)), addr, length); ctl.maxlen = 0; ctl.len = sizeof (dl_set_phys_addr_req_t) + length; ctl.buf = (char*) buf; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlsetphysaddrreq: putmsg"); } void -dldetachreq(fd) - int fd; +dldetachreq(int fd) { dl_detach_req_t detach_req; struct strbuf ctl; int flags; detach_req.dl_primitive = DL_DETACH_REQ; ctl.maxlen = 0; ctl.len = sizeof (detach_req); ctl.buf = (char *) &detach_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dldetachreq: putmsg"); } void -dlbindreq(fd, sap, max_conind, service_mode, conn_mgmt, xidtest) - int fd; - u_long sap; - u_long max_conind; - u_long service_mode; - u_long conn_mgmt; - u_long xidtest; +dlbindreq(int fd, u_long sap, u_long max_conind, u_long service_mode, + u_long conn_mgmt, u_long xidtest) { dl_bind_req_t bind_req; struct strbuf ctl; int flags; bind_req.dl_primitive = DL_BIND_REQ; bind_req.dl_sap = sap; bind_req.dl_max_conind = max_conind; bind_req.dl_service_mode = service_mode; bind_req.dl_conn_mgmt = conn_mgmt; bind_req.dl_xidtest_flg = xidtest; ctl.maxlen = 0; ctl.len = sizeof (bind_req); ctl.buf = (char *) &bind_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlbindreq: putmsg"); } void -dlunitdatareq(fd, addrp, addrlen, minpri, maxpri, datap, datalen) - int fd; - u_char *addrp; - int addrlen; - u_long minpri, maxpri; - u_char *datap; - int datalen; +dlunitdatareq(int fd, u_char *addrp, int addrlen, u_long minpri, + u_long maxpri, u_char *datap, int datalen) { long buf[MAXDLBUF]; union DL_primitives *dlp; struct strbuf data, ctl; dlp = (union DL_primitives*) buf; dlp->unitdata_req.dl_primitive = DL_UNITDATA_REQ; dlp->unitdata_req.dl_dest_addr_length = addrlen; dlp->unitdata_req.dl_dest_addr_offset = sizeof (dl_unitdata_req_t); dlp->unitdata_req.dl_priority.dl_min = minpri; dlp->unitdata_req.dl_priority.dl_max = maxpri; (void) memcpy(OFFADDR(dlp, sizeof (dl_unitdata_req_t)), addrp, addrlen); ctl.maxlen = 0; ctl.len = sizeof (dl_unitdata_req_t) + addrlen; ctl.buf = (char *) buf; data.maxlen = 0; data.len = datalen; data.buf = (char *) datap; if (putmsg(fd, &ctl, &data, 0) < 0) syserr("dlunitdatareq: putmsg"); } void -dlunbindreq(fd) - int fd; +dlunbindreq(int fd) { dl_unbind_req_t unbind_req; struct strbuf ctl; int flags; unbind_req.dl_primitive = DL_UNBIND_REQ; ctl.maxlen = 0; ctl.len = sizeof (unbind_req); ctl.buf = (char *) &unbind_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlunbindreq: putmsg"); } void -dlokack(fd, bufp) - int fd; - char *bufp; +dlokack(int fd, char *bufp) { union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = MAXDLBUF; ctl.len = 0; ctl.buf = bufp; strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlokack"); dlp = (union DL_primitives *) ctl.buf; expecting(DL_OK_ACK, dlp); if (ctl.len < sizeof (dl_ok_ack_t)) err("dlokack: response ctl.len too short: %d", ctl.len); if (flags != RS_HIPRI) err("dlokack: DL_OK_ACK was not M_PCPROTO"); if (ctl.len < sizeof (dl_ok_ack_t)) err("dlokack: short response ctl.len: %d", ctl.len); } void -dlerrorack(fd, bufp) - int fd; - char *bufp; +dlerrorack(int fd, char *bufp) { union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = MAXDLBUF; ctl.len = 0; ctl.buf = bufp; strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlerrorack"); dlp = (union DL_primitives *) ctl.buf; expecting(DL_ERROR_ACK, dlp); if (ctl.len < sizeof (dl_error_ack_t)) err("dlerrorack: response ctl.len too short: %d", ctl.len); if (flags != RS_HIPRI) err("dlerrorack: DL_OK_ACK was not M_PCPROTO"); if (ctl.len < sizeof (dl_error_ack_t)) err("dlerrorack: short response ctl.len: %d", ctl.len); } void -dlbindack(fd, bufp) - int fd; - char *bufp; +dlbindack(int fd, char *bufp) { union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = MAXDLBUF; ctl.len = 0; ctl.buf = bufp; strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlbindack"); dlp = (union DL_primitives *) ctl.buf; expecting(DL_BIND_ACK, dlp); if (flags != RS_HIPRI) err("dlbindack: DL_OK_ACK was not M_PCPROTO"); if (ctl.len < sizeof (dl_bind_ack_t)) err("dlbindack: short response ctl.len: %d", ctl.len); } void -dlphysaddrack(fd, bufp) - int fd; - char *bufp; +dlphysaddrack(int fd, char *bufp) { union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = MAXDLBUF; ctl.len = 0; ctl.buf = bufp; strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlphysaddrack"); dlp = (union DL_primitives *) ctl.buf; expecting(DL_PHYS_ADDR_ACK, dlp); if (flags != RS_HIPRI) err("dlbindack: DL_OK_ACK was not M_PCPROTO"); if (ctl.len < sizeof (dl_phys_addr_ack_t)) err("dlphysaddrack: short response ctl.len: %d", ctl.len); } void -sigalrm() +sigalrm(void) { (void) err("sigalrm: TIMEOUT"); } -strgetmsg(fd, ctlp, datap, flagsp, caller) - int fd; - struct strbuf *ctlp, *datap; - int *flagsp; - char *caller; +strgetmsg(int fd, struct strbuf *ctlp, struct strbuf *datap, int *flagsp, + char *caller) { int rc; static char errmsg[80]; /* * Start timer. */ (void) signal(SIGALRM, sigalrm); if (alarm(MAXWAIT) < 0) { (void) snprintf(errmsg, sizeof(errmsg), "%s: alarm", caller); syserr(errmsg); } /* * Set flags argument and issue getmsg(). */ *flagsp = 0; if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) { (void) snprintf(errmsg, sizeof(errmsg), "%s: getmsg", caller); syserr(errmsg); } /* * Stop timer. */ if (alarm(0) < 0) { (void) snprintf(errmsg, sizeof(errmsg), "%s: alarm", caller); syserr(errmsg); } /* * Check for MOREDATA and/or MORECTL. */ if ((rc & (MORECTL | MOREDATA)) == (MORECTL | MOREDATA)) err("%s: MORECTL|MOREDATA", caller); if (rc & MORECTL) err("%s: MORECTL", caller); if (rc & MOREDATA) err("%s: MOREDATA", caller); /* * Check for at least sizeof (long) control data portion. */ if (ctlp->len < sizeof (long)) err("getmsg: control portion length < sizeof (long): %d", ctlp->len); } -expecting(prim, dlp) - int prim; - union DL_primitives *dlp; +expecting(int prim, union DL_primitives *dlp) { if (dlp->dl_primitive != (u_long)prim) { printdlprim(dlp); err("expected %s got %s", dlprim(prim), dlprim(dlp->dl_primitive)); exit(1); } } /* * Print any DLPI msg in human readable format. */ -printdlprim(dlp) - union DL_primitives *dlp; +printdlprim(union DL_primitives *dlp) { switch (dlp->dl_primitive) { case DL_INFO_REQ: printdlinforeq(dlp); break; case DL_INFO_ACK: printdlinfoack(dlp); break; case DL_ATTACH_REQ: printdlattachreq(dlp); break; case DL_OK_ACK: printdlokack(dlp); break; case DL_ERROR_ACK: printdlerrorack(dlp); break; case DL_DETACH_REQ: printdldetachreq(dlp); break; case DL_BIND_REQ: printdlbindreq(dlp); break; case DL_BIND_ACK: printdlbindack(dlp); break; case DL_UNBIND_REQ: printdlunbindreq(dlp); break; case DL_SUBS_BIND_REQ: printdlsubsbindreq(dlp); break; case DL_SUBS_BIND_ACK: printdlsubsbindack(dlp); break; case DL_SUBS_UNBIND_REQ: printdlsubsunbindreq(dlp); break; case DL_ENABMULTI_REQ: printdlenabmultireq(dlp); break; case DL_DISABMULTI_REQ: printdldisabmultireq(dlp); break; case DL_PROMISCON_REQ: printdlpromisconreq(dlp); break; case DL_PROMISCOFF_REQ: printdlpromiscoffreq(dlp); break; case DL_UNITDATA_REQ: printdlunitdatareq(dlp); break; case DL_UNITDATA_IND: printdlunitdataind(dlp); break; case DL_UDERROR_IND: printdluderrorind(dlp); break; case DL_UDQOS_REQ: printdludqosreq(dlp); break; case DL_PHYS_ADDR_REQ: printdlphysaddrreq(dlp); break; case DL_PHYS_ADDR_ACK: printdlphysaddrack(dlp); break; case DL_SET_PHYS_ADDR_REQ: printdlsetphysaddrreq(dlp); break; default: err("printdlprim: unknown primitive type 0x%x", dlp->dl_primitive); break; } } /* ARGSUSED */ -printdlinforeq(dlp) - union DL_primitives *dlp; +printdlinforeq(union DL_primitives *dlp) { (void) printf("DL_INFO_REQ\n"); } -printdlinfoack(dlp) - union DL_primitives *dlp; +printdlinfoack(union DL_primitives *dlp) { u_char addr[MAXDLADDR]; u_char brdcst[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->info_ack.dl_addr_offset), dlp->info_ack.dl_addr_length, addr); addrtostring(OFFADDR(dlp, dlp->info_ack.dl_brdcst_addr_offset), dlp->info_ack.dl_brdcst_addr_length, brdcst); (void) printf("DL_INFO_ACK: max_sdu %d min_sdu %d\n", dlp->info_ack.dl_max_sdu, dlp->info_ack.dl_min_sdu); (void) printf("addr_length %d mac_type %s current_state %s\n", dlp->info_ack.dl_addr_length, dlmactype(dlp->info_ack.dl_mac_type), dlstate(dlp->info_ack.dl_current_state)); (void) printf("sap_length %d service_mode %s qos_length %d\n", dlp->info_ack.dl_sap_length, dlservicemode(dlp->info_ack.dl_service_mode), dlp->info_ack.dl_qos_length); (void) printf("qos_offset %d qos_range_length %d qos_range_offset %d\n", dlp->info_ack.dl_qos_offset, dlp->info_ack.dl_qos_range_length, dlp->info_ack.dl_qos_range_offset); (void) printf("provider_style %s addr_offset %d version %d\n", dlstyle(dlp->info_ack.dl_provider_style), dlp->info_ack.dl_addr_offset, dlp->info_ack.dl_version); (void) printf("brdcst_addr_length %d brdcst_addr_offset %d\n", dlp->info_ack.dl_brdcst_addr_length, dlp->info_ack.dl_brdcst_addr_offset); (void) printf("addr %s\n", addr); (void) printf("brdcst_addr %s\n", brdcst); } -printdlattachreq(dlp) - union DL_primitives *dlp; +printdlattachreq(union DL_primitives *dlp) { (void) printf("DL_ATTACH_REQ: ppa %d\n", dlp->attach_req.dl_ppa); } -printdlokack(dlp) +printdlokack(union DL_primitives* dlp) union DL_primitives *dlp; { (void) printf("DL_OK_ACK: correct_primitive %s\n", dlprim(dlp->ok_ack.dl_correct_primitive)); } -printdlerrorack(dlp) - union DL_primitives *dlp; +printdlerrorack(union DL_primitives *dlp) { (void) printf("DL_ERROR_ACK: error_primitive %s errno %s unix_errno %d: %s\n", dlprim(dlp->error_ack.dl_error_primitive), dlerrno(dlp->error_ack.dl_errno), dlp->error_ack.dl_unix_errno, strerror(dlp->error_ack.dl_unix_errno)); } -printdlenabmultireq(dlp) - union DL_primitives *dlp; +printdlenabmultireq(union DL_primitives *dlp) { u_char addr[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->enabmulti_req.dl_addr_offset), dlp->enabmulti_req.dl_addr_length, addr); (void) printf("DL_ENABMULTI_REQ: addr_length %d addr_offset %d\n", dlp->enabmulti_req.dl_addr_length, dlp->enabmulti_req.dl_addr_offset); (void) printf("addr %s\n", addr); } -printdldisabmultireq(dlp) - union DL_primitives *dlp; +printdldisabmultireq(union DL_primitives *dlp) { u_char addr[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->disabmulti_req.dl_addr_offset), dlp->disabmulti_req.dl_addr_length, addr); (void) printf("DL_DISABMULTI_REQ: addr_length %d addr_offset %d\n", dlp->disabmulti_req.dl_addr_length, dlp->disabmulti_req.dl_addr_offset); (void) printf("addr %s\n", addr); } -printdlpromisconreq(dlp) - union DL_primitives *dlp; +printdlpromisconreq(union DL_primitives *dlp) { (void) printf("DL_PROMISCON_REQ: level %s\n", dlpromisclevel(dlp->promiscon_req.dl_level)); } -printdlpromiscoffreq(dlp) - union DL_primitives *dlp; +printdlpromiscoffreq(union DL_primitives *dlp) { (void) printf("DL_PROMISCOFF_REQ: level %s\n", dlpromisclevel(dlp->promiscoff_req.dl_level)); } -printdlphysaddrreq(dlp) - union DL_primitives *dlp; +printdlphysaddrreq(union DL_primitives *dlp) { (void) printf("DL_PHYS_ADDR_REQ: addr_type 0x%x\n", dlp->physaddr_req.dl_addr_type); } -printdlphysaddrack(dlp) - union DL_primitives *dlp; +printdlphysaddrack(union DL_primitives *dlp) { u_char addr[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->physaddr_ack.dl_addr_offset), dlp->physaddr_ack.dl_addr_length, addr); (void) printf("DL_PHYS_ADDR_ACK: addr_length %d addr_offset %d\n", dlp->physaddr_ack.dl_addr_length, dlp->physaddr_ack.dl_addr_offset); (void) printf("addr %s\n", addr); } -printdlsetphysaddrreq(dlp) - union DL_primitives *dlp; +printdlsetphysaddrreq(union DL_primitives *dlp) { u_char addr[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->set_physaddr_req.dl_addr_offset), dlp->set_physaddr_req.dl_addr_length, addr); (void) printf("DL_SET_PHYS_ADDR_REQ: addr_length %d addr_offset %d\n", dlp->set_physaddr_req.dl_addr_length, dlp->set_physaddr_req.dl_addr_offset); (void) printf("addr %s\n", addr); } /* ARGSUSED */ -printdldetachreq(dlp) - union DL_primitives *dlp; +printdldetachreq(union DL_primitives *dlp) { (void) printf("DL_DETACH_REQ\n"); } -printdlbindreq(dlp) - union DL_primitives *dlp; +printdlbindreq(union DL_primitives *dlp) { (void) printf("DL_BIND_REQ: sap %d max_conind %d\n", dlp->bind_req.dl_sap, dlp->bind_req.dl_max_conind); (void) printf("service_mode %s conn_mgmt %d xidtest_flg 0x%x\n", dlservicemode(dlp->bind_req.dl_service_mode), dlp->bind_req.dl_conn_mgmt, dlp->bind_req.dl_xidtest_flg); } -printdlbindack(dlp) - union DL_primitives *dlp; +printdlbindack(union DL_primitives *dlp) { u_char addr[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->bind_ack.dl_addr_offset), dlp->bind_ack.dl_addr_length, addr); (void) printf("DL_BIND_ACK: sap %d addr_length %d addr_offset %d\n", dlp->bind_ack.dl_sap, dlp->bind_ack.dl_addr_length, dlp->bind_ack.dl_addr_offset); (void) printf("max_conind %d xidtest_flg 0x%x\n", dlp->bind_ack.dl_max_conind, dlp->bind_ack.dl_xidtest_flg); (void) printf("addr %s\n", addr); } /* ARGSUSED */ -printdlunbindreq(dlp) - union DL_primitives *dlp; +printdlunbindreq(union DL_primitives *dlp) { (void) printf("DL_UNBIND_REQ\n"); } -printdlsubsbindreq(dlp) - union DL_primitives *dlp; +printdlsubsbindreq(union DL_primitives *dlp) { u_char sap[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->subs_bind_req.dl_subs_sap_offset), dlp->subs_bind_req.dl_subs_sap_length, sap); (void) printf("DL_SUBS_BIND_REQ: subs_sap_offset %d sub_sap_len %d\n", dlp->subs_bind_req.dl_subs_sap_offset, dlp->subs_bind_req.dl_subs_sap_length); (void) printf("sap %s\n", sap); } -printdlsubsbindack(dlp) - union DL_primitives *dlp; +printdlsubsbindack(union DL_primitives *dlp) { u_char sap[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->subs_bind_ack.dl_subs_sap_offset), dlp->subs_bind_ack.dl_subs_sap_length, sap); (void) printf("DL_SUBS_BIND_ACK: subs_sap_offset %d sub_sap_length %d\n", dlp->subs_bind_ack.dl_subs_sap_offset, dlp->subs_bind_ack.dl_subs_sap_length); (void) printf("sap %s\n", sap); } -printdlsubsunbindreq(dlp) - union DL_primitives *dlp; +printdlsubsunbindreq(union DL_primitives *dlp) { u_char sap[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->subs_unbind_req.dl_subs_sap_offset), dlp->subs_unbind_req.dl_subs_sap_length, sap); (void) printf("DL_SUBS_UNBIND_REQ: subs_sap_offset %d sub_sap_length %d\n", dlp->subs_unbind_req.dl_subs_sap_offset, dlp->subs_unbind_req.dl_subs_sap_length); (void) printf("sap %s\n", sap); } -printdlunitdatareq(dlp) - union DL_primitives *dlp; +printdlunitdatareq(union DL_primitives *dlp) { u_char addr[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->unitdata_req.dl_dest_addr_offset), dlp->unitdata_req.dl_dest_addr_length, addr); (void) printf("DL_UNITDATA_REQ: dest_addr_length %d dest_addr_offset %d\n", dlp->unitdata_req.dl_dest_addr_length, dlp->unitdata_req.dl_dest_addr_offset); (void) printf("dl_priority.min %d dl_priority.max %d\n", dlp->unitdata_req.dl_priority.dl_min, dlp->unitdata_req.dl_priority.dl_max); (void) printf("addr %s\n", addr); } -printdlunitdataind(dlp) - union DL_primitives *dlp; +printdlunitdataind(union DL_primitives *dlp) { u_char dest[MAXDLADDR]; u_char src[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->unitdata_ind.dl_dest_addr_offset), dlp->unitdata_ind.dl_dest_addr_length, dest); addrtostring(OFFADDR(dlp, dlp->unitdata_ind.dl_src_addr_offset), dlp->unitdata_ind.dl_src_addr_length, src); (void) printf("DL_UNITDATA_IND: dest_addr_length %d dest_addr_offset %d\n", dlp->unitdata_ind.dl_dest_addr_length, dlp->unitdata_ind.dl_dest_addr_offset); (void) printf("src_addr_length %d src_addr_offset %d\n", dlp->unitdata_ind.dl_src_addr_length, dlp->unitdata_ind.dl_src_addr_offset); (void) printf("group_address 0x%x\n", dlp->unitdata_ind.dl_group_address); (void) printf("dest %s\n", dest); (void) printf("src %s\n", src); } -printdluderrorind(dlp) - union DL_primitives *dlp; +printdluderrorind(union DL_primitives *dlp) { u_char addr[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->uderror_ind.dl_dest_addr_offset), dlp->uderror_ind.dl_dest_addr_length, addr); (void) printf("DL_UDERROR_IND: dest_addr_length %d dest_addr_offset %d\n", dlp->uderror_ind.dl_dest_addr_length, dlp->uderror_ind.dl_dest_addr_offset); (void) printf("unix_errno %d errno %s\n", dlp->uderror_ind.dl_unix_errno, dlerrno(dlp->uderror_ind.dl_errno)); (void) printf("addr %s\n", addr); } -printdltestreq(dlp) - union DL_primitives *dlp; +printdltestreq(union DL_primitives *dlp) { u_char addr[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->test_req.dl_dest_addr_offset), dlp->test_req.dl_dest_addr_length, addr); (void) printf("DL_TEST_REQ: flag 0x%x dest_addr_length %d dest_addr_offset %d\n", dlp->test_req.dl_flag, dlp->test_req.dl_dest_addr_length, dlp->test_req.dl_dest_addr_offset); (void) printf("dest_addr %s\n", addr); } -printdltestind(dlp) - union DL_primitives *dlp; +printdltestind(union DL_primitives *dlp) { u_char dest[MAXDLADDR]; u_char src[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->test_ind.dl_dest_addr_offset), dlp->test_ind.dl_dest_addr_length, dest); addrtostring(OFFADDR(dlp, dlp->test_ind.dl_src_addr_offset), dlp->test_ind.dl_src_addr_length, src); (void) printf("DL_TEST_IND: flag 0x%x dest_addr_length %d dest_addr_offset %d\n", dlp->test_ind.dl_flag, dlp->test_ind.dl_dest_addr_length, dlp->test_ind.dl_dest_addr_offset); (void) printf("src_addr_length %d src_addr_offset %d\n", dlp->test_ind.dl_src_addr_length, dlp->test_ind.dl_src_addr_offset); (void) printf("dest_addr %s\n", dest); (void) printf("src_addr %s\n", src); } -printdltestres(dlp) - union DL_primitives *dlp; +printdltestres(union DL_primitives *dlp) { u_char dest[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->test_res.dl_dest_addr_offset), dlp->test_res.dl_dest_addr_length, dest); (void) printf("DL_TEST_RES: flag 0x%x dest_addr_length %d dest_addr_offset %d\n", dlp->test_res.dl_flag, dlp->test_res.dl_dest_addr_length, dlp->test_res.dl_dest_addr_offset); (void) printf("dest_addr %s\n", dest); } -printdltestcon(dlp) - union DL_primitives *dlp; +printdltestcon(union DL_primitives *dlp) { u_char dest[MAXDLADDR]; u_char src[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->test_con.dl_dest_addr_offset), dlp->test_con.dl_dest_addr_length, dest); addrtostring(OFFADDR(dlp, dlp->test_con.dl_src_addr_offset), dlp->test_con.dl_src_addr_length, src); (void) printf("DL_TEST_CON: flag 0x%x dest_addr_length %d dest_addr_offset %d\n", dlp->test_con.dl_flag, dlp->test_con.dl_dest_addr_length, dlp->test_con.dl_dest_addr_offset); (void) printf("src_addr_length %d src_addr_offset %d\n", dlp->test_con.dl_src_addr_length, dlp->test_con.dl_src_addr_offset); (void) printf("dest_addr %s\n", dest); (void) printf("src_addr %s\n", src); } -printdlxidreq(dlp) - union DL_primitives *dlp; +printdlxidreq(union DL_primitives *dlp) { u_char dest[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->xid_req.dl_dest_addr_offset), dlp->xid_req.dl_dest_addr_length, dest); (void) printf("DL_XID_REQ: flag 0x%x dest_addr_length %d dest_addr_offset %d\n", dlp->xid_req.dl_flag, dlp->xid_req.dl_dest_addr_length, dlp->xid_req.dl_dest_addr_offset); (void) printf("dest_addr %s\n", dest); } -printdlxidind(dlp) - union DL_primitives *dlp; +printdlxidind(dlpunion DL_primitives *) { u_char dest[MAXDLADDR]; u_char src[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->xid_ind.dl_dest_addr_offset), dlp->xid_ind.dl_dest_addr_length, dest); addrtostring(OFFADDR(dlp, dlp->xid_ind.dl_src_addr_offset), dlp->xid_ind.dl_src_addr_length, src); (void) printf("DL_XID_IND: flag 0x%x dest_addr_length %d dest_addr_offset %d\n", dlp->xid_ind.dl_flag, dlp->xid_ind.dl_dest_addr_length, dlp->xid_ind.dl_dest_addr_offset); (void) printf("src_addr_length %d src_addr_offset %d\n", dlp->xid_ind.dl_src_addr_length, dlp->xid_ind.dl_src_addr_offset); (void) printf("dest_addr %s\n", dest); (void) printf("src_addr %s\n", src); } -printdlxidres(dlp) - union DL_primitives *dlp; +printdlxidres(union DL_primitives *dlp) { u_char dest[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->xid_res.dl_dest_addr_offset), dlp->xid_res.dl_dest_addr_length, dest); (void) printf("DL_XID_RES: flag 0x%x dest_addr_length %d dest_addr_offset %d\n", dlp->xid_res.dl_flag, dlp->xid_res.dl_dest_addr_length, dlp->xid_res.dl_dest_addr_offset); (void) printf("dest_addr %s\n", dest); } -printdlxidcon(dlp) - union DL_primitives *dlp; +printdlxidcon(union DL_primitives *dlp) { u_char dest[MAXDLADDR]; u_char src[MAXDLADDR]; addrtostring(OFFADDR(dlp, dlp->xid_con.dl_dest_addr_offset), dlp->xid_con.dl_dest_addr_length, dest); addrtostring(OFFADDR(dlp, dlp->xid_con.dl_src_addr_offset), dlp->xid_con.dl_src_addr_length, src); (void) printf("DL_XID_CON: flag 0x%x dest_addr_length %d dest_addr_offset %d\n", dlp->xid_con.dl_flag, dlp->xid_con.dl_dest_addr_length, dlp->xid_con.dl_dest_addr_offset); (void) printf("src_addr_length %d src_addr_offset %d\n", dlp->xid_con.dl_src_addr_length, dlp->xid_con.dl_src_addr_offset); (void) printf("dest_addr %s\n", dest); (void) printf("src_addr %s\n", src); } -printdludqosreq(dlp) - union DL_primitives *dlp; +printdludqosreq(union DL_primitives *dlp) { (void) printf("DL_UDQOS_REQ: qos_length %d qos_offset %d\n", dlp->udqos_req.dl_qos_length, dlp->udqos_req.dl_qos_offset); } /* * Return string. */ -addrtostring(addr, length, s) - u_char *addr; - u_long length; - u_char *s; +addrtostring(u_char *addr, u_long length, u_char *s) { int i; for (i = 0; i < length; i++) { (void) sprintf((char*) s, "%x:", addr[i] & 0xff); s = s + strlen((char*)s); } if (length) *(--s) = '\0'; } /* * Return length */ -stringtoaddr(sp, addr) - char *sp; - char *addr; +stringtoaddr(char *sp, char *addr) { int n = 0; char *p; int val; p = sp; while (p = strtok(p, ":")) { if (sscanf(p, "%x", &val) != 1) err("stringtoaddr: invalid input string: %s", sp); if (val > 0xff) err("stringtoaddr: invalid input string: %s", sp); *addr++ = val; n++; p = NULL; } return (n); } static char -hexnibble(c) - char c; +hexnibble(char c) { static char hextab[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; return (hextab[c & 0x0f]); } char* -dlprim(prim) - u_long prim; +dlprim(u_long prim) { static char primbuf[80]; switch ((int)prim) { CASERET(DL_INFO_REQ); CASERET(DL_INFO_ACK); CASERET(DL_ATTACH_REQ); CASERET(DL_DETACH_REQ); CASERET(DL_BIND_REQ); CASERET(DL_BIND_ACK); CASERET(DL_UNBIND_REQ); CASERET(DL_OK_ACK); CASERET(DL_ERROR_ACK); CASERET(DL_SUBS_BIND_REQ); CASERET(DL_SUBS_BIND_ACK); CASERET(DL_UNITDATA_REQ); CASERET(DL_UNITDATA_IND); CASERET(DL_UDERROR_IND); CASERET(DL_UDQOS_REQ); CASERET(DL_CONNECT_REQ); CASERET(DL_CONNECT_IND); CASERET(DL_CONNECT_RES); CASERET(DL_CONNECT_CON); CASERET(DL_TOKEN_REQ); CASERET(DL_TOKEN_ACK); CASERET(DL_DISCONNECT_REQ); CASERET(DL_DISCONNECT_IND); CASERET(DL_RESET_REQ); CASERET(DL_RESET_IND); CASERET(DL_RESET_RES); CASERET(DL_RESET_CON); default: (void) snprintf(primbuf, sizeof(primbuf), "unknown primitive 0x%x", prim); return (primbuf); } } char* -dlstate(state) - u_long state; +dlstate(u_long state) { static char statebuf[80]; switch (state) { CASERET(DL_UNATTACHED); CASERET(DL_ATTACH_PENDING); CASERET(DL_DETACH_PENDING); CASERET(DL_UNBOUND); CASERET(DL_BIND_PENDING); CASERET(DL_UNBIND_PENDING); CASERET(DL_IDLE); CASERET(DL_UDQOS_PENDING); CASERET(DL_OUTCON_PENDING); CASERET(DL_INCON_PENDING); CASERET(DL_CONN_RES_PENDING); CASERET(DL_DATAXFER); CASERET(DL_USER_RESET_PENDING); CASERET(DL_PROV_RESET_PENDING); CASERET(DL_RESET_RES_PENDING); CASERET(DL_DISCON8_PENDING); CASERET(DL_DISCON9_PENDING); CASERET(DL_DISCON11_PENDING); CASERET(DL_DISCON12_PENDING); CASERET(DL_DISCON13_PENDING); CASERET(DL_SUBS_BIND_PND); default: (void) snprintf(statebuf, sizeof(statebuf), "unknown state 0x%x", state); return (statebuf); } } char* -dlerrno(errno) - u_long errno; +dlerrno(u_long errno) { static char errnobuf[80]; switch (errno) { CASERET(DL_ACCESS); CASERET(DL_BADADDR); CASERET(DL_BADCORR); CASERET(DL_BADDATA); CASERET(DL_BADPPA); CASERET(DL_BADPRIM); CASERET(DL_BADQOSPARAM); CASERET(DL_BADQOSTYPE); CASERET(DL_BADSAP); CASERET(DL_BADTOKEN); CASERET(DL_BOUND); CASERET(DL_INITFAILED); CASERET(DL_NOADDR); CASERET(DL_NOTINIT); CASERET(DL_OUTSTATE); CASERET(DL_SYSERR); CASERET(DL_UNSUPPORTED); CASERET(DL_UNDELIVERABLE); CASERET(DL_NOTSUPPORTED); CASERET(DL_TOOMANY); CASERET(DL_NOTENAB); CASERET(DL_BUSY); CASERET(DL_NOAUTO); CASERET(DL_NOXIDAUTO); CASERET(DL_NOTESTAUTO); CASERET(DL_XIDAUTO); CASERET(DL_TESTAUTO); CASERET(DL_PENDING); default: (void) snprintf(errnobuf, sizeof(errnobuf), "unknown dlpi errno 0x%x", errno); return (errnobuf); } } char* -dlpromisclevel(level) - u_long level; +dlpromisclevel(u_long level) { static char levelbuf[80]; switch (level) { CASERET(DL_PROMISC_PHYS); CASERET(DL_PROMISC_SAP); CASERET(DL_PROMISC_MULTI); default: (void) snprintf(levelbuf, sizeof(levelbuf), "unknown promisc level 0x%x", level); return (levelbuf); } } char* -dlservicemode(servicemode) - u_long servicemode; +dlservicemode(u_long servicemode) { static char servicemodebuf[80]; switch (servicemode) { CASERET(DL_CODLS); CASERET(DL_CLDLS); CASERET(DL_CODLS|DL_CLDLS); default: (void) snprintf(servicemodebuf, sizeof(servicemodebuf), "unknown provider service mode 0x%x", servicemode); return (servicemodebuf); } } char* -dlstyle(style) - long style; +dlstyle(long style) { static char stylebuf[80]; switch (style) { CASERET(DL_STYLE1); CASERET(DL_STYLE2); default: (void) snprintf(stylebuf, sizeof(stylebuf), "unknown provider style 0x%x", style); return (stylebuf); } } char* -dlmactype(media) - u_long media; +dlmactype(u_long media) { static char mediabuf[80]; switch (media) { CASERET(DL_CSMACD); CASERET(DL_TPB); CASERET(DL_TPR); CASERET(DL_METRO); CASERET(DL_ETHER); CASERET(DL_HDLC); CASERET(DL_CHAR); CASERET(DL_CTCA); default: (void) snprintf(mediabuf, sizeof(mediabuf), "unknown media type 0x%x", media); return (mediabuf); } } /*VARARGS1*/ -err(fmt, a1, a2, a3, a4) - char *fmt; - char *a1, *a2, *a3, *a4; +err(char *fmt, char *a1, char *a2, char *a3, char *a4) { (void) fprintf(stderr, fmt, a1, a2, a3, a4); (void) fprintf(stderr, "\n"); (void) exit(1); } -syserr(s) +syserr(char *s) char *s; { (void) perror(s); exit(1); } -strioctl(fd, cmd, timout, len, dp) - int fd; - int cmd; - int timout; - int len; - char *dp; +strioctl(int fd, int cmd, int timout, int len, char *dp) { struct strioctl sioc; int rc; sioc.ic_cmd = cmd; sioc.ic_timout = timout; sioc.ic_len = len; sioc.ic_dp = dp; rc = ioctl(fd, I_STR, &sioc); if (rc < 0) return (rc); else return (sioc.ic_len); } diff --git a/sbin/ipf/ipsend/ip.c b/sbin/ipf/ipsend/ip.c index c1bb73f0b169..8a474704e3ab 100644 --- a/sbin/ipf/ipsend/ip.c +++ b/sbin/ipf/ipsend/ip.c @@ -1,362 +1,351 @@ /* $FreeBSD$ */ /* * ip.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C)1995"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include #include #include #include #include #include #include # include # include # include #include #include #include #include #include #include "ipsend.h" static char *ipbuf = NULL, *ethbuf = NULL; -u_short chksum(buf,len) - u_short *buf; - int len; +u_short +chksum(u_short *buf, int len) { u_long sum = 0; int nwords = len >> 1; for(; nwords > 0; nwords--) sum += *buf++; sum = (sum>>16) + (sum & 0xffff); sum += (sum >>16); return (~sum); } -int send_ether(nfd, buf, len, gwip) - int nfd, len; - char *buf; - struct in_addr gwip; +int +send_ether(int nfd, char *buf, int len, struct in_addr gwip) { static struct in_addr last_gw; static char last_arp[6] = { 0, 0, 0, 0, 0, 0}; ether_header_t *eh; char *s; int err; if (!ethbuf) ethbuf = (char *)calloc(1, 65536+1024); s = ethbuf; eh = (ether_header_t *)s; bcopy((char *)buf, s + sizeof(*eh), len); if (gwip.s_addr == last_gw.s_addr) { bcopy(last_arp, (char *) &eh->ether_dhost, 6); } else if (arp((char *)&gwip, (char *) &eh->ether_dhost) == -1) { perror("arp"); return -2; } eh->ether_type = htons(ETHERTYPE_IP); last_gw.s_addr = gwip.s_addr; err = sendip(nfd, s, sizeof(*eh) + len); return err; } /* */ -int send_ip(nfd, mtu, ip, gwip, frag) - int nfd, mtu; - ip_t *ip; - struct in_addr gwip; - int frag; +int +send_ip(int nfd, int mtu, ip_t *ip, struct in_addr gwip, int frag) { static struct in_addr last_gw, local_ip; static char local_arp[6] = { 0, 0, 0, 0, 0, 0}; static char last_arp[6] = { 0, 0, 0, 0, 0, 0}; static u_short id = 0; ether_header_t *eh; ip_t ipsv; int err, iplen; if (!ipbuf) { ipbuf = (char *)malloc(65536); if (!ipbuf) { perror("malloc failed"); return -2; } } eh = (ether_header_t *)ipbuf; bzero((char *) &eh->ether_shost, sizeof(eh->ether_shost)); if (last_gw.s_addr && (gwip.s_addr == last_gw.s_addr)) { bcopy(last_arp, (char *) &eh->ether_dhost, 6); } else if (arp((char *)&gwip, (char *) &eh->ether_dhost) == -1) { perror("arp"); return -2; } bcopy((char *) &eh->ether_dhost, last_arp, sizeof(last_arp)); eh->ether_type = htons(ETHERTYPE_IP); bcopy((char *)ip, (char *)&ipsv, sizeof(*ip)); last_gw.s_addr = gwip.s_addr; iplen = ip->ip_len; ip->ip_len = htons(iplen); if (!(frag & 2)) { if (!IP_V(ip)) IP_V_A(ip, IPVERSION); if (!ip->ip_id) ip->ip_id = htons(id++); if (!ip->ip_ttl) ip->ip_ttl = 60; } if (ip->ip_src.s_addr != local_ip.s_addr) { (void) arp((char *)&ip->ip_src, (char *) &local_arp); bcopy(local_arp, (char *) &eh->ether_shost,sizeof(last_arp)); local_ip = ip->ip_src; } else bcopy(local_arp, (char *) &eh->ether_shost, 6); if (!frag || (sizeof(*eh) + iplen < mtu)) { ip->ip_sum = 0; ip->ip_sum = chksum((u_short *)ip, IP_HL(ip) << 2); bcopy((char *)ip, ipbuf + sizeof(*eh), iplen); err = sendip(nfd, ipbuf, sizeof(*eh) + iplen); } else { /* * Actually, this is bogus because we're putting all IP * options in every packet, which isn't always what should be * done. Will do for now. */ ether_header_t eth; char optcpy[48], ol; char *s; int i, sent = 0, ts, hlen, olen; hlen = IP_HL(ip) << 2; if (mtu < (hlen + 8)) { fprintf(stderr, "mtu (%d) < ip header size (%d) + 8\n", mtu, hlen); fprintf(stderr, "can't fragment data\n"); return -2; } ol = (IP_HL(ip) << 2) - sizeof(*ip); for (i = 0, s = (char*)(ip + 1); ol > 0; ) if (*s == IPOPT_EOL) { optcpy[i++] = *s; break; } else if (*s == IPOPT_NOP) { s++; ol--; } else { olen = (int)(*(u_char *)(s + 1)); ol -= olen; if (IPOPT_COPIED(*s)) { bcopy(s, optcpy + i, olen); i += olen; s += olen; } } if (i) { /* * pad out */ while ((i & 3) && (i & 3) != 3) optcpy[i++] = IPOPT_NOP; if ((i & 3) == 3) optcpy[i++] = IPOPT_EOL; } bcopy((char *)eh, (char *)ð, sizeof(eth)); s = (char *)ip + hlen; iplen = ntohs(ip->ip_len) - hlen; ip->ip_off |= htons(IP_MF); while (1) { if ((sent + (mtu - hlen)) >= iplen) { ip->ip_off ^= htons(IP_MF); ts = iplen - sent; } else ts = (mtu - hlen); ip->ip_off &= htons(0xe000); ip->ip_off |= htons(sent >> 3); ts += hlen; ip->ip_len = htons(ts); ip->ip_sum = 0; ip->ip_sum = chksum((u_short *)ip, hlen); bcopy((char *)ip, ipbuf + sizeof(*eh), hlen); bcopy(s + sent, ipbuf + sizeof(*eh) + hlen, ts - hlen); err = sendip(nfd, ipbuf, sizeof(*eh) + ts); bcopy((char *)ð, ipbuf, sizeof(eth)); sent += (ts - hlen); if (!(ntohs(ip->ip_off) & IP_MF)) break; else if (!(ip->ip_off & htons(0x1fff))) { hlen = i + sizeof(*ip); IP_HL_A(ip, (sizeof(*ip) + i) >> 2); bcopy(optcpy, (char *)(ip + 1), i); } } } bcopy((char *)&ipsv, (char *)ip, sizeof(*ip)); return err; } /* * send a tcp packet. */ -int send_tcp(nfd, mtu, ip, gwip) - int nfd, mtu; - ip_t *ip; - struct in_addr gwip; +int +send_tcp(int nfd, int mtu, ip_t *ip, struct in_addr gwip) { static tcp_seq iss = 2; tcphdr_t *t, *t2; int thlen, i, iplen, hlen; u_32_t lbuf[20]; ip_t *ip2; iplen = ip->ip_len; hlen = IP_HL(ip) << 2; t = (tcphdr_t *)((char *)ip + hlen); ip2 = (struct ip *)lbuf; t2 = (tcphdr_t *)((char *)ip2 + hlen); thlen = TCP_OFF(t) << 2; if (!thlen) thlen = sizeof(tcphdr_t); bzero((char *)ip2, sizeof(*ip2) + sizeof(*t2)); ip->ip_p = IPPROTO_TCP; ip2->ip_p = ip->ip_p; ip2->ip_src = ip->ip_src; ip2->ip_dst = ip->ip_dst; bcopy((char *)ip + hlen, (char *)t2, thlen); if (!t2->th_win) t2->th_win = htons(4096); iss += 63; i = sizeof(struct tcpiphdr) / sizeof(long); if ((t2->th_flags == TH_SYN) && !ntohs(ip->ip_off) && (lbuf[i] != htonl(0x020405b4))) { lbuf[i] = htonl(0x020405b4); bcopy((char *)ip + hlen + thlen, (char *)ip + hlen + thlen + 4, iplen - thlen - hlen); thlen += 4; } TCP_OFF_A(t2, thlen >> 2); ip2->ip_len = htons(thlen); ip->ip_len = hlen + thlen; t2->th_sum = 0; t2->th_sum = chksum((u_short *)ip2, thlen + sizeof(ip_t)); bcopy((char *)t2, (char *)ip + hlen, thlen); return send_ip(nfd, mtu, ip, gwip, 1); } /* * send a udp packet. */ -int send_udp(nfd, mtu, ip, gwip) - int nfd, mtu; - ip_t *ip; - struct in_addr gwip; +int +send_udp(int nfd, int mtu, ip_t *ip, struct in_addr gwip) { struct tcpiphdr *ti; int thlen; u_long lbuf[20]; ti = (struct tcpiphdr *)lbuf; bzero((char *)ti, sizeof(*ti)); thlen = sizeof(udphdr_t); ti->ti_pr = ip->ip_p; ti->ti_src = ip->ip_src; ti->ti_dst = ip->ip_dst; bcopy((char *)ip + (IP_HL(ip) << 2), (char *)&ti->ti_sport, sizeof(udphdr_t)); ti->ti_len = htons(thlen); ip->ip_len = (IP_HL(ip) << 2) + thlen; ti->ti_sum = 0; ti->ti_sum = chksum((u_short *)ti, thlen + sizeof(ip_t)); bcopy((char *)&ti->ti_sport, (char *)ip + (IP_HL(ip) << 2), sizeof(udphdr_t)); return send_ip(nfd, mtu, ip, gwip, 1); } /* * send an icmp packet. */ -int send_icmp(nfd, mtu, ip, gwip) - int nfd, mtu; - ip_t *ip; - struct in_addr gwip; +int +send_icmp(int nfd, int mtu, ip_t *ip, in_addr gwip) { struct icmp *ic; ic = (struct icmp *)((char *)ip + (IP_HL(ip) << 2)); ic->icmp_cksum = 0; ic->icmp_cksum = chksum((u_short *)ic, sizeof(struct icmp)); return send_ip(nfd, mtu, ip, gwip, 1); } -int send_packet(nfd, mtu, ip, gwip) +int +send_packet(int nfd, int mtu, ip_t *ip, struct in_addr gwip) int nfd, mtu; ip_t *ip; struct in_addr gwip; { switch (ip->ip_p) { case IPPROTO_TCP : return send_tcp(nfd, mtu, ip, gwip); case IPPROTO_UDP : return send_udp(nfd, mtu, ip, gwip); case IPPROTO_ICMP : return send_icmp(nfd, mtu, ip, gwip); default : return send_ip(nfd, mtu, ip, gwip, 1); } } diff --git a/sbin/ipf/ipsend/ipresend.c b/sbin/ipf/ipsend/ipresend.c index d9a5f92cbe2c..2efb2eb4eeed 100644 --- a/sbin/ipf/ipsend/ipresend.c +++ b/sbin/ipf/ipsend/ipresend.c @@ -1,133 +1,132 @@ /* $FreeBSD$ */ /* * ipresend.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. * */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipsend.h" extern char *optarg; extern int optind; #ifndef NO_IPF extern struct ipread pcap, iphex, iptext; #endif int opts = 0; #ifndef DEFAULT_DEVICE # ifdef sun char default_device[] = "le0"; # else char default_device[] = "lan0"; # endif #else char default_device[] = DEFAULT_DEVICE; #endif static void usage(char *); int main(int, char **); static void usage(prog) char *prog; { fprintf(stderr, "Usage: %s [options] <-r filename|-R filename>\n\ \t\t-r filename\tsnoop data file to resend\n\ \t\t-R filename\tlibpcap data file to resend\n\ \toptions:\n\ \t\t-d device\tSend out on this device\n\ \t\t-g gateway\tIP gateway to use if non-local dest.\n\ \t\t-m mtu\t\tfake MTU to use when sending out\n\ ", prog); exit(1); } -int main(argc, argv) - int argc; - char **argv; +int +main(int argc, char **argv) { struct in_addr gwip; struct ipread *ipr = NULL; char *name = argv[0], *gateway = NULL, *dev = NULL; char *resend = NULL; int mtu = 1500, c; while ((c = getopt(argc, argv, "EHPRSTXd:g:m:r:")) != -1) switch (c) { case 'd' : dev = optarg; break; case 'g' : gateway = optarg; break; case 'm' : mtu = atoi(optarg); if (mtu < 28) { fprintf(stderr, "mtu must be > 28\n"); exit(1); } case 'r' : resend = optarg; break; case 'R' : opts |= OPT_RAW; break; #ifndef NO_IPF case 'H' : ipr = &iphex; break; case 'P' : ipr = &pcap; break; case 'X' : ipr = &iptext; break; #endif default : fprintf(stderr, "Unknown option \"%c\"\n", c); usage(name); } if (!ipr || !resend) usage(name); gwip.s_addr = 0; if (gateway && resolve(gateway, (char *)&gwip) == -1) { fprintf(stderr,"Cant resolve %s\n", gateway); exit(2); } if (!dev) dev = default_device; printf("Device: %s\n", dev); printf("Gateway: %s\n", inet_ntoa(gwip)); printf("mtu: %d\n", mtu); return ip_resend(dev, mtu, ipr, gwip, resend); } diff --git a/sbin/ipf/ipsend/ipsend.c b/sbin/ipf/ipsend/ipsend.c index d77081bd8b71..b8111806397f 100644 --- a/sbin/ipf/ipsend/ipsend.c +++ b/sbin/ipf/ipsend/ipsend.c @@ -1,416 +1,411 @@ /* $FreeBSD$ */ /* * ipsend.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) static const char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include # include #include "ipsend.h" #include "ipf.h" # include extern char *optarg; extern int optind; extern void iplang(FILE *); char options[68]; int opts; char default_device[] = "le0"; static void usage(char *); static void do_icmp(ip_t *, char *); void udpcksum(ip_t *, struct udphdr *, int); int main(int, char **); static void usage(prog) char *prog; { fprintf(stderr, "Usage: %s [options] dest [flags]\n\ \toptions:\n\ \t\t-d\tdebug mode\n\ \t\t-i device\tSend out on this device\n\ \t\t-f fragflags\tcan set IP_MF or IP_DF\n\ \t\t-g gateway\tIP gateway to use if non-local dest.\n\ \t\t-I code,type[,gw[,dst[,src]]]\tSet ICMP protocol\n\ \t\t-m mtu\t\tfake MTU to use when sending out\n\ \t\t-P protocol\tSet protocol by name\n\ \t\t-s src\t\tsource address for IP packet\n\ \t\t-T\t\tSet TCP protocol\n\ \t\t-t port\t\tdestination port\n\ \t\t-U\t\tSet UDP protocol\n\ \t\t-v\tverbose mode\n\ \t\t-w \tSet the TCP window size\n\ ", prog); fprintf(stderr, "Usage: %s [-dv] -L \n\ \toptions:\n\ \t\t-d\tdebug mode\n\ \t\t-L filename\tUse IP language for sending packets\n\ \t\t-v\tverbose mode\n\ ", prog); exit(1); } -static void do_icmp(ip, args) - ip_t *ip; - char *args; +static +void do_icmp(ip_t *ip, char *args) { struct icmp *ic; char *s; ip->ip_p = IPPROTO_ICMP; ip->ip_len += sizeof(*ic); ic = (struct icmp *)(ip + 1); bzero((char *)ic, sizeof(*ic)); if (!(s = strchr(args, ','))) { fprintf(stderr, "ICMP args missing: ,\n"); return; } *s++ = '\0'; ic->icmp_type = atoi(args); ic->icmp_code = atoi(s); if (ic->icmp_type == ICMP_REDIRECT && strchr(s, ',')) { char *t; t = strtok(s, ","); t = strtok(NULL, ","); if (resolve(t, (char *)&ic->icmp_gwaddr) == -1) { fprintf(stderr,"Cant resolve %s\n", t); exit(2); } if ((t = strtok(NULL, ","))) { if (resolve(t, (char *)&ic->icmp_ip.ip_dst) == -1) { fprintf(stderr,"Cant resolve %s\n", t); exit(2); } if ((t = strtok(NULL, ","))) { if (resolve(t, (char *)&ic->icmp_ip.ip_src) == -1) { fprintf(stderr,"Cant resolve %s\n", t); exit(2); } } } } } -int send_packets(dev, mtu, ip, gwip) - char *dev; - int mtu; - ip_t *ip; - struct in_addr gwip; +int +send_packets(char *dev, int mtu, ip_t *ip, struct in_addr gwip) { int wfd; wfd = initdevice(dev, 5); if (wfd == -1) return -1; return send_packet(wfd, mtu, ip, gwip); } void udpcksum(ip_t *ip, struct udphdr *udp, int len) { union pseudoh { struct hdr { u_short len; u_char ttl; u_char proto; u_32_t src; u_32_t dst; } h; u_short w[6]; } ph; u_32_t temp32; u_short *opts; ph.h.len = htons(len); ph.h.ttl = 0; ph.h.proto = IPPROTO_UDP; ph.h.src = ip->ip_src.s_addr; ph.h.dst = ip->ip_dst.s_addr; temp32 = 0; opts = &ph.w[0]; temp32 += opts[0] + opts[1] + opts[2] + opts[3] + opts[4] + opts[5]; temp32 = (temp32 >> 16) + (temp32 & 65535); temp32 += (temp32 >> 16); udp->uh_sum = temp32 & 65535; udp->uh_sum = chksum((u_short *)udp, len); if (udp->uh_sum == 0) udp->uh_sum = 0xffff; } -int main(argc, argv) - int argc; - char **argv; +int +main(int argc, char **argv) { FILE *langfile = NULL; struct in_addr gwip; tcphdr_t *tcp; udphdr_t *udp; ip_t *ip; char *name = argv[0], host[MAXHOSTNAMELEN + 1]; char *gateway = NULL, *dev = NULL; char *src = NULL, *dst, *s; int mtu = 1500, olen = 0, c, nonl = 0; /* * 65535 is maximum packet size...you never know... */ ip = (ip_t *)calloc(1, 65536); tcp = (tcphdr_t *)(ip + 1); udp = (udphdr_t *)tcp; ip->ip_len = sizeof(*ip); IP_HL_A(ip, sizeof(*ip) >> 2); while ((c = getopt(argc, argv, "I:L:P:TUdf:i:g:m:o:s:t:vw:")) != -1) { switch (c) { case 'I' : nonl++; if (ip->ip_p) { fprintf(stderr, "Protocol already set: %d\n", ip->ip_p); break; } do_icmp(ip, optarg); break; case 'L' : if (nonl) { fprintf(stderr, "Incorrect usage of -L option.\n"); usage(name); } if (!strcmp(optarg, "-")) langfile = stdin; else if (!(langfile = fopen(optarg, "r"))) { fprintf(stderr, "can't open file %s\n", optarg); exit(1); } iplang(langfile); return 0; case 'P' : { struct protoent *p; nonl++; if (ip->ip_p) { fprintf(stderr, "Protocol already set: %d\n", ip->ip_p); break; } if ((p = getprotobyname(optarg))) ip->ip_p = p->p_proto; else fprintf(stderr, "Unknown protocol: %s\n", optarg); break; } case 'T' : nonl++; if (ip->ip_p) { fprintf(stderr, "Protocol already set: %d\n", ip->ip_p); break; } ip->ip_p = IPPROTO_TCP; ip->ip_len += sizeof(tcphdr_t); break; case 'U' : nonl++; if (ip->ip_p) { fprintf(stderr, "Protocol already set: %d\n", ip->ip_p); break; } ip->ip_p = IPPROTO_UDP; ip->ip_len += sizeof(udphdr_t); break; case 'd' : opts |= OPT_DEBUG; break; case 'f' : nonl++; ip->ip_off = strtol(optarg, NULL, 0); break; case 'g' : nonl++; gateway = optarg; break; case 'i' : nonl++; dev = optarg; break; case 'm' : nonl++; mtu = atoi(optarg); if (mtu < 28) { fprintf(stderr, "mtu must be > 28\n"); exit(1); } break; case 'o' : nonl++; olen = buildopts(optarg, options, (IP_HL(ip) - 5) << 2); break; case 's' : nonl++; src = optarg; break; case 't' : nonl++; if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) tcp->th_dport = htons(atoi(optarg)); break; case 'v' : opts |= OPT_VERBOSE; break; case 'w' : nonl++; if (ip->ip_p == IPPROTO_TCP) tcp->th_win = atoi(optarg); else fprintf(stderr, "set protocol to TCP first\n"); break; default : fprintf(stderr, "Unknown option \"%c\"\n", c); usage(name); } } if (argc - optind < 1) usage(name); dst = argv[optind++]; if (!src) { gethostname(host, sizeof(host)); src = host; } if (resolve(src, (char *)&ip->ip_src) == -1) { fprintf(stderr,"Cant resolve %s\n", src); exit(2); } if (resolve(dst, (char *)&ip->ip_dst) == -1) { fprintf(stderr,"Cant resolve %s\n", dst); exit(2); } if (!gateway) gwip = ip->ip_dst; else if (resolve(gateway, (char *)&gwip) == -1) { fprintf(stderr,"Cant resolve %s\n", gateway); exit(2); } if (olen) { int hlen; char *p; printf("Options: %d\n", olen); hlen = sizeof(*ip) + olen; IP_HL_A(ip, hlen >> 2); ip->ip_len += olen; p = (char *)malloc(65536); if (p == NULL) { fprintf(stderr, "malloc failed\n"); exit(2); } bcopy(ip, p, sizeof(*ip)); bcopy(options, p + sizeof(*ip), olen); bcopy(ip + 1, p + hlen, ip->ip_len - hlen); ip = (ip_t *)p; if (ip->ip_p == IPPROTO_TCP) { tcp = (tcphdr_t *)(p + hlen); } else if (ip->ip_p == IPPROTO_UDP) { udp = (udphdr_t *)(p + hlen); } } if (ip->ip_p == IPPROTO_TCP) for (s = argv[optind]; s && (c = *s); s++) switch(c) { case 'S' : case 's' : tcp->th_flags |= TH_SYN; break; case 'A' : case 'a' : tcp->th_flags |= TH_ACK; break; case 'F' : case 'f' : tcp->th_flags |= TH_FIN; break; case 'R' : case 'r' : tcp->th_flags |= TH_RST; break; case 'P' : case 'p' : tcp->th_flags |= TH_PUSH; break; case 'U' : case 'u' : tcp->th_flags |= TH_URG; break; } if (!dev) dev = default_device; printf("Device: %s\n", dev); printf("Source: %s\n", inet_ntoa(ip->ip_src)); printf("Dest: %s\n", inet_ntoa(ip->ip_dst)); printf("Gateway: %s\n", inet_ntoa(gwip)); if (ip->ip_p == IPPROTO_TCP && tcp->th_flags) printf("Flags: %#x\n", tcp->th_flags); printf("mtu: %d\n", mtu); if (ip->ip_p == IPPROTO_UDP) { udp->uh_sum = 0; udpcksum(ip, udp, ip->ip_len - (IP_HL(ip) << 2)); } #ifdef DOSOCKET if (ip->ip_p == IPPROTO_TCP && tcp->th_dport) return do_socket(dev, mtu, ip, gwip); #endif return send_packets(dev, mtu, ip, gwip); } diff --git a/sbin/ipf/ipsend/ipsopt.c b/sbin/ipf/ipsend/ipsopt.c index ce6616525ca1..e5585d906d7f 100644 --- a/sbin/ipf/ipsend/ipsopt.c +++ b/sbin/ipf/ipsend/ipsopt.c @@ -1,194 +1,192 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * */ #if !defined(lint) static const char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipsend.h" #ifndef __P # define __P(x) x #endif struct ipopt_names ionames[] = { { IPOPT_EOL, 0x01, 1, "eol" }, { IPOPT_NOP, 0x02, 1, "nop" }, { IPOPT_RR, 0x04, 3, "rr" }, /* 1 route */ { IPOPT_TS, 0x08, 8, "ts" }, /* 1 TS */ { IPOPT_SECURITY, 0x08, 11, "sec-level" }, { IPOPT_LSRR, 0x10, 7, "lsrr" }, /* 1 route */ { IPOPT_SATID, 0x20, 4, "satid" }, { IPOPT_SSRR, 0x40, 7, "ssrr" }, /* 1 route */ { 0, 0, 0, NULL } /* must be last */ }; struct ipopt_names secnames[] = { { IPOPT_SECUR_UNCLASS, 0x0100, 0, "unclass" }, { IPOPT_SECUR_CONFID, 0x0200, 0, "confid" }, { IPOPT_SECUR_EFTO, 0x0400, 0, "efto" }, { IPOPT_SECUR_MMMM, 0x0800, 0, "mmmm" }, { IPOPT_SECUR_RESTR, 0x1000, 0, "restr" }, { IPOPT_SECUR_SECRET, 0x2000, 0, "secret" }, { IPOPT_SECUR_TOPSECRET, 0x4000,0, "topsecret" }, { 0, 0, 0, NULL } /* must be last */ }; u_short ipseclevel(slevel) char *slevel; { struct ipopt_names *so; for (so = secnames; so->on_name; so++) if (!strcasecmp(slevel, so->on_name)) break; if (!so->on_name) { fprintf(stderr, "no such security level: %s\n", slevel); return 0; } return so->on_value; } -int addipopt(op, io, len, class) - char *op; - struct ipopt_names *io; - int len; - char *class; +int +addipopt(char *op, struct ipopt_names *io, int len, char *class) { struct in_addr ipadr; int olen = len, srr = 0; u_short val; u_char lvl; char *s = op, *t; if ((len + io->on_siz) > 48) { fprintf(stderr, "options too long\n"); return 0; } len += io->on_siz; *op++ = io->on_value; if (io->on_siz > 1) { /* * Allow option to specify RR buffer length in bytes. */ if (io->on_value == IPOPT_RR) { val = (class && *class) ? atoi(class) : 4; *op++ = val + io->on_siz; len += val; } else *op++ = io->on_siz; if (io->on_value == IPOPT_TS) *op++ = IPOPT_MINOFF + 1; else *op++ = IPOPT_MINOFF; while (class && *class) { t = NULL; switch (io->on_value) { case IPOPT_SECURITY : lvl = ipseclevel(class); *(op - 1) = lvl; break; case IPOPT_LSRR : case IPOPT_SSRR : if ((t = strchr(class, ','))) *t = '\0'; ipadr.s_addr = inet_addr(class); srr++; bcopy((char *)&ipadr, op, sizeof(ipadr)); op += sizeof(ipadr); break; case IPOPT_SATID : val = atoi(class); bcopy((char *)&val, op, 2); break; } if (t) *t++ = ','; class = t; } if (srr) s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4 * srr; if (io->on_value == IPOPT_RR) op += val; else op += io->on_siz - 3; } return len - olen; } -u_32_t buildopts(cp, op, len) +u_32_t +buildopts(char *cp, char *op, int len) char *cp, *op; int len; { struct ipopt_names *io; u_32_t msk = 0; char *s, *t; int inc, lastop = -1; for (s = strtok(cp, ","); s; s = strtok(NULL, ",")) { if ((t = strchr(s, '='))) *t++ = '\0'; for (io = ionames; io->on_name; io++) { if (strcasecmp(s, io->on_name) || (msk & io->on_bit)) continue; lastop = io->on_value; if ((inc = addipopt(op, io, len, t))) { op += inc; len += inc; } msk |= io->on_bit; break; } if (!io->on_name) { fprintf(stderr, "unknown IP option name %s\n", s); return 0; } } if (len & 3) { while (len & 3) { *op++ = ((len & 3) == 3) ? IPOPT_EOL : IPOPT_NOP; len++; } } else { if (lastop != IPOPT_EOL) { if (lastop == IPOPT_NOP) *(op - 1) = IPOPT_EOL; else { *op++ = IPOPT_NOP; *op++ = IPOPT_NOP; *op++ = IPOPT_NOP; *op = IPOPT_EOL; len += 4; } } } return len; } diff --git a/sbin/ipf/ipsend/iptest.c b/sbin/ipf/ipsend/iptest.c index df2efb96a32a..e6c57c3cdbbd 100644 --- a/sbin/ipf/ipsend/iptest.c +++ b/sbin/ipf/ipsend/iptest.c @@ -1,197 +1,196 @@ /* $FreeBSD$ */ /* * ipsend.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. * */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipsend.h" extern char *optarg; extern int optind; char options[68]; # ifdef sun char default_device[] = "le0"; # else char default_device[] = "lan0"; # endif static void usage(char *); int main(int, char **); static void usage(prog) char *prog; { fprintf(stderr, "Usage: %s [options] dest\n\ \toptions:\n\ \t\t-d device\tSend out on this device\n\ \t\t-g gateway\tIP gateway to use if non-local dest.\n\ \t\t-m mtu\t\tfake MTU to use when sending out\n\ \t\t-p pointtest\t\n\ \t\t-s src\t\tsource address for IP packet\n\ \t\t-1 \t\tPerform test 1 (IP header)\n\ \t\t-2 \t\tPerform test 2 (IP options)\n\ \t\t-3 \t\tPerform test 3 (ICMP)\n\ \t\t-4 \t\tPerform test 4 (UDP)\n\ \t\t-5 \t\tPerform test 5 (TCP)\n\ \t\t-6 \t\tPerform test 6 (overlapping fragments)\n\ \t\t-7 \t\tPerform test 7 (random packets)\n\ ", prog); exit(1); } -int main(argc, argv) - int argc; - char **argv; +int +main(int argc, char **argv) { struct tcpiphdr *ti; struct in_addr gwip; ip_t *ip; char *name = argv[0], host[MAXHOSTNAMELEN + 1]; char *gateway = NULL, *dev = NULL; char *src = NULL, *dst; int mtu = 1500, tests = 0, pointtest = 0, c; /* * 65535 is maximum packet size...you never know... */ ip = (ip_t *)calloc(1, 65536); ti = (struct tcpiphdr *)ip; ip->ip_len = sizeof(*ip); IP_HL_A(ip, sizeof(*ip) >> 2); while ((c = getopt(argc, argv, "1234567d:g:m:p:s:")) != -1) switch (c) { case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : tests = c - '0'; break; case 'd' : dev = optarg; break; case 'g' : gateway = optarg; break; case 'm' : mtu = atoi(optarg); if (mtu < 28) { fprintf(stderr, "mtu must be > 28\n"); exit(1); } break; case 'p' : pointtest = atoi(optarg); break; case 's' : src = optarg; break; default : fprintf(stderr, "Unknown option \"%c\"\n", c); usage(name); } if ((argc <= optind) || !argv[optind]) usage(name); dst = argv[optind++]; if (!src) { gethostname(host, sizeof(host)); host[sizeof(host) - 1] = '\0'; src = host; } if (resolve(dst, (char *)&ip->ip_dst) == -1) { fprintf(stderr,"Cant resolve %s\n", dst); exit(2); } if (resolve(src, (char *)&ip->ip_src) == -1) { fprintf(stderr,"Cant resolve %s\n", src); exit(2); } if (!gateway) gwip = ip->ip_dst; else if (resolve(gateway, (char *)&gwip) == -1) { fprintf(stderr,"Cant resolve %s\n", gateway); exit(2); } if (!dev) dev = default_device; printf("Device: %s\n", dev); printf("Source: %s\n", inet_ntoa(ip->ip_src)); printf("Dest: %s\n", inet_ntoa(ip->ip_dst)); printf("Gateway: %s\n", inet_ntoa(gwip)); printf("mtu: %d\n", mtu); switch (tests) { case 1 : ip_test1(dev, mtu, (ip_t *)ti, gwip, pointtest); break; case 2 : ip_test2(dev, mtu, (ip_t *)ti, gwip, pointtest); break; case 3 : ip_test3(dev, mtu, (ip_t *)ti, gwip, pointtest); break; case 4 : ip_test4(dev, mtu, (ip_t *)ti, gwip, pointtest); break; case 5 : ip_test5(dev, mtu, (ip_t *)ti, gwip, pointtest); break; case 6 : ip_test6(dev, mtu, (ip_t *)ti, gwip, pointtest); break; case 7 : ip_test7(dev, mtu, (ip_t *)ti, gwip, pointtest); break; default : ip_test1(dev, mtu, (ip_t *)ti, gwip, pointtest); ip_test2(dev, mtu, (ip_t *)ti, gwip, pointtest); ip_test3(dev, mtu, (ip_t *)ti, gwip, pointtest); ip_test4(dev, mtu, (ip_t *)ti, gwip, pointtest); ip_test5(dev, mtu, (ip_t *)ti, gwip, pointtest); ip_test6(dev, mtu, (ip_t *)ti, gwip, pointtest); ip_test7(dev, mtu, (ip_t *)ti, gwip, pointtest); break; } return 0; } diff --git a/sbin/ipf/ipsend/iptests.c b/sbin/ipf/ipsend/iptests.c index a4e1a99b2885..cbda02893162 100644 --- a/sbin/ipf/ipsend/iptests.c +++ b/sbin/ipf/ipsend/iptests.c @@ -1,1397 +1,1373 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include #if defined(__NetBSD__) && defined(__vax__) /* * XXX need to declare boolean_t for _KERNEL * which ends up including for vax. See PR#32907 * for further details. */ typedef int boolean_t; #endif #include # ifdef __NetBSD__ # include # include # endif # define _KERNEL # define KERNEL # if !defined(solaris) # include # else # ifdef solaris # include # endif # endif # undef _KERNEL # undef KERNEL #if !defined(solaris) # include # include # include #endif # include # include #if defined(solaris) # include #else # include #endif #ifdef sun #include #include #endif # include # include # include #include #include #include # if defined(__FreeBSD__) # include "radix_ipf.h" # endif # if !defined(solaris) # include # endif #include #include #include #if defined(__SVR4) || defined(__svr4__) # include #endif #include #include #include #include # include # if !defined(solaris) # include # endif #include "ipsend.h" # include # include #if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 106000000) # define USE_NANOSLEEP #endif #ifdef USE_NANOSLEEP # define PAUSE() ts.tv_sec = 0; ts.tv_nsec = 10000000; \ (void) nanosleep(&ts, NULL) #else # define PAUSE() tv.tv_sec = 0; tv.tv_usec = 10000; \ (void) select(0, NULL, NULL, NULL, &tv) #endif -void ip_test1(dev, mtu, ip, gwip, ptest) - char *dev; - int mtu; - ip_t *ip; - struct in_addr gwip; - int ptest; +void +ip_test1(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest) { #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif udphdr_t *u; int nfd, i = 0, len, id = getpid(); IP_HL_A(ip, sizeof(*ip) >> 2); IP_V_A(ip, IPVERSION); ip->ip_tos = 0; ip->ip_off = 0; ip->ip_ttl = 60; ip->ip_p = IPPROTO_UDP; ip->ip_sum = 0; u = (udphdr_t *)(ip + 1); u->uh_sport = htons(1); u->uh_dport = htons(9); u->uh_sum = 0; u->uh_ulen = htons(sizeof(*u) + 4); ip->ip_len = sizeof(*ip) + ntohs(u->uh_ulen); len = ip->ip_len; nfd = initdevice(dev, 1); if (nfd == -1) return; if (!ptest || (ptest == 1)) { /* * Part1: hl < len */ ip->ip_id = 0; printf("1.1. sending packets with ip_hl < ip_len\n"); for (i = 0; i < ((sizeof(*ip) + ntohs(u->uh_ulen)) >> 2); i++) { IP_HL_A(ip, i >> 2); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 2)) { /* * Part2: hl > len */ ip->ip_id = 0; printf("1.2. sending packets with ip_hl > ip_len\n"); for (; i < ((sizeof(*ip) * 2 + ntohs(u->uh_ulen)) >> 2); i++) { IP_HL_A(ip, i >> 2); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 3)) { /* * Part3: v < 4 */ ip->ip_id = 0; printf("1.3. ip_v < 4\n"); IP_HL_A(ip, sizeof(*ip) >> 2); for (i = 0; i < 4; i++) { IP_V_A(ip, i); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 4)) { /* * Part4: v > 4 */ ip->ip_id = 0; printf("1.4. ip_v > 4\n"); for (i = 5; i < 16; i++) { IP_V_A(ip, i); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 5)) { /* * Part5: len < packet */ ip->ip_id = 0; IP_V_A(ip, IPVERSION); i = ip->ip_len + 1; printf("1.5.0 ip_len < packet size (size++, long packets)\n"); for (; i < (ip->ip_len * 2); i++) { ip->ip_id = htons(id++); ip->ip_sum = 0; ip->ip_sum = chksum((u_short *)ip, IP_HL(ip) << 2); (void) send_ether(nfd, (char *)ip, i, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); printf("1.5.1 ip_len < packet size (ip_len-, short packets)\n"); for (i = len; i > 0; i--) { ip->ip_id = htons(id++); ip->ip_len = i; ip->ip_sum = 0; ip->ip_sum = chksum((u_short *)ip, IP_HL(ip) << 2); (void) send_ether(nfd, (char *)ip, len, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 6)) { /* * Part6: len > packet */ ip->ip_id = 0; printf("1.6.0 ip_len > packet size (increase ip_len)\n"); for (i = len + 1; i < (len * 2); i++) { ip->ip_id = htons(id++); ip->ip_len = i; ip->ip_sum = 0; ip->ip_sum = chksum((u_short *)ip, IP_HL(ip) << 2); (void) send_ether(nfd, (char *)ip, len, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); ip->ip_len = len; printf("1.6.1 ip_len > packet size (size--, short packets)\n"); for (i = len; i > 0; i--) { ip->ip_id = htons(id++); ip->ip_sum = 0; ip->ip_sum = chksum((u_short *)ip, IP_HL(ip) << 2); (void) send_ether(nfd, (char *)ip, i, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 7)) { /* * Part7: 0 length fragment */ printf("1.7.0 Zero length fragments (ip_off = 0x2000)\n"); ip->ip_id = 0; ip->ip_len = sizeof(*ip); ip->ip_off = htons(IP_MF); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("1.7.1 Zero length fragments (ip_off = 0x3000)\n"); ip->ip_id = 0; ip->ip_len = sizeof(*ip); ip->ip_off = htons(IP_MF); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("1.7.2 Zero length fragments (ip_off = 0xa000)\n"); ip->ip_id = 0; ip->ip_len = sizeof(*ip); ip->ip_off = htons(0xa000); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("1.7.3 Zero length fragments (ip_off = 0x0100)\n"); ip->ip_id = 0; ip->ip_len = sizeof(*ip); ip->ip_off = htons(0x0100); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); } if (!ptest || (ptest == 8)) { struct timeval tv; gettimeofday(&tv, NULL); srand(tv.tv_sec ^ getpid() ^ tv.tv_usec); /* * Part8.1: 63k packet + 1k fragment at offset 0x1ffe * Mark it as being ICMP (so it doesn't get junked), but * don't bother about the ICMP header, we're not worrying * about that here. */ ip->ip_p = IPPROTO_ICMP; ip->ip_off = htons(IP_MF); u->uh_dport = htons(9); ip->ip_id = htons(id++); printf("1.8.1 63k packet + 1k fragment at offset 0x1ffe\n"); ip->ip_len = 768 + 20 + 8; (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); ip->ip_len = MIN(768 + 20, mtu - 68); i = 512; for (; i < (63 * 1024 + 768); i += 768) { ip->ip_off = htons(IP_MF | (i >> 3)); (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); fflush(stdout); PAUSE(); } ip->ip_len = 896 + 20; ip->ip_off = htons(i >> 3); (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); putchar('\n'); fflush(stdout); /* * Part8.2: 63k packet + 1k fragment at offset 0x1ffe * Mark it as being ICMP (so it doesn't get junked), but * don't bother about the ICMP header, we're not worrying * about that here. (Lossage here) */ ip->ip_p = IPPROTO_ICMP; ip->ip_off = htons(IP_MF); u->uh_dport = htons(9); ip->ip_id = htons(id++); printf("1.8.2 63k packet + 1k fragment at offset 0x1ffe\n"); ip->ip_len = 768 + 20 + 8; if ((rand() & 0x1f) != 0) { (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); } else printf("skip 0\n"); ip->ip_len = MIN(768 + 20, mtu - 68); i = 512; for (; i < (63 * 1024 + 768); i += 768) { ip->ip_off = htons(IP_MF | (i >> 3)); if ((rand() & 0x1f) != 0) { (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); } else printf("skip %d\n", i); fflush(stdout); PAUSE(); } ip->ip_len = 896 + 20; ip->ip_off = htons(i >> 3); if ((rand() & 0x1f) != 0) { (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); } else printf("skip\n"); putchar('\n'); fflush(stdout); /* * Part8.3: 33k packet - test for not dealing with -ve length * Mark it as being ICMP (so it doesn't get junked), but * don't bother about the ICMP header, we're not worrying * about that here. */ ip->ip_p = IPPROTO_ICMP; ip->ip_off = htons(IP_MF); u->uh_dport = htons(9); ip->ip_id = htons(id++); printf("1.8.3 33k packet\n"); ip->ip_len = 768 + 20 + 8; (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); ip->ip_len = MIN(768 + 20, mtu - 68); i = 512; for (; i < (32 * 1024 + 768); i += 768) { ip->ip_off = htons(IP_MF | (i >> 3)); (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); fflush(stdout); PAUSE(); } ip->ip_len = 896 + 20; ip->ip_off = htons(i >> 3); (void) send_ip(nfd, mtu, ip, gwip, 1); printf("%d\r", i); putchar('\n'); fflush(stdout); } ip->ip_len = len; ip->ip_off = 0; if (!ptest || (ptest == 9)) { /* * Part9: off & 0x8000 == 0x8000 */ ip->ip_id = 0; ip->ip_off = htons(0x8000); printf("1.9. ip_off & 0x8000 == 0x8000\n"); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); } ip->ip_off = 0; if (!ptest || (ptest == 10)) { /* * Part10: ttl = 255 */ ip->ip_id = 0; ip->ip_ttl = 255; printf("1.10.0 ip_ttl = 255\n"); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); ip->ip_ttl = 128; printf("1.10.1 ip_ttl = 128\n"); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); ip->ip_ttl = 0; printf("1.10.2 ip_ttl = 0\n"); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); } (void) close(nfd); } void ip_test2(dev, mtu, ip, gwip, ptest) char *dev; int mtu; ip_t *ip; struct in_addr gwip; int ptest; { #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif int nfd; u_char *s; nfd = initdevice(dev, 1); if (nfd == -1) return; IP_HL_A(ip, 6); ip->ip_len = IP_HL(ip) << 2; s = (u_char *)(ip + 1); s[IPOPT_OPTVAL] = IPOPT_NOP; s++; if (!ptest || (ptest == 1)) { /* * Test 1: option length > packet length, * header length == packet length */ s[IPOPT_OPTVAL] = IPOPT_TS; s[IPOPT_OLEN] = 4; s[IPOPT_OFFSET] = IPOPT_MINOFF; ip->ip_p = IPPROTO_IP; printf("2.1 option length > packet length\n"); (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); } IP_HL_A(ip, 7); ip->ip_len = IP_HL(ip) << 2; if (!ptest || (ptest == 1)) { /* * Test 2: options have length = 0 */ printf("2.2.1 option length = 0, RR\n"); s[IPOPT_OPTVAL] = IPOPT_RR; s[IPOPT_OLEN] = 0; (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("2.2.2 option length = 0, TS\n"); s[IPOPT_OPTVAL] = IPOPT_TS; s[IPOPT_OLEN] = 0; (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("2.2.3 option length = 0, SECURITY\n"); s[IPOPT_OPTVAL] = IPOPT_SECURITY; s[IPOPT_OLEN] = 0; (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("2.2.4 option length = 0, LSRR\n"); s[IPOPT_OPTVAL] = IPOPT_LSRR; s[IPOPT_OLEN] = 0; (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("2.2.5 option length = 0, SATID\n"); s[IPOPT_OPTVAL] = IPOPT_SATID; s[IPOPT_OLEN] = 0; (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); printf("2.2.6 option length = 0, SSRR\n"); s[IPOPT_OPTVAL] = IPOPT_SSRR; s[IPOPT_OLEN] = 0; (void) send_ip(nfd, mtu, ip, gwip, 1); fflush(stdout); PAUSE(); } (void) close(nfd); } /* * test 3 (ICMP) */ -void ip_test3(dev, mtu, ip, gwip, ptest) - char *dev; - int mtu; - ip_t *ip; - struct in_addr gwip; - int ptest; +void +ip_test3(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest) { static int ict1[10] = { 8, 9, 10, 13, 14, 15, 16, 17, 18, 0 }; static int ict2[8] = { 3, 9, 10, 13, 14, 17, 18, 0 }; #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif struct icmp *icp; int nfd, i; IP_HL_A(ip, sizeof(*ip) >> 2); IP_V_A(ip, IPVERSION); ip->ip_tos = 0; ip->ip_off = 0; ip->ip_ttl = 60; ip->ip_p = IPPROTO_ICMP; ip->ip_sum = 0; ip->ip_len = sizeof(*ip) + sizeof(*icp); icp = (struct icmp *)((char *)ip + (IP_HL(ip) << 2)); nfd = initdevice(dev, 1); if (nfd == -1) return; if (!ptest || (ptest == 1)) { /* * Type 0 - 31, 255, code = 0 */ bzero((char *)icp, sizeof(*icp)); for (i = 0; i < 32; i++) { icp->icmp_type = i; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.1.%d ICMP type %d code 0 (all 0's)\r", i, i); } icp->icmp_type = 255; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.1.%d ICMP type %d code 0 (all 0's)\r", i, 255); putchar('\n'); } if (!ptest || (ptest == 2)) { /* * Type 3, code = 0 - 31 */ icp->icmp_type = 3; for (i = 0; i < 32; i++) { icp->icmp_code = i; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.2.%d ICMP type 3 code %d (all 0's)\r", i, i); } } if (!ptest || (ptest == 3)) { /* * Type 4, code = 0,127,128,255 */ icp->icmp_type = 4; icp->icmp_code = 0; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.3.1 ICMP type 4 code 0 (all 0's)\r"); icp->icmp_code = 127; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.3.2 ICMP type 4 code 127 (all 0's)\r"); icp->icmp_code = 128; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.3.3 ICMP type 4 code 128 (all 0's)\r"); icp->icmp_code = 255; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.3.4 ICMP type 4 code 255 (all 0's)\r"); } if (!ptest || (ptest == 4)) { /* * Type 5, code = 0,127,128,255 */ icp->icmp_type = 5; icp->icmp_code = 0; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.4.1 ICMP type 5 code 0 (all 0's)\r"); icp->icmp_code = 127; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.4.2 ICMP type 5 code 127 (all 0's)\r"); icp->icmp_code = 128; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.4.3 ICMP type 5 code 128 (all 0's)\r"); icp->icmp_code = 255; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.4.4 ICMP type 5 code 255 (all 0's)\r"); } if (!ptest || (ptest == 5)) { /* * Type 8-10;13-18, code - 0,127,128,255 */ for (i = 0; ict1[i]; i++) { icp->icmp_type = ict1[i]; icp->icmp_code = 0; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type 5 code 0 (all 0's)\r", i * 4); icp->icmp_code = 127; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type 5 code 127 (all 0's)\r", i * 4 + 1); icp->icmp_code = 128; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type 5 code 128 (all 0's)\r", i * 4 + 2); icp->icmp_code = 255; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type 5 code 255 (all 0's)\r", i * 4 + 3); } putchar('\n'); } if (!ptest || (ptest == 6)) { /* * Type 12, code - 0,127,128,129,255 */ icp->icmp_type = 12; icp->icmp_code = 0; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.6.1 ICMP type 12 code 0 (all 0's)\r"); icp->icmp_code = 127; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.6.2 ICMP type 12 code 127 (all 0's)\r"); icp->icmp_code = 128; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.6.3 ICMP type 12 code 128 (all 0's)\r"); icp->icmp_code = 129; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.6.4 ICMP type 12 code 129 (all 0's)\r"); icp->icmp_code = 255; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.6.5 ICMP type 12 code 255 (all 0's)\r"); putchar('\n'); } if (!ptest || (ptest == 7)) { /* * Type 3;9-10;13-14;17-18 - shorter packets */ ip->ip_len = sizeof(*ip) + sizeof(*icp) / 2; for (i = 0; ict2[i]; i++) { icp->icmp_type = ict1[i]; icp->icmp_code = 0; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type %d code 0 (all 0's)\r", i * 4, icp->icmp_type); icp->icmp_code = 127; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type %d code 127 (all 0's)\r", i * 4 + 1, icp->icmp_type); icp->icmp_code = 128; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type %d code 128 (all 0's)\r", i * 4 + 2, icp->icmp_type); icp->icmp_code = 255; (void) send_icmp(nfd, mtu, ip, gwip); PAUSE(); printf("3.5.%d ICMP type %d code 127 (all 0's)\r", i * 4 + 3, icp->icmp_type); } putchar('\n'); } } /* Perform test 4 (UDP) */ -void ip_test4(dev, mtu, ip, gwip, ptest) - char *dev; - int mtu; - ip_t *ip; - struct in_addr gwip; - int ptest; +void +ip_test4(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest) { #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif udphdr_t *u; int nfd, i; IP_HL_A(ip, sizeof(*ip) >> 2); IP_V_A(ip, IPVERSION); ip->ip_tos = 0; ip->ip_off = 0; ip->ip_ttl = 60; ip->ip_p = IPPROTO_UDP; ip->ip_sum = 0; u = (udphdr_t *)((char *)ip + (IP_HL(ip) << 2)); u->uh_sport = htons(1); u->uh_dport = htons(1); u->uh_ulen = htons(sizeof(*u) + 4); nfd = initdevice(dev, 1); if (nfd == -1) return; if (!ptest || (ptest == 1)) { /* * Test 1. ulen > packet */ u->uh_ulen = htons(sizeof(*u) + 4); ip->ip_len = (IP_HL(ip) << 2) + ntohs(u->uh_ulen); printf("4.1 UDP uh_ulen > packet size - short packets\n"); for (i = ntohs(u->uh_ulen) * 2; i > sizeof(*u) + 4; i--) { u->uh_ulen = htons(i); (void) send_udp(nfd, 1500, ip, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 2)) { /* * Test 2. ulen < packet */ u->uh_ulen = htons(sizeof(*u) + 4); ip->ip_len = (IP_HL(ip) << 2) + ntohs(u->uh_ulen); printf("4.2 UDP uh_ulen < packet size - short packets\n"); for (i = ntohs(u->uh_ulen) * 2; i > sizeof(*u) + 4; i--) { ip->ip_len = i; (void) send_udp(nfd, 1500, ip, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 3)) { /* * Test 3: sport = 0, sport = 1, sport = 32767 * sport = 32768, sport = 65535 */ u->uh_ulen = sizeof(*u) + 4; ip->ip_len = (IP_HL(ip) << 2) + ntohs(u->uh_ulen); printf("4.3.1 UDP sport = 0\n"); u->uh_sport = 0; (void) send_udp(nfd, 1500, ip, gwip); printf("0\n"); fflush(stdout); PAUSE(); printf("4.3.2 UDP sport = 1\n"); u->uh_sport = htons(1); (void) send_udp(nfd, 1500, ip, gwip); printf("1\n"); fflush(stdout); PAUSE(); printf("4.3.3 UDP sport = 32767\n"); u->uh_sport = htons(32767); (void) send_udp(nfd, 1500, ip, gwip); printf("32767\n"); fflush(stdout); PAUSE(); printf("4.3.4 UDP sport = 32768\n"); u->uh_sport = htons(32768); (void) send_udp(nfd, 1500, ip, gwip); printf("32768\n"); putchar('\n'); fflush(stdout); PAUSE(); printf("4.3.5 UDP sport = 65535\n"); u->uh_sport = htons(65535); (void) send_udp(nfd, 1500, ip, gwip); printf("65535\n"); fflush(stdout); PAUSE(); } if (!ptest || (ptest == 4)) { /* * Test 4: dport = 0, dport = 1, dport = 32767 * dport = 32768, dport = 65535 */ u->uh_ulen = ntohs(sizeof(*u) + 4); u->uh_sport = htons(1); ip->ip_len = (IP_HL(ip) << 2) + ntohs(u->uh_ulen); printf("4.4.1 UDP dport = 0\n"); u->uh_dport = 0; (void) send_udp(nfd, 1500, ip, gwip); printf("0\n"); fflush(stdout); PAUSE(); printf("4.4.2 UDP dport = 1\n"); u->uh_dport = htons(1); (void) send_udp(nfd, 1500, ip, gwip); printf("1\n"); fflush(stdout); PAUSE(); printf("4.4.3 UDP dport = 32767\n"); u->uh_dport = htons(32767); (void) send_udp(nfd, 1500, ip, gwip); printf("32767\n"); fflush(stdout); PAUSE(); printf("4.4.4 UDP dport = 32768\n"); u->uh_dport = htons(32768); (void) send_udp(nfd, 1500, ip, gwip); printf("32768\n"); fflush(stdout); PAUSE(); printf("4.4.5 UDP dport = 65535\n"); u->uh_dport = htons(65535); (void) send_udp(nfd, 1500, ip, gwip); printf("65535\n"); fflush(stdout); PAUSE(); } if (!ptest || (ptest == 5)) { /* * Test 5: sizeof(ip_t) <= MTU <= sizeof(udphdr_t) + * sizeof(ip_t) */ printf("4.5 UDP 20 <= MTU <= 32\n"); for (i = sizeof(*ip); i <= ntohs(u->uh_ulen); i++) { (void) send_udp(nfd, i, ip, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } } /* Perform test 5 (TCP) */ -void ip_test5(dev, mtu, ip, gwip, ptest) - char *dev; - int mtu; - ip_t *ip; - struct in_addr gwip; - int ptest; +void +ip_test5(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest) { #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif tcphdr_t *t; int nfd, i; t = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2)); t->th_x2 = 0; TCP_OFF_A(t, 0); t->th_sport = htons(1); t->th_dport = htons(1); t->th_win = htons(4096); t->th_urp = 0; t->th_sum = 0; t->th_seq = htonl(1); t->th_ack = 0; ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t); nfd = initdevice(dev, 1); if (nfd == -1) return; if (!ptest || (ptest == 1)) { /* * Test 1: flags variations, 0 - 3f */ TCP_OFF_A(t, sizeof(*t) >> 2); printf("5.1 Test TCP flag combinations\n"); for (i = 0; i <= (TH_URG|TH_ACK|TH_PUSH|TH_RST|TH_SYN|TH_FIN); i++) { t->th_flags = i; (void) send_tcp(nfd, mtu, ip, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } if (!ptest || (ptest == 2)) { t->th_flags = TH_SYN; /* * Test 2: seq = 0, seq = 1, seq = 0x7fffffff, seq=0x80000000, * seq = 0xa000000, seq = 0xffffffff */ printf("5.2.1 TCP seq = 0\n"); t->th_seq = htonl(0); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.2.2 TCP seq = 1\n"); t->th_seq = htonl(1); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.2.3 TCP seq = 0x7fffffff\n"); t->th_seq = htonl(0x7fffffff); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.2.4 TCP seq = 0x80000000\n"); t->th_seq = htonl(0x80000000); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.2.5 TCP seq = 0xc0000000\n"); t->th_seq = htonl(0xc0000000); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.2.6 TCP seq = 0xffffffff\n"); t->th_seq = htonl(0xffffffff); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); } if (!ptest || (ptest == 3)) { t->th_flags = TH_ACK; /* * Test 3: ack = 0, ack = 1, ack = 0x7fffffff, ack = 0x8000000 * ack = 0xa000000, ack = 0xffffffff */ printf("5.3.1 TCP ack = 0\n"); t->th_ack = 0; (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.3.2 TCP ack = 1\n"); t->th_ack = htonl(1); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.3.3 TCP ack = 0x7fffffff\n"); t->th_ack = htonl(0x7fffffff); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.3.4 TCP ack = 0x80000000\n"); t->th_ack = htonl(0x80000000); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.3.5 TCP ack = 0xc0000000\n"); t->th_ack = htonl(0xc0000000); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.3.6 TCP ack = 0xffffffff\n"); t->th_ack = htonl(0xffffffff); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); } if (!ptest || (ptest == 4)) { t->th_flags = TH_SYN; /* * Test 4: win = 0, win = 32768, win = 65535 */ printf("5.4.1 TCP win = 0\n"); t->th_seq = htonl(0); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.4.2 TCP win = 32768\n"); t->th_seq = htonl(0x7fff); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.4.3 TCP win = 65535\n"); t->th_win = htons(0xffff); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); } #if !defined(linux) && !defined(__SVR4) && !defined(__svr4__) && \ !defined(__sgi) && !defined(__hpux) && !defined(__osf__) { struct tcpcb *tcbp, tcb; struct tcpiphdr ti; struct sockaddr_in sin; int fd; socklen_t slen; bzero((char *)&sin, sizeof(sin)); for (i = 1; i < 63; i++) { fd = socket(AF_INET, SOCK_STREAM, 0); bzero((char *)&sin, sizeof(sin)); sin.sin_addr.s_addr = ip->ip_dst.s_addr; sin.sin_port = htons(i); sin.sin_family = AF_INET; if (!connect(fd, (struct sockaddr *)&sin, sizeof(sin))) break; close(fd); } if (i == 63) { printf("Couldn't open a TCP socket between ports 1 and 63\n"); printf("to host %s for test 5 and 6 - skipping.\n", inet_ntoa(ip->ip_dst)); goto skip_five_and_six; } bcopy((char *)ip, (char *)&ti, sizeof(*ip)); t->th_dport = htons(i); slen = sizeof(sin); if (!getsockname(fd, (struct sockaddr *)&sin, &slen)) t->th_sport = sin.sin_port; if (!(tcbp = find_tcp(fd, &ti))) { printf("Can't find PCB\n"); goto skip_five_and_six; } KMCPY(&tcb, tcbp, sizeof(tcb)); ti.ti_win = tcb.rcv_adv; ti.ti_seq = htonl(tcb.snd_nxt - 1); ti.ti_ack = tcb.rcv_nxt; if (!ptest || (ptest == 5)) { /* * Test 5: urp */ t->th_flags = TH_ACK|TH_URG; printf("5.5.1 TCP Urgent pointer, sport %hu dport %hu\n", ntohs(t->th_sport), ntohs(t->th_dport)); t->th_urp = htons(1); (void) send_tcp(nfd, mtu, ip, gwip); PAUSE(); t->th_seq = htonl(tcb.snd_nxt); ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t) + 1; t->th_urp = htons(0x7fff); (void) send_tcp(nfd, mtu, ip, gwip); PAUSE(); t->th_urp = htons(0x8000); (void) send_tcp(nfd, mtu, ip, gwip); PAUSE(); t->th_urp = htons(0xffff); (void) send_tcp(nfd, mtu, ip, gwip); PAUSE(); t->th_urp = 0; t->th_flags &= ~TH_URG; ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t); } if (!ptest || (ptest == 6)) { /* * Test 6: data offset, off = 0, off is inside, off is outside */ t->th_flags = TH_ACK; printf("5.6.1 TCP off = 1-15, len = 40\n"); for (i = 1; i < 16; i++) { TCP_OFF_A(t, ntohs(i)); (void) send_tcp(nfd, mtu, ip, gwip); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t); } (void) close(fd); } skip_five_and_six: #endif t->th_seq = htonl(1); t->th_ack = htonl(1); TCP_OFF_A(t, 0); if (!ptest || (ptest == 7)) { t->th_flags = TH_SYN; /* * Test 7: sport = 0, sport = 1, sport = 32767 * sport = 32768, sport = 65535 */ printf("5.7.1 TCP sport = 0\n"); t->th_sport = 0; (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.7.2 TCP sport = 1\n"); t->th_sport = htons(1); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.7.3 TCP sport = 32767\n"); t->th_sport = htons(32767); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.7.4 TCP sport = 32768\n"); t->th_sport = htons(32768); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.7.5 TCP sport = 65535\n"); t->th_sport = htons(65535); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); } if (!ptest || (ptest == 8)) { t->th_sport = htons(1); t->th_flags = TH_SYN; /* * Test 8: dport = 0, dport = 1, dport = 32767 * dport = 32768, dport = 65535 */ printf("5.8.1 TCP dport = 0\n"); t->th_dport = 0; (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.8.2 TCP dport = 1\n"); t->th_dport = htons(1); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.8.3 TCP dport = 32767\n"); t->th_dport = htons(32767); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.8.4 TCP dport = 32768\n"); t->th_dport = htons(32768); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); printf("5.8.5 TCP dport = 65535\n"); t->th_dport = htons(65535); (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); } /* LAND attack - self connect, so make src & dst ip/port the same */ if (!ptest || (ptest == 9)) { printf("5.9 TCP LAND attack. sport = 25, dport = 25\n"); /* chose SMTP port 25 */ t->th_sport = htons(25); t->th_dport = htons(25); t->th_flags = TH_SYN; ip->ip_src = ip->ip_dst; (void) send_tcp(nfd, mtu, ip, gwip); fflush(stdout); PAUSE(); } /* TCP options header checking */ /* 0 length options, etc */ } /* Perform test 6 (exhaust mbuf test) */ -void ip_test6(dev, mtu, ip, gwip, ptest) - char *dev; - int mtu; - ip_t *ip; - struct in_addr gwip; - int ptest; +void +ip_test6(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest) { #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif udphdr_t *u; int nfd, i, j, k; IP_V_A(ip, IPVERSION); ip->ip_tos = 0; ip->ip_off = 0; ip->ip_ttl = 60; ip->ip_p = IPPROTO_UDP; ip->ip_sum = 0; u = (udphdr_t *)(ip + 1); u->uh_sport = htons(1); u->uh_dport = htons(9); u->uh_sum = 0; nfd = initdevice(dev, 1); if (nfd == -1) return; u->uh_ulen = htons(7168); printf("6. Exhaustive mbuf test.\n"); printf(" Send 7k packet in 768 & 128 byte fragments, 128 times.\n"); printf(" Total of around 8,900 packets\n"); for (i = 0; i < 128; i++) { /* * First send the entire packet in 768 byte chunks. */ ip->ip_len = sizeof(*ip) + 768 + sizeof(*u); IP_HL_A(ip, sizeof(*ip) >> 2); ip->ip_off = htons(IP_MF); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d %d\r", i, 0); fflush(stdout); PAUSE(); /* * And again using 128 byte chunks. */ ip->ip_len = sizeof(*ip) + 128 + sizeof(*u); ip->ip_off = htons(IP_MF); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d %d\r", i, 0); fflush(stdout); PAUSE(); for (j = 768; j < 3584; j += 768) { ip->ip_len = sizeof(*ip) + 768; ip->ip_off = htons(IP_MF|(j>>3)); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d %d\r", i, j); fflush(stdout); PAUSE(); ip->ip_len = sizeof(*ip) + 128; for (k = j - 768; k < j; k += 128) { ip->ip_off = htons(IP_MF|(k>>3)); (void) send_ip(nfd, 1500, ip, gwip, 1); printf("%d %d\r", i, k); fflush(stdout); PAUSE(); } } } putchar('\n'); } /* Perform test 7 (random packets) */ static u_long tbuf[64]; -void ip_test7(dev, mtu, ip, gwip, ptest) - char *dev; - int mtu; - ip_t *ip; - struct in_addr gwip; - int ptest; +void +ip_test7(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest) { ip_t *pip; #ifdef USE_NANOSLEEP struct timespec ts; #else struct timeval tv; #endif int nfd, i, j; u_char *s; nfd = initdevice(dev, 1); if (nfd == -1) return; pip = (ip_t *)tbuf; srand(time(NULL) ^ (getpid() * getppid())); printf("7. send 1024 random IP packets.\n"); for (i = 0; i < 512; i++) { for (s = (u_char *)pip, j = 0; j < sizeof(tbuf); j++, s++) *s = (rand() >> 13) & 0xff; IP_V_A(pip, IPVERSION); bcopy((char *)&ip->ip_dst, (char *)&pip->ip_dst, sizeof(struct in_addr)); pip->ip_sum = 0; pip->ip_len &= 0xff; (void) send_ip(nfd, mtu, pip, gwip, 0); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); for (i = 0; i < 512; i++) { for (s = (u_char *)pip, j = 0; j < sizeof(tbuf); j++, s++) *s = (rand() >> 13) & 0xff; IP_V_A(pip, IPVERSION); pip->ip_off &= htons(0xc000); bcopy((char *)&ip->ip_dst, (char *)&pip->ip_dst, sizeof(struct in_addr)); pip->ip_sum = 0; pip->ip_len &= 0xff; (void) send_ip(nfd, mtu, pip, gwip, 0); printf("%d\r", i); fflush(stdout); PAUSE(); } putchar('\n'); } diff --git a/sbin/ipf/ipsend/resend.c b/sbin/ipf/ipsend/resend.c index 5d01bb78e5e5..537eb0a262b7 100644 --- a/sbin/ipf/ipsend/resend.c +++ b/sbin/ipf/ipsend/resend.c @@ -1,141 +1,138 @@ /* $FreeBSD$ */ /* * resend.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. * */ #if !defined(lint) static const char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include #include #include #include #include #include #include #include # include # include #include #include #include #include #include #include "ipsend.h" extern int opts; void dumppacket(ip_t *); -void dumppacket(ip) - ip_t *ip; +void +dumppacket(ip_t *ip) { tcphdr_t *t; int i, j; t = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2)); if (ip->ip_tos) printf("tos %#x ", ip->ip_tos); if (ip->ip_off & 0x3fff) printf("frag @%#x ", (ip->ip_off & 0x1fff) << 3); printf("len %d id %d ", ip->ip_len, ip->ip_id); printf("ttl %d p %d src %s", ip->ip_ttl, ip->ip_p, inet_ntoa(ip->ip_src)); if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) printf(",%d", t->th_sport); printf(" dst %s", inet_ntoa(ip->ip_dst)); if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) printf(",%d", t->th_dport); if (ip->ip_p == IPPROTO_TCP) { printf(" seq %lu:%lu flags ", (u_long)t->th_seq, (u_long)t->th_ack); for (j = 0, i = 1; i < 256; i *= 2, j++) if (t->th_flags & i) printf("%c", "FSRPAU--"[j]); } putchar('\n'); } -int ip_resend(dev, mtu, r, gwip, datain) - char *dev; - int mtu; - struct in_addr gwip; - struct ipread *r; - char *datain; +int +ip_resend(char *dev, int mtu, struct ipread *r, struct in_addr gwip, + char *datain) { ether_header_t *eh; char dhost[6]; ip_t *ip; int fd, wfd = initdevice(dev, 5), len, i; mb_t mb; if (wfd == -1) return -1; if (datain) fd = (*r->r_open)(datain); else fd = (*r->r_open)("-"); if (fd < 0) exit(-1); ip = (struct ip *)mb.mb_buf; eh = (ether_header_t *)malloc(sizeof(*eh)); if(!eh) { perror("malloc failed"); return -2; } bzero((char *) &eh->ether_shost, sizeof(eh->ether_shost)); if (gwip.s_addr && (arp((char *)&gwip, dhost) == -1)) { perror("arp"); free(eh); return -2; } while ((i = (*r->r_readip)(&mb, NULL, NULL)) > 0) { if (!(opts & OPT_RAW)) { len = ntohs(ip->ip_len); eh = (ether_header_t *)realloc((char *)eh, sizeof(*eh) + len); eh->ether_type = htons((u_short)ETHERTYPE_IP); if (!gwip.s_addr) { if (arp((char *)&gwip, (char *) &eh->ether_dhost) == -1) { perror("arp"); continue; } } else bcopy(dhost, (char *) &eh->ether_dhost, sizeof(dhost)); if (!ip->ip_sum) ip->ip_sum = chksum((u_short *)ip, IP_HL(ip) << 2); bcopy(ip, (char *)(eh + 1), len); len += sizeof(*eh); dumppacket(ip); } else { eh = (ether_header_t *)mb.mb_buf; len = i; } if (sendip(wfd, (char *)eh, len) == -1) { perror("send_packet"); break; } } (*r->r_close)(); free(eh); return 0; } diff --git a/sbin/ipf/ipsend/sbpf.c b/sbin/ipf/ipsend/sbpf.c index 27f239185d37..c1b8cc546961 100644 --- a/sbin/ipf/ipsend/sbpf.c +++ b/sbin/ipf/ipsend/sbpf.c @@ -1,150 +1,148 @@ /* $FreeBSD$ */ /* * (C)opyright 1995-1998 Darren Reed. (from tcplog) * * See the IPFILTER.LICENCE file for details on licencing. * */ #include #include #include #include #include #include #include #ifdef __FreeBSD__ # include #else # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __NetBSD__ # include #endif #include #include #include #include "ipsend.h" #if !defined(lint) static const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif /* * the code herein is dervied from libpcap. */ static u_char *buf = NULL; static int bufsize = 0, timeout = 1; -int initdevice(device, tout) - char *device; - int tout; +int +initdevice(char *device, int tout) { struct bpf_version bv; struct timeval to; struct ifreq ifr; #ifdef _PATH_BPF char *bpfname = _PATH_BPF; int fd; if ((fd = open(bpfname, O_RDWR)) < 0) { fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); return -1; } #else char bpfname[16]; int fd = 0, i; for (i = 0; i < 16; i++) { (void) snprintf(bpfname, sizeof(bpfname), "/dev/bpf%d", i); if ((fd = open(bpfname, O_RDWR)) >= 0) break; } if (i == 16) { fprintf(stderr, "no bpf devices available as /dev/bpfxx\n"); return -1; } #endif if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) { perror("BIOCVERSION"); return -1; } if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION) { fprintf(stderr, "kernel bpf (v%d.%d) filter out of date:\n", bv.bv_major, bv.bv_minor); fprintf(stderr, "current version: %d.%d\n", BPF_MAJOR_VERSION, BPF_MINOR_VERSION); return -1; } (void) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); if (ioctl(fd, BIOCSETIF, &ifr) == -1) { fprintf(stderr, "%s(%d):", ifr.ifr_name, fd); perror("BIOCSETIF"); exit(1); } /* * get kernel buffer size */ if (ioctl(fd, BIOCGBLEN, &bufsize) == -1) { perror("BIOCSBLEN"); exit(-1); } buf = (u_char*)malloc(bufsize); /* * set the timeout */ timeout = tout; to.tv_sec = 1; to.tv_usec = 0; if (ioctl(fd, BIOCSRTIMEOUT, (caddr_t)&to) == -1) { perror("BIOCSRTIMEOUT"); exit(-1); } (void) ioctl(fd, BIOCFLUSH, 0); return fd; } /* * output an IP packet onto a fd opened for /dev/bpf */ -int sendip(fd, pkt, len) - int fd, len; - char *pkt; +int +sendip(int fd, char *pkt, int len) { if (write(fd, pkt, len) == -1) { perror("send"); return -1; } return len; } diff --git a/sbin/ipf/ipsend/sdlpi.c b/sbin/ipf/ipsend/sdlpi.c index cd540337b2fa..10ef87ed509d 100644 --- a/sbin/ipf/ipsend/sdlpi.c +++ b/sbin/ipf/ipsend/sdlpi.c @@ -1,166 +1,166 @@ /* $FreeBSD$ */ /* * (C)opyright 1992-1998 Darren Reed. (from tcplog) * * See the IPFILTER.LICENCE file for details on licencing. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef sun # include # include #endif # include #include #include #include #include #include #include #include #include #include #include "ipsend.h" #if !defined(lint) static const char sccsid[] = "@(#)sdlpi.c 1.3 10/30/95 (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #define CHUNKSIZE 8192 #define BUFSPACE (4*CHUNKSIZE) /* * Be careful to only include those defined in the flags option for the * interface are included in the header size. */ -int initdevice(device, tout) - char *device; - int tout; +int +initdevice(char *device, int tout) { char devname[16], *s, buf[256]; int i, fd; (void) strcpy(devname, "/dev/"); (void) strncat(devname, device, sizeof(devname) - strlen(devname)); s = devname + 5; while (*s && !ISDIGIT(*s)) s++; if (!*s) { fprintf(stderr, "bad device name %s\n", devname); exit(-1); } i = atoi(s); *s = '\0'; /* * For writing */ if ((fd = open(devname, O_RDWR)) < 0) { fprintf(stderr, "O_RDWR(1) "); perror(devname); exit(-1); } if (dlattachreq(fd, i) == -1) { fprintf(stderr, "dlattachreq: DLPI error\n"); exit(-1); } else if (dlokack(fd, buf) == -1) { fprintf(stderr, "dlokack(attach): DLPI error\n"); exit(-1); } #ifdef DL_HP_RAWDLS if (dlpromisconreq(fd, DL_PROMISC_SAP) < 0) { fprintf(stderr, "dlpromisconreq: DL_PROMISC_PHYS error\n"); exit(-1); } else if (dlokack(fd, buf) < 0) { fprintf(stderr, "dlokack(promisc): DLPI error\n"); exit(-1); } /* 22 is INSAP as per the HP-UX DLPI Programmer's Guide */ dlbindreq(fd, 22, 1, DL_HP_RAWDLS, 0, 0); #else dlbindreq(fd, ETHERTYPE_IP, 0, DL_CLDLS, 0, 0); #endif dlbindack(fd, buf); /* * write full headers */ #ifdef DLIOCRAW /* we require RAW DLPI mode, which is a Sun extension */ if (strioctl(fd, DLIOCRAW, -1, 0, NULL) == -1) { fprintf(stderr, "DLIOCRAW error\n"); exit(-1); } #endif return fd; } /* * output an IP packet onto a fd opened for /dev/nit */ -int sendip(fd, pkt, len) +int +sendip(int fd, char *pkt, int len) int fd, len; char *pkt; { struct strbuf dbuf, *dp = &dbuf, *cp = NULL; int pri = 0; #ifdef DL_HP_RAWDLS struct strbuf cbuf; dl_hp_rawdata_req_t raw; cp = &cbuf; raw.dl_primitive = DL_HP_RAWDATA_REQ; cp->len = sizeof(raw); cp->buf = (char *)&raw; cp->maxlen = cp->len; pri = MSG_HIPRI; #endif /* * construct NIT STREAMS messages, first control then data. */ dp->buf = pkt; dp->len = len; dp->maxlen = dp->len; if (putmsg(fd, cp, dp, pri) == -1) { perror("putmsg"); return -1; } if (ioctl(fd, I_FLUSH, FLUSHW) == -1) { perror("I_FLUSHW"); return -1; } return len; } diff --git a/sbin/ipf/ipsend/snit.c b/sbin/ipf/ipsend/snit.c index 0d75b4e616f5..ae7491fcf54d 100644 --- a/sbin/ipf/ipsend/snit.c +++ b/sbin/ipf/ipsend/snit.c @@ -1,160 +1,160 @@ /* $FreeBSD$ */ /* * (C)opyright 1992-1998 Darren Reed. (from tcplog) * * See the IPFILTER.LICENCE file for details on licencing. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipsend.h" #if !defined(lint) static const char sccsid[] = "@(#)snit.c 1.5 1/11/96 (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #define CHUNKSIZE 8192 #define BUFSPACE (4*CHUNKSIZE) /* * Be careful to only include those defined in the flags option for the * interface are included in the header size. */ #define BUFHDR_SIZE (sizeof(struct nit_bufhdr)) #define NIT_HDRSIZE (BUFHDR_SIZE) static int timeout; -int initdevice(device, tout) - char *device; - int tout; +int +initdevice(char *device, int tout) { struct strioctl si; struct timeval to; struct ifreq ifr; int fd; if ((fd = open("/dev/nit", O_RDWR)) < 0) { perror("/dev/nit"); exit(-1); } /* * arrange to get messages from the NIT STREAM and use NIT_BUF option */ ioctl(fd, I_SRDOPT, (char*)RMSGD); ioctl(fd, I_PUSH, "nbuf"); /* * set the timeout */ timeout = tout; si.ic_timout = 1; to.tv_sec = 1; to.tv_usec = 0; si.ic_cmd = NIOCSTIME; si.ic_len = sizeof(to); si.ic_dp = (char*)&to; if (ioctl(fd, I_STR, (char*)&si) == -1) { perror("ioctl: NIT timeout"); exit(-1); } /* * request the interface */ strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' '; si.ic_cmd = NIOCBIND; si.ic_len = sizeof(ifr); si.ic_dp = (char*)𝔦 if (ioctl(fd, I_STR, (char*)&si) == -1) { perror(ifr.ifr_name); exit(1); } return fd; } /* * output an IP packet onto a fd opened for /dev/nit */ -int sendip(fd, pkt, len) +int +sendip(int fd, char *pkt, int len) int fd, len; char *pkt; { struct sockaddr sk, *sa = &sk; struct strbuf cbuf, *cp = &cbuf, dbuf, *dp = &dbuf; /* * For ethernet, need at least 802.3 header and IP header. */ if (len < (sizeof(sa->sa_data) + sizeof(struct ip))) return -1; /* * to avoid any output processing for IP, say we're not. */ sa->sa_family = AF_UNSPEC; bcopy(pkt, sa->sa_data, sizeof(sa->sa_data)); pkt += sizeof(sa->sa_data); len -= sizeof(sa->sa_data); /* * construct NIT STREAMS messages, first control then data. */ cp->len = sizeof(*sa); cp->maxlen = sizeof(*sa); cp->buf = (char *)sa; dp->buf = pkt; dp->len = len; dp->maxlen = dp->len; if (putmsg(fd, cp, dp, 0) == -1) { perror("putmsg"); return -1; } if (ioctl(fd, I_FLUSH, FLUSHW) == -1) { perror("I_FLUSH"); return -1; } return len; } diff --git a/sbin/ipf/ipsend/sock.c b/sbin/ipf/ipsend/sock.c index 7754ef9d8e1c..1104f51120fc 100644 --- a/sbin/ipf/ipsend/sock.c +++ b/sbin/ipf/ipsend/sock.c @@ -1,318 +1,313 @@ /* $FreeBSD$ */ /* * sock.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. * */ #if !defined(lint) static const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include #include #include #if defined(__NetBSD__) && defined(__vax__) /* * XXX need to declare boolean_t for _KERNEL * which ends up including for vax. See PR#32907 * for further details. */ typedef int boolean_t; #endif #include # include # ifdef __NetBSD__ # include # endif # ifdef __FreeBSD__ # define _WANT_FILE # else # define _KERNEL # define KERNEL # endif # include # ifdef __FreeBSD__ # undef _WANT_FILE # else # undef _KERNEL # undef KERNEL # endif #include #include #include #include #include # include #ifdef sun #include #include #endif #include #include #include #include #include #include #include #include #include # include #include #define _WANT_INPCB #include #include #define _WANT_TCPCB #include #include #include #include #include #include #include #include "ipsend.h" int nproc; struct proc *proc; #ifndef KMEM # ifdef _PATH_KMEM # define KMEM _PATH_KMEM # endif #endif #ifndef KERNEL # ifdef _PATH_UNIX # define KERNEL _PATH_UNIX # endif #endif #ifndef KMEM # define KMEM "/dev/kmem" #endif #ifndef KERNEL # define KERNEL "/vmunix" #endif static struct kinfo_proc *getproc(void); -int kmemcpy(buf, pos, n) - char *buf; - void *pos; - int n; +int +kmemcpy(char *buf, void *pos, int n) { static int kfd = -1; off_t offset = (u_long)pos; if (kfd == -1) kfd = open(KMEM, O_RDONLY); if (lseek(kfd, offset, SEEK_SET) == -1) { perror("lseek"); return -1; } if (read(kfd, buf, n) == -1) { perror("read"); return -1; } return n; } struct nlist names[4] = { { "_proc" }, { "_nproc" }, { NULL }, { NULL } }; -static struct kinfo_proc *getproc() +static struct +kinfo_proc *getproc(void) { static struct kinfo_proc kp; pid_t pid = getpid(); int mib[4]; size_t n; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; mib[3] = pid; n = sizeof(kp); if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1) { perror("sysctl"); return NULL; } return &kp; } -struct tcpcb *find_tcp(tfd, ti) - int tfd; - struct tcpiphdr *ti; +struct tcpcb * +find_tcp(int tfd, struct tcpiphdr *ti) { struct tcpcb *t; struct inpcb *i; struct socket *s; struct filedesc *fd; struct kinfo_proc *p; struct file *f, **o; if (!(p = getproc())) return NULL; fd = (struct filedesc *)malloc(sizeof(*fd)); if (fd == NULL) return NULL; #if defined( __FreeBSD__) if (KMCPY(fd, p->ki_fd, sizeof(*fd)) == -1) { fprintf(stderr, "read(%#lx,%#lx) failed\n", (u_long)p, (u_long)p->ki_fd); free(fd); return NULL; } #else if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1) { fprintf(stderr, "read(%#lx,%#lx) failed\n", (u_long)p, (u_long)p->kp_proc.p_fd); free(fd); return NULL; } #endif o = NULL; f = NULL; s = NULL; i = NULL; t = NULL; o = (struct file **)calloc(fd->fd_lastfile + 1, sizeof(*o)); if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) { fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n", (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o)); goto finderror; } f = (struct file *)calloc(1, sizeof(*f)); if (KMCPY(f, o[tfd], sizeof(*f)) == -1) { fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n", (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f)); goto finderror; } s = (struct socket *)calloc(1, sizeof(*s)); if (KMCPY(s, f->f_data, sizeof(*s)) == -1) { fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n", (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s)); goto finderror; } i = (struct inpcb *)calloc(1, sizeof(*i)); if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) { fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n", (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i)); goto finderror; } t = (struct tcpcb *)calloc(1, sizeof(*t)); if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) { fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n", (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t)); goto finderror; } return (struct tcpcb *)i->inp_ppcb; finderror: if (o != NULL) free(o); if (f != NULL) free(f); if (s != NULL) free(s); if (i != NULL) free(i); if (t != NULL) free(t); return NULL; } -int do_socket(dev, mtu, ti, gwip) - char *dev; - int mtu; - struct tcpiphdr *ti; - struct in_addr gwip; +int +do_socket(char *dev, int mtu, struct tcpiphdr *ti, struct in_addr gwip) { struct sockaddr_in rsin, lsin; struct tcpcb *t, tcb; int fd, nfd; socklen_t len; printf("Dest. Port: %d\n", ti->ti_dport); fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { perror("socket"); return -1; } if (fcntl(fd, F_SETFL, FNDELAY) == -1) { perror("fcntl"); return -1; } bzero((char *)&lsin, sizeof(lsin)); lsin.sin_family = AF_INET; bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, sizeof(struct in_addr)); if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) { perror("bind"); return -1; } len = sizeof(lsin); (void) getsockname(fd, (struct sockaddr *)&lsin, &len); ti->ti_sport = lsin.sin_port; printf("sport %d\n", ntohs(lsin.sin_port)); nfd = initdevice(dev, 1); if (nfd == -1) return -1; if (!(t = find_tcp(fd, ti))) return -1; bzero((char *)&rsin, sizeof(rsin)); rsin.sin_family = AF_INET; bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, sizeof(struct in_addr)); rsin.sin_port = ti->ti_dport; if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && errno != EINPROGRESS) { perror("connect"); return -1; } KMCPY(&tcb, t, sizeof(tcb)); ti->ti_win = tcb.rcv_adv; ti->ti_seq = tcb.snd_nxt - 1; ti->ti_ack = tcb.rcv_nxt; if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) return -1; (void)write(fd, "Hello World\n", 12); sleep(2); close(fd); return 0; } diff --git a/sbin/ipf/ipsend/sockraw.c b/sbin/ipf/ipsend/sockraw.c index c9232273ee86..1fd04a91002b 100644 --- a/sbin/ipf/ipsend/sockraw.c +++ b/sbin/ipf/ipsend/sockraw.c @@ -1,89 +1,90 @@ /* $FreeBSD$ */ /* * (C)opyright 2000 Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * WARNING: Attempting to use this .c file on HP-UX 11.00 will cause the * system to crash. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipsend.h" #if !defined(lint) && defined(LIBC_SCCS) static char sirix[] = "@(#)sirix.c 1.0 10/9/97 (C)1997 Marc Boucher"; #endif -int initdevice(char *device, int tout) +int +initdevice(char *device, int tout) { struct sockaddr s; struct ifreq ifr; int fd; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, device, sizeof ifr.ifr_name); if ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { perror("socket(AF_INET, SOCK_RAW, IPPROTO_RAW)"); return -1; } if (ioctl(fd, SIOCGIFADDR, &ifr) == -1) { perror("ioctl SIOCGIFADDR"); return -1; } bzero((char *)&s, sizeof(s)); s.sa_family = AF_INET; bcopy(&ifr.ifr_addr, s.sa_data, 4); if (bind(fd, &s, sizeof(s)) == -1) perror("bind"); return fd; } /* * output an IP packet */ int sendip(int fd, char *pkt, int len) { struct ether_header *eh; struct sockaddr_in sin; eh = (struct ether_header *)pkt; bzero((char *)&sin, sizeof(sin)); sin.sin_family = AF_INET; pkt += 14; len -= 14; bcopy(pkt + 12, (char *)&sin.sin_addr, 4); if (sendto(fd, pkt, len, 0, &sin, sizeof(sin)) == -1) { perror("send"); return -1; } return len; } diff --git a/sbin/ipf/libipf/addipopt.c b/sbin/ipf/libipf/addipopt.c index 26aff83f31b6..81429fbb84b7 100644 --- a/sbin/ipf/libipf/addipopt.c +++ b/sbin/ipf/libipf/addipopt.c @@ -1,65 +1,62 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -int addipopt(op, io, len, class) - char *op; - struct ipopt_names *io; - int len; - char *class; +int +addipopt(char *op, struct ipopt_names *io, int len, char *class) { int olen = len; struct in_addr ipadr; u_short val; u_char lvl; char *s; if ((len + io->on_siz) > 48) { fprintf(stderr, "options too long\n"); return 0; } len += io->on_siz; *op++ = io->on_value; if (io->on_siz > 1) { s = op; *op++ = io->on_siz; *op++ = IPOPT_MINOFF; if (class) { switch (io->on_value) { case IPOPT_SECURITY : lvl = seclevel(class); *(op - 1) = lvl; break; case IPOPT_RR : case IPOPT_TS : s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4; break; case IPOPT_LSRR : case IPOPT_SSRR : ipadr.s_addr = inet_addr(class); s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4; bcopy((char *)&ipadr, op, sizeof(ipadr)); break; case IPOPT_SATID : val = atoi(class); bcopy((char *)&val, op, 2); break; } } } if (opts & OPT_DEBUG) fprintf(stderr, "bo: %s %d %#x: %d\n", io->on_name, io->on_value, io->on_bit, len); return len - olen; } diff --git a/sbin/ipf/libipf/alist_free.c b/sbin/ipf/libipf/alist_free.c index 44dea1330f81..4b2e17aba84b 100644 --- a/sbin/ipf/libipf/alist_free.c +++ b/sbin/ipf/libipf/alist_free.c @@ -1,20 +1,19 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: alist_free.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" void -alist_free(hosts) - alist_t *hosts; +alist_free(alist_t *hosts) { alist_t *a, *next; for (a = hosts; a != NULL; a = next) { next = a->al_next; free(a); } } diff --git a/sbin/ipf/libipf/allocmbt.c b/sbin/ipf/libipf/allocmbt.c index df776842736c..ec00cb09b31e 100644 --- a/sbin/ipf/libipf/allocmbt.c +++ b/sbin/ipf/libipf/allocmbt.c @@ -1,22 +1,23 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: allocmbt.c,v 1.1.4.1 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" -mb_t *allocmbt(size_t len) +mb_t * +allocmbt(size_t len) { mb_t *m; m = (mb_t *)malloc(sizeof(mb_t)); if (m == NULL) return NULL; m->mb_len = len; m->mb_next = NULL; m->mb_data = (char *)m->mb_buf; return m; } diff --git a/sbin/ipf/libipf/assigndefined.c b/sbin/ipf/libipf/assigndefined.c index 34f8d9af3acc..991ca70736d9 100644 --- a/sbin/ipf/libipf/assigndefined.c +++ b/sbin/ipf/libipf/assigndefined.c @@ -1,27 +1,27 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: assigndefined.c,v 1.4.2.2 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" -void assigndefined(env) - char *env; +void +assigndefined(char *env) { char *s, *t; if (env == NULL) return; for (s = strtok(env, ";"); s != NULL; s = strtok(NULL, ";")) { t = strchr(s, '='); if (t == NULL) continue; *t++ = '\0'; set_variable(s, t); *--t = '='; } } diff --git a/sbin/ipf/libipf/bcopywrap.c b/sbin/ipf/libipf/bcopywrap.c index 453c0464846f..c704ef04e5ee 100644 --- a/sbin/ipf/libipf/bcopywrap.c +++ b/sbin/ipf/libipf/bcopywrap.c @@ -1,20 +1,19 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -int bcopywrap(from, to, size) - void *from, *to; - size_t size; +int +bcopywrap(void *from, void *to, size_t size) { bcopy((caddr_t)from, (caddr_t)to, size); return 0; } diff --git a/sbin/ipf/libipf/binprint.c b/sbin/ipf/libipf/binprint.c index f826721e0d21..131e3f62d481 100644 --- a/sbin/ipf/libipf/binprint.c +++ b/sbin/ipf/libipf/binprint.c @@ -1,31 +1,30 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -void binprint(ptr, size) - void *ptr; - size_t size; +void +binprint(void *ptr, size_t size) { u_char *s; int i, j; for (i = size, j = 0, s = (u_char *)ptr; i; i--, s++) { j++; printf("%02x ", *s); if (j == 16) { printf("\n"); j = 0; } } putchar('\n'); (void)fflush(stdout); } diff --git a/sbin/ipf/libipf/buildopts.c b/sbin/ipf/libipf/buildopts.c index 1d1de8c36784..2f16fcda049b 100644 --- a/sbin/ipf/libipf/buildopts.c +++ b/sbin/ipf/libipf/buildopts.c @@ -1,50 +1,49 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -u_32_t buildopts(cp, op, len) - char *cp, *op; - int len; +u_32_t +buildopts(char *cp, char *op, int len) { struct ipopt_names *io; u_32_t msk = 0; char *s, *t; int inc; for (s = strtok(cp, ","); s; s = strtok(NULL, ",")) { if ((t = strchr(s, '='))) *t++ = '\0'; else t = ""; for (io = ionames; io->on_name; io++) { if (strcasecmp(s, io->on_name) || (msk & io->on_bit)) continue; if ((inc = addipopt(op, io, len, t))) { op += inc; len += inc; } msk |= io->on_bit; break; } if (!io->on_name) { fprintf(stderr, "unknown IP option name %s\n", s); return 0; } } while ((len & 3) != 3) { *op++ = IPOPT_NOP; len++; } *op++ = IPOPT_EOL; len++; return len; } diff --git a/sbin/ipf/libipf/checkrev.c b/sbin/ipf/libipf/checkrev.c index b6f8eeec1fc2..6f73ec0c9573 100644 --- a/sbin/ipf/libipf/checkrev.c +++ b/sbin/ipf/libipf/checkrev.c @@ -1,46 +1,46 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include #include "ipf.h" #include "netinet/ipl.h" -int checkrev(ipfname) - char *ipfname; +int +checkrev(char *ipfname) { static int vfd = -1; struct friostat fio; ipfobj_t obj; bzero((caddr_t)&obj, sizeof(obj)); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_size = sizeof(fio); obj.ipfo_ptr = (void *)&fio; obj.ipfo_type = IPFOBJ_IPFSTAT; if ((vfd == -1) && ((vfd = open(ipfname, O_RDONLY)) == -1)) { perror("open device"); return -1; } if (ioctl(vfd, SIOCGETFS, &obj)) { ipferror(vfd, "ioctl(SIOCGETFS)"); close(vfd); vfd = -1; return -1; } if (strncmp(IPL_VERSION, fio.f_version, sizeof(fio.f_version))) { return -1; } return 0; } diff --git a/sbin/ipf/libipf/count4bits.c b/sbin/ipf/libipf/count4bits.c index a847388fad8e..f374928e7b0e 100644 --- a/sbin/ipf/libipf/count4bits.c +++ b/sbin/ipf/libipf/count4bits.c @@ -1,40 +1,40 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" /* * count consecutive 1's in bit mask. If the mask generated by counting * consecutive 1's is different to that passed, return -1, else return # * of bits. */ -int count4bits(ip) - u_int ip; +int +count4bits(u_int ip) { int cnt = 0, i, j; u_int ipn; ip = ipn = ntohl(ip); for (i = 32; i; i--, ipn *= 2) if (ipn & 0x80000000) cnt++; else break; ipn = 0; for (i = 32, j = cnt; i; i--, j--) { ipn *= 2; if (j > 0) ipn++; } if (ipn == ip) return cnt; return -1; } diff --git a/sbin/ipf/libipf/count6bits.c b/sbin/ipf/libipf/count6bits.c index b8f43206a8bd..ba624f4d8719 100644 --- a/sbin/ipf/libipf/count6bits.c +++ b/sbin/ipf/libipf/count6bits.c @@ -1,29 +1,29 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -int count6bits(msk) - u_32_t *msk; +int +count6bits(u_32_t *msk) { int i = 0, k; u_32_t j; for (k = 3; k >= 0; k--) if (msk[k] == 0xffffffff) i += 32; else { for (j = msk[k]; j; j <<= 1) if (j & 0x80000000) i++; } return i; } diff --git a/sbin/ipf/libipf/dupmbt.c b/sbin/ipf/libipf/dupmbt.c index 0929eeb54229..5a009d8e5a62 100644 --- a/sbin/ipf/libipf/dupmbt.c +++ b/sbin/ipf/libipf/dupmbt.c @@ -1,24 +1,24 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: dupmbt.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" -mb_t *dupmbt(orig) - mb_t *orig; +mb_t * +dupmbt(mb_t *orig) { mb_t *m; m = (mb_t *)malloc(sizeof(mb_t)); if (m == NULL) return NULL; m->mb_len = orig->mb_len; m->mb_next = NULL; m->mb_data = (char *)m->mb_buf + (orig->mb_data - (char *)orig->mb_buf); bcopy(orig->mb_data, m->mb_data, m->mb_len); return m; } diff --git a/sbin/ipf/libipf/facpri.c b/sbin/ipf/libipf/facpri.c index c9b47746b3ac..d892050f20d9 100644 --- a/sbin/ipf/libipf/facpri.c +++ b/sbin/ipf/libipf/facpri.c @@ -1,153 +1,149 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include #include #include #if !defined(__SVR4) && !defined(__svr4__) #include #endif #include #include #include #include #include "facpri.h" #if !defined(lint) static const char rcsid[] = "@(#)$Id$"; #endif typedef struct table { char *name; int value; } table_t; table_t facs[] = { { "kern", LOG_KERN }, { "user", LOG_USER }, { "mail", LOG_MAIL }, { "daemon", LOG_DAEMON }, { "auth", LOG_AUTH }, { "syslog", LOG_SYSLOG }, { "lpr", LOG_LPR }, { "news", LOG_NEWS }, { "uucp", LOG_UUCP }, #if LOG_CRON == LOG_CRON2 { "cron2", LOG_CRON1 }, #else { "cron", LOG_CRON1 }, #endif #ifdef LOG_FTP { "ftp", LOG_FTP }, #endif #ifdef LOG_AUTHPRIV { "authpriv", LOG_AUTHPRIV }, #endif #ifdef LOG_AUDIT { "audit", LOG_AUDIT }, #endif #ifdef LOG_LFMT { "logalert", LOG_LFMT }, #endif #if LOG_CRON == LOG_CRON1 { "cron", LOG_CRON2 }, #else { "cron2", LOG_CRON2 }, #endif #ifdef LOG_SECURITY { "security", LOG_SECURITY }, #endif { "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 }, { "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 }, { "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 }, { "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 }, { NULL, 0 } }; /* * map a facility number to its name */ char * -fac_toname(facpri) - int facpri; +fac_toname(int facpri) { int i, j, fac; fac = facpri & LOG_FACMASK; j = fac >> 3; if (j < (sizeof(facs)/sizeof(facs[0]))) { if (facs[j].value == fac) return facs[j].name; } for (i = 0; facs[i].name; i++) if (fac == facs[i].value) return facs[i].name; return NULL; } /* * map a facility name to its number */ int -fac_findname(name) - char *name; +fac_findname(char *name) { int i; for (i = 0; facs[i].name; i++) if (!strcmp(facs[i].name, name)) return facs[i].value; return -1; } table_t pris[] = { { "emerg", LOG_EMERG }, { "alert", LOG_ALERT }, { "crit", LOG_CRIT }, { "err", LOG_ERR }, { "warn", LOG_WARNING }, { "notice", LOG_NOTICE }, { "info", LOG_INFO }, { "debug", LOG_DEBUG }, { NULL, 0 } }; /* * map a facility name to its number */ int -pri_findname(name) - char *name; +pri_findname(char *name) { int i; for (i = 0; pris[i].name; i++) if (!strcmp(pris[i].name, name)) return pris[i].value; return -1; } /* * map a priority number to its name */ char * -pri_toname(facpri) - int facpri; +pri_toname(int facpri) { int i, pri; pri = facpri & LOG_PRIMASK; if (pris[pri].value == pri) return pris[pri].name; for (i = 0; pris[i].name; i++) if (pri == pris[i].value) return pris[i].name; return NULL; } diff --git a/sbin/ipf/libipf/familyname.c b/sbin/ipf/libipf/familyname.c index 891c6715ed0b..10cd0eaa1e83 100644 --- a/sbin/ipf/libipf/familyname.c +++ b/sbin/ipf/libipf/familyname.c @@ -1,12 +1,13 @@ #include "ipf.h" -const char *familyname(int family) +const char * +familyname(int family) { if (family == AF_INET) return "inet"; #ifdef USE_INET6 if (family == AF_INET6) return "inet6"; #endif return "unknown"; } diff --git a/sbin/ipf/libipf/fill6bits.c b/sbin/ipf/libipf/fill6bits.c index 39ec735f8ee9..b8f5914ef426 100644 --- a/sbin/ipf/libipf/fill6bits.c +++ b/sbin/ipf/libipf/fill6bits.c @@ -1,48 +1,47 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -void fill6bits(bits, msk) - int bits; - u_int *msk; +void +fill6bits(int bits, u_int *msk) { if (bits == 0) { msk[0] = 0; msk[1] = 0; msk[2] = 0; msk[3] = 0; return; } msk[0] = 0xffffffff; msk[1] = 0xffffffff; msk[2] = 0xffffffff; msk[3] = 0xffffffff; if (bits == 128) return; if (bits > 96) { msk[3] = htonl(msk[3] << (128 - bits)); } else if (bits > 64) { msk[3] = 0; msk[2] = htonl(msk[2] << (96 - bits)); } else if (bits > 32) { msk[3] = 0; msk[2] = 0; msk[1] = htonl(msk[1] << (64 - bits)); } else { msk[3] = 0; msk[2] = 0; msk[1] = 0; msk[0] = htonl(msk[0] << (32 - bits)); } } diff --git a/sbin/ipf/libipf/findword.c b/sbin/ipf/libipf/findword.c index e06f213c0540..8e836267db22 100644 --- a/sbin/ipf/libipf/findword.c +++ b/sbin/ipf/libipf/findword.c @@ -1,25 +1,24 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: findword.c,v 1.3.4.1 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" -wordtab_t *findword(words, name) - wordtab_t *words; - char *name; +wordtab_t * +findword(wordtab_t *words, char *name) { wordtab_t *w; for (w = words; w->w_word != NULL; w++) if (!strcmp(name, w->w_word)) break; if (w->w_word == NULL) return NULL; return w; } diff --git a/sbin/ipf/libipf/freembt.c b/sbin/ipf/libipf/freembt.c index 0fc748decd65..68daea842cd8 100644 --- a/sbin/ipf/libipf/freembt.c +++ b/sbin/ipf/libipf/freembt.c @@ -1,16 +1,16 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: freembt.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" -void freembt(m) - mb_t *m; +void +freembt(mb_t *m) { free(m); } diff --git a/sbin/ipf/libipf/ftov.c b/sbin/ipf/libipf/ftov.c index cb9715de450f..082a50e1c397 100644 --- a/sbin/ipf/libipf/ftov.c +++ b/sbin/ipf/libipf/ftov.c @@ -1,16 +1,15 @@ #include "ipf.h" int -ftov(version) - int version; +ftov(int version) { #ifdef USE_INET6 if (version == AF_INET6) return 6; #endif if (version == AF_INET) return 4; if (version == AF_UNSPEC) return 0; return -1; } diff --git a/sbin/ipf/libipf/gethost.c b/sbin/ipf/libipf/gethost.c index 14099e25c372..a66247701683 100644 --- a/sbin/ipf/libipf/gethost.c +++ b/sbin/ipf/libipf/gethost.c @@ -1,76 +1,74 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -int gethost(family, name, hostp) - int family; - char *name; - i6addr_t *hostp; +int +gethost(int family, char *name, i6addr_t *hostp) { struct hostent *h; struct netent *n; u_32_t addr; bzero(hostp, sizeof(*hostp)); if (!strcmp(name, "test.host.dots")) { if (family == AF_INET) { hostp->in4.s_addr = htonl(0xfedcba98); } #ifdef USE_INET6 if (family == AF_INET6) { hostp->i6[0] = htonl(0xfe80aa55); hostp->i6[1] = htonl(0x12345678); hostp->i6[2] = htonl(0x5a5aa5a5); hostp->i6[3] = htonl(0xfedcba98); } #endif return 0; } if (!strcmp(name, "")) name = thishost; if (family == AF_INET) { h = gethostbyname(name); if (h != NULL) { if ((h->h_addr != NULL) && (h->h_length == sizeof(addr))) { bcopy(h->h_addr, (char *)&addr, sizeof(addr)); hostp->in4.s_addr = addr; return 0; } } n = getnetbyname(name); if (n != NULL) { hostp->in4.s_addr = htonl(n->n_net & 0xffffffff); return 0; } } #ifdef USE_INET6 if (family == AF_INET6) { struct addrinfo hints, *res; struct sockaddr_in6 *sin6; bzero((char *)&hints, sizeof(hints)); hints.ai_family = PF_INET6; getaddrinfo(name, NULL, &hints, &res); if (res != NULL) { sin6 = (struct sockaddr_in6 *)res->ai_addr; hostp->in6 = sin6->sin6_addr; freeaddrinfo(res); return 0; } } #endif return -1; } diff --git a/sbin/ipf/libipf/geticmptype.c b/sbin/ipf/libipf/geticmptype.c index 5c962e949526..aa62d0a41909 100644 --- a/sbin/ipf/libipf/geticmptype.c +++ b/sbin/ipf/libipf/geticmptype.c @@ -1,29 +1,28 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -int geticmptype(family, name) - int family; - char *name; +int +geticmptype(int family, char *name) { icmptype_t *i; for (i = icmptypelist; i->it_name != NULL; i++) { if (!strcmp(name, i->it_name)) { if (family == AF_INET) return i->it_v4; #ifdef USE_INET6 if (family == AF_INET6) return i->it_v6; #endif return -1; } } return -1; } diff --git a/sbin/ipf/libipf/getifname.c b/sbin/ipf/libipf/getifname.c index 518950acd1a2..beb3795fbbb9 100644 --- a/sbin/ipf/libipf/getifname.c +++ b/sbin/ipf/libipf/getifname.c @@ -1,54 +1,54 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #include "kmem.h" /* * Given a pointer to an interface in the kernel, return a pointer to a * string which is the interface name. */ -char *getifname(ptr) - struct ifnet *ptr; +char * +getifname(struct ifnet *ptr) { #if SOLARIS # include # include # include "../pfil/qif.h" char *ifname; qif_t qif; if ((void *)ptr == (void *)-1) return "!"; if (ptr == NULL) return "-"; if (kmemcpy((char *)&qif, (u_long)ptr, sizeof(qif)) == -1) return "X"; ifname = strdup(qif.qf_name); if ((ifname != NULL) && (*ifname == '\0')) { free(ifname); return "!"; } return ifname; #else struct ifnet netif; if ((void *)ptr == (void *)-1) return "!"; if (ptr == NULL) return "-"; if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1) return "X"; return strdup(netif.if_xname); #endif } diff --git a/sbin/ipf/libipf/getnattype.c b/sbin/ipf/libipf/getnattype.c index 81364738e94a..44e1134a7f06 100644 --- a/sbin/ipf/libipf/getnattype.c +++ b/sbin/ipf/libipf/getnattype.c @@ -1,70 +1,69 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) */ #include "ipf.h" #include "kmem.h" #if !defined(lint) static const char rcsid[] = "@(#)$Id$"; #endif /* * Get a nat filter type given its kernel address. */ char * -getnattype(nat) - nat_t *nat; +getnattype(nat_t *nat) { static char unknownbuf[20]; char *which; if (!nat) return "???"; switch (nat->nat_redir) { case NAT_MAP : which = "MAP"; break; case NAT_MAPBLK : which = "MAP-BLOCK"; break; case NAT_REDIRECT : which = "RDR"; break; case NAT_MAP|NAT_REWRITE : which = "RWR-MAP"; break; case NAT_REDIRECT|NAT_REWRITE : which = "RWR-RDR"; break; case NAT_BIMAP : which = "BIMAP"; break; case NAT_REDIRECT|NAT_DIVERTUDP : which = "DIV-RDR"; break; case NAT_MAP|NAT_DIVERTUDP : which = "DIV-MAP"; break; case NAT_REDIRECT|NAT_ENCAP : which = "ENC-RDR"; break; case NAT_MAP|NAT_ENCAP : which = "ENC-MAP"; break; default : snprintf(unknownbuf, sizeof(unknownbuf), "unknown(%04x)", nat->nat_redir & 0xffffffff); which = unknownbuf; break; } return which; } diff --git a/sbin/ipf/libipf/getport.c b/sbin/ipf/libipf/getport.c index 0981ff172b96..d2a4ba7f9c1f 100644 --- a/sbin/ipf/libipf/getport.c +++ b/sbin/ipf/libipf/getport.c @@ -1,90 +1,88 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #include -int getport(fr, name, port, proto) - frentry_t *fr; - char *name, *proto; - u_short *port; +int +getport(frentry_t *fr, char *name, u_short *port, char *proto) { struct protoent *p; struct servent *s; u_short p1; if (fr == NULL || fr->fr_type != FR_T_IPF) { s = getservbyname(name, proto); if (s != NULL) { *port = s->s_port; return 0; } if (ISDIGIT(*name)) { int portval = atoi(name); if (portval < 0 || portval > 65535) return -1; *port = htons((u_short)portval); return 0; } return -1; } /* * Some people will use port names in rules without specifying * either TCP or UDP because it is implied by the group head. * If we don't know the protocol, then the best we can do here is * to take either only the TCP or UDP mapping (if one or the other * is missing) or make sure both of them agree. */ if (fr->fr_proto == 0) { s = getservbyname(name, "tcp"); if (s != NULL) p1 = s->s_port; else p1 = 0; s = getservbyname(name, "udp"); if (s != NULL) { if (p1 != s->s_port) return -1; } if ((p1 == 0) && (s == NULL)) return -1; if (p1) *port = p1; else *port = s->s_port; return 0; } if ((fr->fr_flx & FI_TCPUDP) != 0) { /* * If a rule is "tcp/udp" then check that both TCP and UDP * mappings for this protocol name match ports. */ s = getservbyname(name, "tcp"); if (s == NULL) return -1; p1 = s->s_port; s = getservbyname(name, "udp"); if (s == NULL || s->s_port != p1) return -1; *port = p1; return 0; } p = getprotobynumber(fr->fr_proto); s = getservbyname(name, p ? p->p_name : NULL); if (s != NULL) { *port = s->s_port; return 0; } return -1; } diff --git a/sbin/ipf/libipf/getportproto.c b/sbin/ipf/libipf/getportproto.c index 69fecff157fd..7835748175b7 100644 --- a/sbin/ipf/libipf/getportproto.c +++ b/sbin/ipf/libipf/getportproto.c @@ -1,40 +1,39 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include "ipf.h" -int getportproto(name, proto) - char *name; - int proto; +int +getportproto(char *name, int proto) { struct servent *s; struct protoent *p; if (ISDIGIT(*name)) { int number; char *s; for (s = name; *s != '\0'; s++) if (!ISDIGIT(*s)) return -1; number = atoi(name); if (number < 0 || number > 65535) return -1; return htons(number); } p = getprotobynumber(proto); s = getservbyname(name, p ? p->p_name : NULL); if (s != NULL) return s->s_port; return -1; } diff --git a/sbin/ipf/libipf/getproto.c b/sbin/ipf/libipf/getproto.c index f57fe06358fb..5432a60434f3 100644 --- a/sbin/ipf/libipf/getproto.c +++ b/sbin/ipf/libipf/getproto.c @@ -1,33 +1,35 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #include -int getproto(name) - char *name; +int getproto(char *name); + +int +getproto(char *name) { struct protoent *p; char *s; for (s = name; *s != '\0'; s++) if (!ISDIGIT(*s)) break; if (*s == '\0') return atoi(name); if (!strcasecmp(name, "ip")) return 0; p = getprotobyname(name); if (p != NULL) return p->p_proto; return -1; } diff --git a/sbin/ipf/libipf/getsumd.c b/sbin/ipf/libipf/getsumd.c index 53869131e694..d353e1189e34 100644 --- a/sbin/ipf/libipf/getsumd.c +++ b/sbin/ipf/libipf/getsumd.c @@ -1,23 +1,23 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -char *getsumd(sum) - u_32_t sum; +char * +getsumd(u_32_t sum) { static char sumdbuf[17]; if (sum & NAT_HW_CKSUM) snprintf(sumdbuf, sizeof(sumdbuf), "hw(%#0x)", sum & 0xffff); else snprintf(sumdbuf, sizeof(sumdbuf), "%#0x", sum); return sumdbuf; } diff --git a/sbin/ipf/libipf/icmptypename.c b/sbin/ipf/libipf/icmptypename.c index d7eb3bd3ab73..304b902a00e5 100644 --- a/sbin/ipf/libipf/icmptypename.c +++ b/sbin/ipf/libipf/icmptypename.c @@ -1,28 +1,28 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -char *icmptypename(family, type) - int family, type; +char * +icmptypename(int family, int type) { icmptype_t *i; if ((type < 0) || (type > 255)) return NULL; for (i = icmptypelist; i->it_name != NULL; i++) { if ((family == AF_INET) && (i->it_v4 == type)) return i->it_name; #ifdef USE_INET6 if ((family == AF_INET6) && (i->it_v6 == type)) return i->it_name; #endif } return NULL; } diff --git a/sbin/ipf/libipf/inet_addr.c b/sbin/ipf/libipf/inet_addr.c index 2b192ae19eff..0a29c775b964 100644 --- a/sbin/ipf/libipf/inet_addr.c +++ b/sbin/ipf/libipf/inet_addr.c @@ -1,204 +1,201 @@ /* $FreeBSD$ */ /* * ++Copyright++ 1983, 1990, 1993 * - * Copyright (c) 1983, 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */ #if !defined(lint) static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; static const char rcsid[] = "@(#)$Id: inet_addr.c,v 1.8.2.3 2004/12/09 19:41:20 darrenr Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #ifndef __P # define __P(x) x #endif int inet_aton(const char *, struct in_addr *); /* * Because the ctype(3) posix definition, if used "safely" in code everywhere, * would mean all normal code that walks through strings needed casts. Yuck. */ #define ISALNUM(x) isalnum((u_char)(x)) #define ISALPHA(x) isalpha((u_char)(x)) #define ISASCII(x) isascii((u_char)(x)) #define ISDIGIT(x) isdigit((u_char)(x)) #define ISPRINT(x) isprint((u_char)(x)) #define ISSPACE(x) isspace((u_char)(x)) #define ISUPPER(x) isupper((u_char)(x)) #define ISXDIGIT(x) isxdigit((u_char)(x)) #define ISLOWER(x) islower((u_char)(x)) /* * Check whether "cp" is a valid ascii representation * of an Internet address and convert to a binary address. * Returns 1 if the address is valid, 0 if not. * This replaces inet_addr, the return value from which * cannot distinguish between failure and a local broadcast address. */ int -inet_aton(cp, addr) - register const char *cp; - struct in_addr *addr; +inet_aton(register const char *cp, struct in_addr *addr) { register u_long val; register int base, n; register char c; u_int parts[4]; register u_int *pp = parts; c = *cp; for (;;) { /* * Collect number up to ``.''. * Values are specified as for C: * 0x=hex, 0=octal, isdigit=decimal. */ if (!ISDIGIT(c)) return (0); val = 0; base = 10; if (c == '0') { c = *++cp; if (c == 'x' || c == 'X') base = 16, c = *++cp; else base = 8; } for (;;) { if (ISASCII(c) && ISDIGIT(c)) { val = (val * base) + (c - '0'); c = *++cp; } else if (base == 16 && ISASCII(c) && ISXDIGIT(c)) { val = (val << 4) | (c + 10 - (ISLOWER(c) ? 'a' : 'A')); c = *++cp; } else break; } if (c == '.') { /* * Internet format: * a.b.c.d * a.b.c (with c treated as 16 bits) * a.b (with b treated as 24 bits) */ if (pp >= parts + 3) return (0); *pp++ = val; c = *++cp; } else break; } /* * Check for trailing characters. */ if (c != '\0' && (!ISASCII(c) || !ISSPACE(c))) return (0); /* * Concoct the address according to * the number of parts specified. */ n = pp - parts + 1; switch (n) { case 0: return (0); /* initial nondigit */ case 1: /* a -- 32 bits */ break; case 2: /* a.b -- 8.24 bits */ if (val > 0xffffff) return (0); val |= parts[0] << 24; break; case 3: /* a.b.c -- 8.8.16 bits */ if (val > 0xffff) return (0); val |= (parts[0] << 24) | (parts[1] << 16); break; case 4: /* a.b.c.d -- 8.8.8.8 bits */ if (val > 0xff) return (0); val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); break; } if (addr) addr->s_addr = htonl(val); return (1); } /* these are compatibility routines, not needed on recent BSD releases */ /* * Ascii internet address interpretation routine. * The value returned is in network order. */ #if 0 -inet_addr(cp) - const char *cp; +inet_addr(const char *cp) { struct in_addr val; if (inet_aton(cp, &val)) return (val.s_addr); return (0xffffffff); } #endif diff --git a/sbin/ipf/libipf/interror.c b/sbin/ipf/libipf/interror.c index 78ae4bf37849..c6e2e3dc03c3 100644 --- a/sbin/ipf/libipf/interror.c +++ b/sbin/ipf/libipf/interror.c @@ -1,582 +1,578 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: interror.c,v 1.9.2.12 2012/07/22 08:03:39 darren_r Exp $ */ #include "ipf.h" #include #include typedef struct { int iee_number; char *iee_text; } ipf_error_entry_t; static ipf_error_entry_t *find_error(int); #define IPF_NUM_ERRORS 475 /* * NO REUSE OF NUMBERS! * * IF YOU WANT TO ADD AN ERROR TO THIS TABLE, _ADD_ A NEW NUMBER. * DO _NOT_ USE AN EMPTY NUMBER OR FILL IN A GAP. */ static ipf_error_entry_t ipf_errors[IPF_NUM_ERRORS] = { { 1, "auth table locked/full" }, { 2, "" }, { 3, "copyinptr received bad address" }, { 4, "copyoutptr received bad address" }, { 5, "" }, { 6, "cannot load a rule with FR_T_BUILTIN flag set" }, { 7, "internal rule without FR_T_BUILDINT flag set" }, { 8, "no data provided with filter rule" }, { 9, "invalid ioctl for rule" }, { 10, "rule protocol is not 4 or 6" }, { 11, "cannot find rule function" }, { 12, "cannot find rule group" }, { 13, "group in/out does not match rule in/out" }, { 14, "rule without in/out does not belong to a group" }, { 15, "cannot determine where to append rule" }, { 16, "malloc for rule data failed" }, { 17, "copyin for rule data failed" }, { 18, "" }, { 19, "zero data size for BPF rule" }, { 20, "BPF validation failed" }, { 21, "incorrect data size for IPF rule" }, { 22, "'keep state' rule included 'with oow'" }, { 23, "bad interface index with dynamic source address" }, { 24, "bad interface index with dynamic dest. address" }, { 25, "match array verif failed for filter rule" }, { 26, "bad filter rule type" }, { 27, "rule not found for zero'stats" }, { 28, "copyout failed for zero'ing stats" }, { 29, "rule not found for removing" }, { 30, "cannot remove internal rule" }, { 31, "rule in use" }, { 32, "rule already exists" }, { 33, "no memory for another rule" }, { 34, "could not find function" }, { 35, "copyout failed for resolving function name -> addr" }, { 36, "copyout failed for resolving function addr -> name" }, { 37, "function name/addr resolving search failed" }, { 38, "group map cannot find it's hash table" }, { 39, "group map hash-table in/out do not match rule" }, { 40, "bcopyout failed for SIOCIPFINTERROR" }, { 41, "" }, { 42, "ipfilter not enabled for NAT ioctl" }, { 43, "ipfilter not enabled for state ioctl" }, { 44, "ipfilter not enabled for auth ioctl" }, { 45, "ipfilter not enbaled for sync ioctl" }, { 46, "ipfilter not enabled for scan ioctl" }, { 47, "ipfilter not enabled for lookup ioctl" }, { 48, "unrecognised device minor number for ioctl" }, { 49, "unrecognised object type for copying in ipfobj" }, { 50, "mismatching object type for copying in ipfobj" }, { 51, "object size too small for copying in ipfobj" }, { 52, "object size mismatch for copying in ipfobj" }, { 53, "compat object size too small for copying in ipfobj" }, { 54, "compat object size mismatch for copying in ipfobj" }, { 55, "error doing copyin of data for in ipfobj" }, { 56, "unrecognised object type for size copy in ipfobj" }, { 57, "object size too small for size copy in ipfobj" }, { 58, "mismatching object type for size copy in ipfobj" }, { 59, "object size mismatch for size copy in ipfobj" }, { 60, "compat object size mismatch for size copy in ipfobj" }, { 61, "error doing size copyin of data for in ipfobj" }, { 62, "bad object type for size copy out ipfobj" }, { 63, "mismatching object type for size copy out ipfobj" }, { 64, "object size mismatch for size copy out ipfobj" }, { 65, "compat object size wrong for size copy out ipfobj" }, { 66, "error doing size copyout of data for out ipfobj" }, { 67, "unrecognised object type for copying out ipfobj" }, { 68, "mismatching object type for copying out ipfobj" }, { 69, "object size too small for copying out ipfobj" }, { 70, "object size mismatch for copying out ipfobj" }, { 71, "compat object size too small for copying out ipfobj" }, { 72, "compat object size mismatch for copying out ipfobj" }, { 73, "error doing copyout of data for out ipfobj" }, { 74, "attempt to add existing tunable name" }, { 75, "cannot find tunable name to delete" }, { 76, "internal data too big for next tunable" }, { 77, "could not find tunable" }, { 78, "tunable can only be changed when ipfilter disabled" }, { 79, "new tunable value outside accepted range" }, { 80, "ipftune called for unrecognised ioctl" }, { 81, "" }, { 82, "could not find token to delete" }, { 83, "" }, { 84, "attempt to get next rule when no more exist" }, { 85, "value for iri_inout outside accepted range" }, { 86, "value for iri_active outside accepted range" }, { 87, "value for iri_nrules is 0" }, { 88, "NULL pointer specified for where to copy rule to" }, { 89, "copyout of rule failed" }, { 90, "" }, { 91, "could not get token for rule iteration" }, { 92, "unrecognised generic iterator" }, { 93, "could not find token for generic iterator" }, { 94, "need write permissions to disable/enable ipfilter" }, { 95, "error copying in enable/disable value" }, { 96, "need write permissions to set ipf tunable" }, { 97, "need write permissions to set ipf flags" }, { 98, "error doing copyin of ipf flags" }, { 99, "error doing copyout of ipf flags" }, { 100, "need write permissions to add another rule" }, { 101, "need write permissions to insert another rule" }, { 102, "need write permissions to swap active rule set" }, { 103, "error copying out current active rule set" }, { 104, "need write permissions to zero ipf stats" }, { 105, "need write permissions to flush ipf v4 rules" }, { 106, "error copying out v4 flush results" }, { 107, "error copying in v4 flush command" }, { 108, "need write permissions to flush ipf v6 rules" }, { 109, "error copying out v6 flush results" }, { 110, "error copying in v6 flush command" }, { 111, "error copying in new lock state for ipfilter" }, { 112, "need write permissions to flush ipf logs" }, { 113, "error copying out results of log flush" }, { 114, "need write permissions to resync ipf" }, { 115, "unrecognised ipf ioctl" }, { 116, "error copying in match array" }, { 117, "match array type is not IPFOBJ_IPFEXPR" }, { 118, "bad size for match array" }, { 119, "cannot allocate memory for match aray" }, { 120, "error copying in match array" }, { 121, "error verifying contents of match array" }, { 122, "need write permissions to set ipf lock status" }, { 123, "error copying in data for function resolution" }, { 124, "error copying in ipfobj structure" }, { 125, "error copying in ipfobj structure" }, { 126, "error copying in ipfobj structure" }, { 127, "error copying in ipfobj structure" }, { 128, "no memory for filter rule comment" }, { 129, "error copying in filter rule comment" }, { 130, "error copying out filter rule comment" }, { 131, "no memory for new rule alloc buffer" }, { 132, "cannot find source lookup pool" }, { 133, "unknown source address type" }, { 134, "cannot find destination lookup pool" }, { 135, "unknown destination address type" }, { 136, "icmp head group name index incorrect" }, { 137, "group head name index incorrect" }, { 138, "group name index incorrect" }, { 139, "to interface name index incorrect" }, { 140, "dup-to interface name index incorrect" }, { 141, "reply-to interface name index incorrect" }, { 142, "could not initialise call now function" }, { 143, "could not initialise call function" }, { 144, "could not find destination list" }, { 145, "auth rules cannot have dup/to/fastroute" }, { 146, "incorrect size for object to copy out" }, { 147, "object type out of bounds for kernel copyout" }, { 148, "object size too small for kernel copyout" }, { 149, "object size validation failed for kernel copyout" }, { 150, "error copying data out for kernel copyout" }, { 151, "version mismatch for kernel copyout" }, /* -------------------------------------------------------------------------- */ { 10001, "could not find token for auth iterator" }, { 10002, "write permissions require to add/remove auth rule" }, { 10003, "need write permissions to set auth lock" }, { 10004, "error copying out results of auth flush" }, { 10005, "unknown auth ioctl" }, { 10006, "can only append or remove preauth rules" }, { 10007, "NULL pointers passed in for preauth remove" }, { 10008, "preauth rule not found to remove" }, { 10009, "could not malloc memory for preauth entry" }, { 10010, "unrecognised preauth rule ioctl command" }, { 10011, "iterator data supplied with NULL pointer" }, { 10012, "unknown auth iterator type" }, { 10013, "iterator error copying out auth data" }, { 10014, "sleep waiting for auth packet interrupted" }, { 10015, "bad index supplied in auth reply" }, { 10016, "error injecting outbound packet back into kernel" }, { 10017, "error injecting inbound packet back into kernel" }, { 10018, "could not attempt to inject packet back into kernel" }, { 10019, "packet id does not match" }, /* -------------------------------------------------------------------------- */ { 20001, "invalid frag token data pointer supplied" }, { 20002, "error copying out frag token data" }, { 20003, "can only copy one fragment state entry at a time" }, /* -------------------------------------------------------------------------- */ { 30001, "incorrect object size to get hash table stats" }, { 30002, "could not malloc memory for new hash table" }, { 30003, "error coping in hash table structure" }, { 30004, "hash table already exists" }, { 30005, "mismach between new hash table and operation unit" }, { 30006, "could not malloc memory for hash table base" }, { 30007, "could not find hash table" }, { 30008, "mismatch between hash table and operation unit" }, { 30009, "could not find hash table for iterators next node" }, { 30010, "unknown iterator tpe" }, { 30011, "iterator error copying out hash table" }, { 30012, "iterator error copying out hash table entry" }, { 30013, "error copying out hash table statistics" }, { 30014, "table node delete structure wrong size" }, { 30015, "error copying in node to delete" }, { 30016, "table to delete node from does not exist" }, { 30017, "could not find table to remove node from" }, { 30018, "table node add structure wrong size" }, { 30019, "error copying in node to add" }, { 30020, "could not find table to add node to" }, { 30021, "node already exists in the table" }, { 30022, "could not find node to delete in table" }, { 30023, "uid mismatch on node to delete" }, { 30024, "object size incorrect for hash table" }, { 30025, "hash table size must be at least 1"}, { 30026, "cannot allocate memory for hash table context" }, /* -------------------------------------------------------------------------- */ { 40001, "invalid minor device numebr for log read" }, { 40002, "read size too small" }, { 40003, "interrupted waiting for log data to read" }, { 40004, "interrupted waiting for log data to read" }, { 40005, "read size too large" }, { 40006, "uiomove for read operation failed" }, /* -------------------------------------------------------------------------- */ { 50001, "unknown lookup ioctl" }, { 50002, "error copying in object data for add node" }, { 50003, "invalid unit for lookup add node" }, { 50004, "incorrect size for adding a pool node" }, { 50005, "error copying in pool node structure" }, { 50006, "mismatch in pool node address/mask families" }, { 50007, "could not find pool name" }, { 50008, "node already exists in pool" }, { 50009, "incorrect size for adding a hash node" }, { 50010, "error copying in hash node structure" }, { 50011, "could not find hash table name" }, { 50012, "unrecognised object type for lookup add node" }, { 50013, "invalid unit for lookup delete node" }, { 50014, "incorrect size for deleting a pool node" }, { 50015, "error copying in pool node structure" }, { 50016, "could not find pool name" }, { 50017, "could not find pool node" }, { 50018, "incorrect size for removing a hash node" }, { 50019, "error copying in hash node structure" }, { 50020, "could not find hash table name" }, { 50021, "unrecognised object type for lookup delete node" }, { 50022, "error copying in add table data" }, { 50023, "invalid unit for lookup add table" }, { 50024, "pool name already exists" }, { 50025, "hash table name already exists" }, { 50026, "unrecognised object type for lookup add table" }, { 50027, "error copying table data back out" }, { 50028, "error copying in remove table data" }, { 50029, "invalid unit for lookup remove table" }, { 50030, "unrecognised object type for lookup remove table" }, { 50031, "error copying in lookup stats structure" }, { 50032, "invalid unit for lookup stats" }, { 50033, "unrecognised object type for lookup stats" }, { 50034, "error copying in flush lookup data" }, { 50035, "invalid unit for lookup flush" }, { 50036, "incorrect table type for lookup flush" }, { 50037, "error copying out lookup flush results" }, { 50038, "invalid unit for lookup iterator" }, { 50039, "invalid unit for lookup iterator" }, { 50040, "could not find token for lookup iterator" }, { 50041, "unrecognised object type for lookup interator" }, { 50042, "error copying in lookup delete node operation" }, /* -------------------------------------------------------------------------- */ { 60001, "insufficient privilege for NAT write operation" }, { 60002, "need write permissions to flush NAT logs" }, { 60003, "need write permissions to turn NAT logging on/off" }, { 60004, "error copying out current NAT log setting" }, { 60005, "error copying out bytes waiting to be read in NAT \ log" }, { 60006, "need write permissions to add NAT rule" }, { 60007, "NAT rule already exists" }, { 60008, "could not allocate memory for NAT rule" }, { 60009, "need write permissions to remove NAT rule" }, { 60010, "NAT rule could not be found" }, { 60011, "could not find NAT entry for redirect lookup" }, { 60012, "need write permissions to flush NAT table" }, { 60013, "error copying in NAT flush command" }, { 60014, "need write permissions to do matching NAT flush" }, { 60015, "need write permissions to set NAT lock" }, { 60016, "need write permissions to add entry to NAT table" }, { 60017, "NAT not locked for size retrieval" }, { 60018, "NAT not locked for fetching NAT table entry" }, { 60019, "error copying in NAT token data for deletion" }, { 60020, "unknown NAT ioctl" }, { 60021, "" }, { 60022, "resolving proxy name in NAT rule failed" }, { 60023, "only reply age specified in NAT rule" }, { 60024, "error doing copyin to determine NAT entry size" }, { 60025, "error copying out NAT size of 0" }, { 60026, "NAT entry not found" }, { 60027, "error doing copyout of NAT entry size" }, { 60028, "invalid data size for getting NAT entry" }, { 60029, "could not malloc temporary space for NAT entry" }, { 60030, "no NAT table entries present" }, { 60031, "NAT entry to get next from not found" }, { 60032, "not enough space for proxy structure" }, { 60033, "not enough space for private proxy data" }, { 60034, "NAT entry size is too large" }, { 60035, "could not malloc memory for NAT entry sratch space" }, { 60036, "" }, { 60037, "could not malloc memory for NAT entry" }, { 60038, "could not malloc memory for NAT entry rule" }, { 60039, "could not resolve NAT entry rule's proxy" }, { 60040, "cannot add outbound duplicate NAT entry" }, { 60041, "cannot add inbound duplicate NAT entry" }, { 60042, "cannot add NAT entry that is neither IN nor OUT" }, { 60043, "could not malloc memory for NAT proxy data" }, { 60044, "proxy data size too big" }, { 60045, "could not malloc proxy private data for NAT entry" }, { 60046, "could not malloc memory for new NAT filter rule" }, { 60047, "could not find existing filter rule for NAT entry" }, { 60048, "insertion into NAT table failed" }, { 60049, "iterator error copying out hostmap data" }, { 60050, "iterator error copying out NAT rule data" }, { 60051, "iterator error copying out NAT entry data" }, { 60052, "iterator data supplied with NULL pointer" }, { 60053, "unknown NAT iterator type" }, { 60054, "unknwon next address type" }, { 60055, "iterator suppled with unknown type for get-next" }, { 60056, "unknown lookup group for next address" }, { 60057, "error copying out NAT log flush results" }, { 60058, "bucket table type is incorrect" }, { 60059, "error copying out NAT bucket table" }, { 60060, "function not found for lookup" }, { 60061, "address family not supported with SIOCSTPUT" }, { 60062, "unknown timeout name" }, { 60063, "cannot allocate new inbound NAT entry table" }, { 60064, "cannot allocate new outbound NAT entry table" }, { 60065, "cannot allocate new inbound NAT bucketlen table" }, { 60066, "cannot allocate new outbound NAT bucketlen table" }, { 60067, "cannot allocate new NAT rules table" }, { 60068, "cannot allocate new NAT hostmap table" }, { 60069, "new source lookup type is not dstlist" }, { 60070, "cannot allocate NAT rule scratch space" }, { 60071, "new destination lookup type is not dstlist" }, { 60072, "function not found for lookup (ipv6)" }, { 60073, "unknown lookup group for next address (ipv6)" }, { 60074, "unknown next address type (ipv6)" }, { 60075, "one object at a time must be copied" }, /* -------------------------------------------------------------------------- */ { 70001, "incorrect object size to get pool stats" }, { 70002, "could not malloc memory for new pool node" }, { 70003, "invalid address length for new pool node" }, { 70004, "invalid mask length for new pool node" }, { 70005, "error adding node to pool" }, { 70006, "pool already exists" }, { 70007, "could not malloc memory for new pool" }, { 70008, "could not allocate radix tree for new pool" }, { 70009, "could not find pool" }, { 70010, "unknown pool name for iteration" }, { 70011, "unknown pool iterator" }, { 70012, "error copying out pool head" }, { 70013, "error copying out pool node" }, { 70014, "add node size incorrect" }, { 70015, "error copying in pool node" }, { 70016, "" }, { 70017, "cannot find pool for node" }, { 70018, "node entry already present in pool" }, { 70019, "delete node size incorrect" }, { 70020, "error copying in node to delete" }, { 70021, "cannot find pool to delete node from" }, { 70022, "cannot find node to delete in pool" }, { 70023, "pool name already exists" }, { 70024, "uid mismatch for node removal" }, { 70025, "stats device unit is invalid" }, { 70026, "error copying out statistics" }, { 70027, "could not remove node from radix tree" }, { 70028, "incorrect address length in pool node add" }, { 70029, "incorrect mask length in pool node add" }, { 70030, "incorrect address length in pool node remove" }, { 70031, "incorrect mask length in pool node remove" }, { 70032, "cannot allocate memory for pool context" }, { 70033, "cannot allocate memory for radix tree context" }, { 70034, "adding IPv6 node with incorrect address length" }, { 70035, "IPv4 address not masked" }, { 70036, "IPv6 address not masked" }, { 70037, "removing IPv6 node with incorrect address length" }, /* -------------------------------------------------------------------------- */ { 80001, "could not find proxy" }, { 80002, "proxy does not support control operations" }, { 80003, "could not allocate data to hold proxy operation" }, { 80004, "unknown proxy ioctl" }, { 80005, "could not copyin proxy control structure" }, { 80006, "DNS proxy could not find rule to delete" }, { 80007, "DNS proxy found existing matching rule" }, { 80008, "DNS proxy could not allocate memory for new rule" }, { 80009, "DNS proxy unknown command request" }, /* -------------------------------------------------------------------------- */ { 90001, "could not malloc space for new scan structure" }, { 90002, "scan tag already exists" }, { 90003, "scan structure in use" }, { 90004, "could not find matching scan tag for filter rule" }, { 90005, "could not copyout scan statistics" }, /* -------------------------------------------------------------------------- */ { 100001, "cannot find matching state entry to remove" }, { 100002, "error copying in v4 state flush command" }, { 100003, "error copying out v4 state flush results" }, { 100004, "error copying in v6 state flush command" }, { 100005, "error copying out v6 state flush results" }, { 100006, "" }, { 100007, "" }, { 100008, "need write permissions to flush state log" }, { 100009, "erorr copyout results of flushing state log" }, { 100010, "need write permissions to turn state logging on/off" }, { 100011, "error copying in new state logging state" }, { 100012, "error copying out current state logging state" }, { 100013, "error copying out bytes waiting to be read in state \ log" }, { 100014, "need write permissions to set state lock" }, { 100015, "need write permissions to add entry to state table" }, { 100016, "state not locked for size retrieval" }, { 100017, "error copying out hash table bucket lengths" }, { 100018, "could not find token for state iterator" }, { 100019, "error copying in state token data for deletion" }, { 100020, "unknown state ioctl" }, { 100021, "no state table entries present" }, { 100022, "state entry to get next from not found" }, { 100023, "could not malloc memory for state entry" }, { 100024, "could not malloc memory for state entry rule" }, { 100025, "could not copy back state entry to user space" }, { 100026, "iterator data supplied with NULL pointer" }, { 100027, "iterator supplied with 0 item count" }, { 100028, "iterator type is incorrect" }, { 100029, "invalid state token data pointer supplied" }, { 100030, "error copying out next state entry" }, { 100031, "unrecognised table request" }, { 100032, "error copying out bucket length data" }, { 100033, "could not find existing filter rule for state entry" }, { 100034, "could not find timeout name" }, { 100035, "could not allocate new state table" }, { 100036, "could not allocate new state bucket length table" }, /* -------------------------------------------------------------------------- */ { 110001, "sync write header magic number is incorrect" }, { 110002, "sync write header protocol is incorrect" }, { 110003, "sync write header command is incorrect" }, { 110004, "sync write header table number is incorrect" }, { 110005, "data structure too small for sync write operation" }, { 110006, "zero length data with sync write header" }, { 110007, "insufficient data for sync write" }, { 110008, "bad sync read size" }, { 110009, "interrupted sync read (solaris)" }, { 110010, "interrupted sync read (hpux)" }, { 110011, "interrupted sync read (osf)" }, { 110012, "interrupted sync read" }, { 110013, "could not malloc memory for sync'd state" }, { 110014, "could not malloc memory for sync-state list item" }, { 110015, "sync update could not find state" }, { 110016, "unrecognised sync state command" }, { 110017, "could not malloc memory for new sync'd NAT entry" }, { 110018, "could not malloc memory for sync-NAT list item" }, { 110019, "sync update could not find NAT entry" }, { 110020, "unrecognised sync NAT command" }, { 110021, "ioctls are not handled with sync" }, /* -------------------------------------------------------------------------- */ { 120001, "null data pointer for iterator" }, { 120002, "unit outside of acceptable range" }, { 120003, "unknown iterator subtype" }, { 120004, "cannot find dest. list for iteration" }, { 120005, "error copying out destination iteration list" }, { 120006, "error copying out destination iteration node" }, { 120007, "wrong size for frdest_t structure" }, { 120008, "cannot allocate memory for new destination node" }, { 120009, "error copying in destination node to add" }, { 120010, "could not find destination list to add node to" }, { 120011, "error copying in destination node to remove" }, { 120012, "could not find dest. list to remove node from" }, { 120013, "destination list already exists" }, { 120014, "could not allocate new destination table" }, { 120015, "could not find destination list to remove" }, { 120016, "destination list cannot be removed - it is busy" }, { 120017, "error copying in names for destination" }, { 120018, "destination name is too long/short" }, { 120019, "unrecognised address family in destination" }, { 120020, "" }, { 120021, "error copying in new destination table" }, { 120022, "cannot allocate memory for node table" }, { 120023, "stats object size is incorrect for dest. lists" }, { 120024, "stats device unit is invalid for dest. lists" }, { 120025, "error copying out dest. list statistics" }, { 120026, "cannot allocate memory for destination node" }, { 120027, "error copying in destination node" }, { 120028, "cannot allocate memory for destination context " }, /* -------------------------------------------------------------------------- */ { 130001, "ioctl denied by system security level" }, { 130002, "ioctl operation on invalid minor device" }, { 130003, "ioctl on device denied, ipfitler is disabled" }, { 130004, "ioctl command not allowed when disabled" }, { 130005, "ioctl denied due to insufficient authorisation" }, { 130006, "cannot read while ipfilter is disabled" }, { 130007, "read on minor device not supported" }, { 130008, "cannot write while ipfilter is disabled" }, { 130009, "write on minor device not supported" }, { 130010, "poll on minor device is not supported" }, { 130011, "error removing IPv4 filter hooks" }, { 130012, "error removing IPv6 filter hooks" }, { 130013, "attaching IPv4 hook failed" }, { 130014, "attaching IPv6 hook failed" }, { 130015, "ipf_init_all failed" }, { 130016, "finding pfil head failed" }, { 130017, "ipfilter is already initialised and running" }, }; static ipf_error_entry_t * -find_error(errnum) - int errnum; +find_error(int errnum) { ipf_error_entry_t *ie; int l = -1, r = IPF_NUM_ERRORS + 1, step; step = (r - l) / 2;; while (step != 0) { ie = ipf_errors + l + step; if (ie->iee_number == errnum) return ie; step = l + step; if (ie->iee_number > errnum) r = step; else l = step; step = (r - l) / 2;; } return NULL; } char * -ipf_geterror(fd, func) - int fd; - ioctlfunc_t *func; +ipf_geterror(int fd, ioctlfunc_t *func) { static char text[80]; ipf_error_entry_t *ie; int errnum; if ((*func)(fd, SIOCIPFINTERROR, &errnum) == 0) { ie = find_error(errnum); if (ie != NULL) return ie->iee_text; snprintf(text, sizeof(text), "unknown error %d", errnum); } else { snprintf(text, sizeof(text), "retrieving error number failed (%d)", errno); } return text; } char * -ipf_strerror(errnum) - int errnum; +ipf_strerror(int errnum) { static char text[80]; ipf_error_entry_t *ie; ie = find_error(errnum); if (ie != NULL) return ie->iee_text; snprintf(text, sizeof(text), "unknown error %d", errnum); return text; } diff --git a/sbin/ipf/libipf/ipf_dotuning.c b/sbin/ipf/libipf/ipf_dotuning.c index b0ac8b42a2f8..c7064cfbefef 100644 --- a/sbin/ipf/libipf/ipf_dotuning.c +++ b/sbin/ipf/libipf/ipf_dotuning.c @@ -1,74 +1,71 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #include "netinet/ipl.h" #include -void ipf_dotuning(fd, tuneargs, iocfn) - int fd; - char *tuneargs; - ioctlfunc_t iocfn; +void ipf_dotuning(int fd, char *tuneargs, ioctlfunc_t iocfn) { ipfobj_t obj; ipftune_t tu; char *s, *t; bzero((char *)&tu, sizeof(tu)); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_size = sizeof(tu);; obj.ipfo_ptr = (void *)&tu; obj.ipfo_type = IPFOBJ_TUNEABLE; for (s = strtok(tuneargs, ","); s != NULL; s = strtok(NULL, ",")) { if (!strcmp(s, "list")) { while (1) { if ((*iocfn)(fd, SIOCIPFGETNEXT, &obj) == -1) { ipf_perror_fd(fd, iocfn, "ioctl(SIOCIPFGETNEXT)"); break; } if (tu.ipft_cookie == NULL) break; tu.ipft_name[sizeof(tu.ipft_name) - 1] = '\0'; printtunable(&tu); } } else if ((t = strchr(s, '=')) != NULL) { tu.ipft_cookie = NULL; *t++ = '\0'; strncpy(tu.ipft_name, s, sizeof(tu.ipft_name)); if (sscanf(t, "%lu", &tu.ipft_vlong) == 1) { if ((*iocfn)(fd, SIOCIPFSET, &obj) == -1) { ipf_perror_fd(fd, iocfn, "ioctl(SIOCIPFSET)"); return; } } else { fprintf(stderr, "invalid value '%s'\n", s); return; } } else { tu.ipft_cookie = NULL; strncpy(tu.ipft_name, s, sizeof(tu.ipft_name)); if ((*iocfn)(fd, SIOCIPFGET, &obj) == -1) { ipf_perror_fd(fd, iocfn, "ioctl(SIOCIPFGET)"); return; } if (tu.ipft_cookie == NULL) { fprintf(stderr, "Null cookie for %s\n", s); return; } tu.ipft_name[sizeof(tu.ipft_name) - 1] = '\0'; printtunable(&tu); } } } diff --git a/sbin/ipf/libipf/ipf_perror.c b/sbin/ipf/libipf/ipf_perror.c index 08e31648b053..13fc5f0296e4 100644 --- a/sbin/ipf/libipf/ipf_perror.c +++ b/sbin/ipf/libipf/ipf_perror.c @@ -1,47 +1,40 @@ #include #include #include "ipf.h" void -ipf_perror(err, string) - int err; - char *string; +ipf_perror(int err, char *string) { if (err == 0) fprintf(stderr, "%s\n", string); else fprintf(stderr, "%s: %s\n", string, ipf_strerror(err)); } int -ipf_perror_fd(fd, iocfunc, string) - int fd; - ioctlfunc_t iocfunc; - char *string; +ipf_perror_fd( int fd, ioctlfunc_t iocfunc, char *string) { int save; int realerr; save = errno; if ((*iocfunc)(fd, SIOCIPFINTERROR, &realerr) == -1) realerr = 0; errno = save; fprintf(stderr, "%d:", realerr); ipf_perror(realerr, string); return realerr ? realerr : save; } void -ipferror(fd, msg) - int fd; - char *msg; +ipferror(int fd, char *msg) { if (fd >= 0) { ipf_perror_fd(fd, ioctl, msg); } else { fprintf(stderr, "0:"); perror(msg); } } diff --git a/sbin/ipf/libipf/ipft_hx.c b/sbin/ipf/libipf/ipft_hx.c index e424c3929c79..8b27ddd33bd6 100644 --- a/sbin/ipf/libipf/ipft_hx.c +++ b/sbin/ipf/libipf/ipft_hx.c @@ -1,183 +1,182 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) static const char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include "ipf.h" #include "ipt.h" extern int opts; static int hex_open(char *); static int hex_close(void); static int hex_readip(mb_t *, char **, int *); static char *readhex(char *, char *); struct ipread iphex = { hex_open, hex_close, hex_readip, 0 }; static FILE *tfp = NULL; static int tfd = -1; -static int hex_open(fname) - char *fname; +static int +hex_open(char *fname) { if (tfp && tfd != -1) { rewind(tfp); return tfd; } if (!strcmp(fname, "-")) { tfd = 0; tfp = stdin; } else { tfd = open(fname, O_RDONLY); if (tfd != -1) tfp = fdopen(tfd, "r"); } return tfd; } -static int hex_close() +static int +hex_close(void) { int cfd = tfd; tfd = -1; return close(cfd); } -static int hex_readip(mb, ifn, dir) - mb_t *mb; - char **ifn; - int *dir; +static int +hex_readip(mb_t *mb, char **ifn, int *dir) { register char *s, *t, *u; char line[513]; ip_t *ip; char *buf; buf = (char *)mb->mb_buf; /* * interpret start of line as possibly "[ifname]" or * "[in/out,ifname]". */ if (ifn) *ifn = NULL; if (dir) *dir = 0; ip = (ip_t *)buf; while (fgets(line, sizeof(line)-1, tfp)) { if ((s = strchr(line, '\n'))) { if (s == line) { mb->mb_len = (char *)ip - buf; return mb->mb_len; } *s = '\0'; } if ((s = strchr(line, '#'))) *s = '\0'; if (!*line) continue; if ((opts & OPT_DEBUG) != 0) { printf("input: %s", line); } if ((*line == '[') && (s = strchr(line, ']'))) { t = line + 1; if (s - t > 0) { *s++ = '\0'; if ((u = strchr(t, ',')) && (u < s)) { u++; if (ifn) *ifn = strdup(u); if (dir) { if (*t == 'i') *dir = 0; else if (*t == 'o') *dir = 1; } } else if (ifn) *ifn = t; } while (*s++ == '+') { if (!strncasecmp(s, "mcast", 5)) { mb->mb_flags |= M_MCAST; s += 5; } if (!strncasecmp(s, "bcast", 5)) { mb->mb_flags |= M_BCAST; s += 5; } if (!strncasecmp(s, "mbcast", 6)) { mb->mb_flags |= M_MBCAST; s += 6; } } while (ISSPACE(*s)) s++; } else s = line; t = (char *)ip; ip = (ip_t *)readhex(s, (char *)ip); if ((opts & OPT_DEBUG) != 0) { if (opts & OPT_ASCII) { int c = *t; if (t < (char *)ip) putchar('\t'); while (t < (char *)ip) { if (isprint(c) && isascii(c)) putchar(c); else putchar('.'); t++; } } putchar('\n'); fflush(stdout); } } if (feof(tfp)) return 0; return -1; } -static char *readhex(src, dst) -register char *src, *dst; +static char +*readhex(register char *src, register char *dst) { int state = 0; char c; while ((c = *src++)) { if (ISSPACE(c)) { if (state) { dst++; state = 0; } continue; } else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { c = ISDIGIT(c) ? (c - '0') : (TOUPPER(c) - 55); if (state == 0) { *dst = (c << 4); state++; } else { *dst++ |= c; state = 0; } } else break; } return dst; } diff --git a/sbin/ipf/libipf/ipft_pc.c b/sbin/ipf/libipf/ipft_pc.c index 65eee078bd06..9fab5234d18c 100644 --- a/sbin/ipf/libipf/ipft_pc.c +++ b/sbin/ipf/libipf/ipft_pc.c @@ -1,251 +1,249 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #include "ipt.h" #if !defined(lint) static const char rcsid[] = "@(#)$Id$"; #endif struct llc { int lc_type; int lc_sz; /* LLC header length */ int lc_to; /* LLC Type offset */ int lc_tl; /* LLC Type length */ }; /* * While many of these maybe the same, some do have different header formats * which make this useful. */ static struct llc llcs[] = { { 0, 0, 0, 0 }, /* DLT_NULL */ { 1, 14, 12, 2 }, /* DLT_Ethernet */ { 10, 0, 0, 0 }, /* DLT_FDDI */ { 12, 0, 0, 0 }, /* DLT_RAW */ { -1, -1, -1, -1 } }; typedef struct { u_int id; u_short major; u_short minor; u_int timezone; u_int sigfigs; u_int snaplen; u_int type; } fileheader_t; typedef struct { u_32_t seconds; u_32_t microseconds; u_32_t caplen; u_32_t wirelen; } packetheader_t; static int ipcap_open(char *); static int ipcap_close(void); static int ipcap_readip(mb_t *, char **, int *); static int ipcap_read_rec(packetheader_t *); static void iswap_hdr(fileheader_t *); static int pfd = -1, swapped = 0; static struct llc *llcp = NULL; struct ipread pcap = { ipcap_open, ipcap_close, ipcap_readip, 0 }; #define SWAPLONG(y) \ ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) #define SWAPSHORT(y) \ ( (((y)&0xff)<<8) | (((y)&0xff00)>>8) ) -static void iswap_hdr(p) - fileheader_t *p; +static void +iswap_hdr(fileheader_t *p) { p->major = SWAPSHORT(p->major); p->minor = SWAPSHORT(p->minor); p->timezone = SWAPLONG(p->timezone); p->sigfigs = SWAPLONG(p->sigfigs); p->snaplen = SWAPLONG(p->snaplen); p->type = SWAPLONG(p->type); } -static int ipcap_open(fname) - char *fname; +static int +ipcap_open(char *fname) { fileheader_t ph; int fd, i; if (pfd != -1) return pfd; if (!strcmp(fname, "-")) fd = 0; else if ((fd = open(fname, O_RDONLY)) == -1) return -1; if (read(fd, (char *)&ph, sizeof(ph)) != sizeof(ph)) return -2; if (ph.id != 0xa1b2c3d4) { if (SWAPLONG(ph.id) != 0xa1b2c3d4) { (void) close(fd); return -2; } swapped = 1; iswap_hdr(&ph); } for (i = 0; llcs[i].lc_type != -1; i++) if (llcs[i].lc_type == ph.type) { llcp = llcs + i; break; } if (llcp == NULL) { (void) close(fd); return -2; } pfd = fd; printf("opened pcap file %s:\n", fname); printf("\tid: %08x version: %d.%d type: %d snap %d\n", ph.id, ph.major, ph.minor, ph.type, ph.snaplen); return fd; } -static int ipcap_close() +static int +ipcap_close(void) { return close(pfd); } /* * read in the header (and validate) which should be the first record * in a pcap file. */ -static int ipcap_read_rec(rec) - packetheader_t *rec; +static int +ipcap_read_rec(packetheader_t *rec) { int n, p, i; n = sizeof(*rec); while (n > 0) { i = read(pfd, (char *)rec, sizeof(*rec)); if (i <= 0) return -2; n -= i; } if (swapped) { rec->caplen = SWAPLONG(rec->caplen); rec->wirelen = SWAPLONG(rec->wirelen); rec->seconds = SWAPLONG(rec->seconds); rec->microseconds = SWAPLONG(rec->microseconds); } p = rec->caplen; n = MIN(p, rec->wirelen); if (!n || n < 0) return -3; if (p < 0 || p > 65536) return -4; return p; } #ifdef notyet /* * read an entire pcap packet record. only the data part is copied into * the available buffer, with the number of bytes copied returned. */ -static int ipcap_read(buf, cnt) - char *buf; - int cnt; +static int +ipcap_read(char *buf, int cnt) { packetheader_t rec; static char *bufp = NULL; int i, n; if ((i = ipcap_read_rec(&rec)) <= 0) return i; if (!bufp) bufp = malloc(i); else bufp = realloc(bufp, i); if (read(pfd, bufp, i) != i) return -2; n = MIN(i, cnt); bcopy(bufp, buf, n); return n; } #endif /* * return only an IP packet read into buf */ -static int ipcap_readip(mb, ifn, dir) - mb_t *mb; - char **ifn; - int *dir; +static int +ipcap_readip(mb_t *mb, char **ifn, int *dir) { static char *bufp = NULL; packetheader_t rec; struct llc *l; char *s, ty[4]; int i, j, n; char *buf; int cnt; #if 0 ifn = ifn; /* gcc -Wextra */ dir = dir; /* gcc -Wextra */ #endif buf = (char *)mb->mb_buf; cnt = sizeof(mb->mb_buf); l = llcp; /* do { */ if ((i = ipcap_read_rec(&rec)) <= 0) return i; if (!bufp) bufp = malloc(i); else bufp = realloc(bufp, i); s = bufp; for (j = i, n = 0; j > 0; ) { n = read(pfd, s, j); if (n <= 0) return -2; j -= n; s += n; } s = bufp; i -= l->lc_sz; s += l->lc_to; bcopy(s, ty, l->lc_tl); s += l->lc_tl; /* } while (ty[0] != 0x8 && ty[1] != 0); */ n = MIN(i, cnt); bcopy(s, buf, n); mb->mb_len = n; return n; } diff --git a/sbin/ipf/libipf/ipft_tx.c b/sbin/ipf/libipf/ipft_tx.c index 3499afedf854..3b6b580c705b 100644 --- a/sbin/ipf/libipf/ipft_tx.c +++ b/sbin/ipf/libipf/ipft_tx.c @@ -1,508 +1,500 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #if !defined(lint) static const char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include #include "ipf.h" #include "ipt.h" extern int opts; static char *tx_proto = ""; static int text_open(char *), text_close(void); static int text_readip(mb_t *, char **, int *); static int parseline(char *, ip_t *, char **, int *); static char myflagset[] = "FSRPAUEC"; static u_char myflags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG, TH_ECN, TH_CWR }; struct ipread iptext = { text_open, text_close, text_readip, R_DO_CKSUM }; static FILE *tfp = NULL; static int tfd = -1; static u_32_t tx_hostnum(char *, int *); static u_short tx_portnum(char *); #ifdef USE_INET6 int parseipv6(char **, ip6_t *, char **, int *); #endif /* * returns an ip address as a long var as a result of either a DNS lookup or * straight inet_addr() call */ -static u_32_t tx_hostnum(host, resolved) - char *host; - int *resolved; +static u_32_t +tx_hostnum(char *host, int *resolved) { i6addr_t ipa; *resolved = 0; if (!strcasecmp("any", host)) return 0L; if (ISDIGIT(*host)) return inet_addr(host); if (gethost(AF_INET, host, &ipa) == -1) { *resolved = -1; fprintf(stderr, "can't resolve hostname: %s\n", host); return 0; } return ipa.in4.s_addr; } /* * find the port number given by the name, either from getservbyname() or * straight atoi() */ -static u_short tx_portnum(name) - char *name; +static u_short +tx_portnum(char *name) { struct servent *sp; if (ISDIGIT(*name)) return (u_short)atoi(name); sp = getservbyname(name, tx_proto); if (sp) return ntohs(sp->s_port); (void) fprintf(stderr, "unknown service \"%s\".\n", name); return 0; } -static int text_open(fname) - char *fname; +static int +text_open(char *fname) { if (tfp && tfd != -1) { rewind(tfp); return tfd; } if (!strcmp(fname, "-")) { tfd = 0; tfp = stdin; } else { tfd = open(fname, O_RDONLY); if (tfd != -1) tfp = fdopen(tfd, "r"); } return tfd; } -static int text_close() +static int +text_close(void) { int cfd = tfd; tfd = -1; return close(cfd); } -static int text_readip(mb, ifn, dir) - mb_t *mb; - char **ifn; - int *dir; +static int +text_readip(mb_t *mb, char **ifn, int *dir) { register char *s; char line[513]; ip_t *ip; char *buf; buf = (char *)mb->mb_buf; *ifn = NULL; while (fgets(line, sizeof(line)-1, tfp)) { if ((s = strchr(line, '\n'))) *s = '\0'; if ((s = strchr(line, '\r'))) *s = '\0'; if ((s = strchr(line, '#'))) *s = '\0'; if (!*line) continue; if ((opts & OPT_DEBUG) != 0) printf("input: %s\n", line); *ifn = NULL; *dir = 0; if (!parseline(line, (ip_t *)buf, ifn, dir)) { ip = (ip_t *)buf; if (IP_V(ip) == 6) { #ifdef USE_INET6 mb->mb_len = ntohs(((ip6_t *)ip)->ip6_plen) + sizeof(ip6_t); #else mb->mb_len = 0; #endif } else { mb->mb_len = ntohs(ip->ip_len); } return mb->mb_len; } } if (feof(tfp)) return 0; return -1; } -static int parseline(line, ip, ifn, out) - char *line; - ip_t *ip; - char **ifn; - int *out; +static int +parseline(char *line, ip_t *ip, char **ifn, int *out) { tcphdr_t th, *tcp = &th; struct icmp icmp, *ic = &icmp; char *cps[20], **cpp, c, ipopts[68]; int i, r; if (*ifn) free(*ifn); bzero((char *)ip, MAX(sizeof(*tcp), sizeof(*ic)) + sizeof(*ip)); bzero((char *)tcp, sizeof(*tcp)); bzero((char *)ic, sizeof(*ic)); bzero(ipopts, sizeof(ipopts)); IP_HL_A(ip, sizeof(*ip) >> 2); IP_V_A(ip, IPVERSION); ip->ip_ttl = 63; for (i = 0, cps[0] = strtok(line, " \b\t\r\n"); cps[i] && i < 19; ) cps[++i] = strtok(NULL, " \b\t\r\n"); cpp = cps; if (!*cpp) return 1; c = **cpp; if (!ISALPHA(c) || (TOLOWER(c) != 'o' && TOLOWER(c) != 'i')) { fprintf(stderr, "bad direction \"%s\"\n", *cpp); return 1; } #ifdef USE_INET6 if (!strcasecmp(*cpp, "out6") || !strcasecmp(*cpp, "in6")) { return parseipv6(cpp, (ip6_t *)ip, ifn, out); } #endif *out = (TOLOWER(c) == 'o') ? 1 : 0; cpp++; if (!*cpp) return 1; if (!strcasecmp(*cpp, "on")) { cpp++; if (!*cpp) return 1; *ifn = strdup(*cpp++); if (!*cpp) return 1; } c = **cpp; ip->ip_len = sizeof(ip_t); if (!strcasecmp(*cpp, "tcp") || !strcasecmp(*cpp, "udp") || !strcasecmp(*cpp, "icmp")) { if (c == 't') { ip->ip_p = IPPROTO_TCP; ip->ip_len += sizeof(struct tcphdr); tx_proto = "tcp"; } else if (c == 'u') { ip->ip_p = IPPROTO_UDP; ip->ip_len += sizeof(struct udphdr); tx_proto = "udp"; } else { ip->ip_p = IPPROTO_ICMP; ip->ip_len += ICMPERR_IPICMPHLEN; tx_proto = "icmp"; } cpp++; } else if (ISDIGIT(**cpp) && !index(*cpp, '.')) { ip->ip_p = atoi(*cpp); cpp++; } else ip->ip_p = IPPROTO_IP; if (!*cpp) return 1; if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) { char *last; last = strchr(*cpp, ','); if (!last) { fprintf(stderr, "tcp/udp with no source port\n"); return 1; } *last++ = '\0'; tcp->th_sport = htons(tx_portnum(last)); if (ip->ip_p == IPPROTO_TCP) { tcp->th_win = htons(4096); TCP_OFF_A(tcp, sizeof(*tcp) >> 2); } } ip->ip_src.s_addr = tx_hostnum(*cpp, &r); cpp++; if (!*cpp) return 1; if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) { char *last; last = strchr(*cpp, ','); if (!last) { fprintf(stderr, "tcp/udp with no destination port\n"); return 1; } *last++ = '\0'; tcp->th_dport = htons(tx_portnum(last)); } ip->ip_dst.s_addr = tx_hostnum(*cpp, &r); cpp++; if (ip->ip_p == IPPROTO_TCP) { if (*cpp != NULL) { char *s, *t; tcp->th_flags = 0; for (s = *cpp; *s; s++) if ((t = strchr(myflagset, *s))) tcp->th_flags |= myflags[t-myflagset]; if (tcp->th_flags) cpp++; } if (tcp->th_flags & TH_URG) tcp->th_urp = htons(1); if (*cpp && !strncasecmp(*cpp, "seq=", 4)) { tcp->th_seq = htonl(atoi(*cpp + 4)); cpp++; } if (*cpp && !strncasecmp(*cpp, "ack=", 4)) { tcp->th_ack = htonl(atoi(*cpp + 4)); cpp++; } } else if (*cpp && ip->ip_p == IPPROTO_ICMP) { char *t; t = strchr(*cpp, ','); if (t != NULL) *t = '\0'; ic->icmp_type = geticmptype(AF_INET, *cpp); if (t != NULL) ic->icmp_code = atoi(t + 1); cpp++; if (ic->icmp_type == ICMP_ECHO || ic->icmp_type == ICMP_ECHOREPLY) ic->icmp_id = htons(getpid()); if (t != NULL) *t = ','; } if (*cpp && !strcasecmp(*cpp, "opt")) { u_long olen; cpp++; olen = buildopts(*cpp, ipopts, (IP_HL(ip) - 5) << 2); if (olen) { bcopy(ipopts, (char *)(ip + 1), olen); IP_HL_A(ip, IP_HL(ip) + (olen >> 2)); ip->ip_len += olen; } } if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) bcopy((char *)tcp, ((char *)ip) + (IP_HL(ip) << 2), sizeof(*tcp)); else if (ip->ip_p == IPPROTO_ICMP) bcopy((char *)ic, ((char *)ip) + (IP_HL(ip) << 2), sizeof(*ic)); ip->ip_len = htons(ip->ip_len); return 0; } #ifdef USE_INET6 -int parseipv6(cpp, ip6, ifn, out) - char **cpp; - ip6_t *ip6; - char **ifn; - int *out; +int +parseipv6(char **cpp, ip6_t *ip6, char **ifn, int *out) { tcphdr_t th, *tcp = &th; struct icmp6_hdr icmp, *ic6 = &icmp; bzero((char *)ip6, MAX(sizeof(*tcp), sizeof(*ic6)) + sizeof(*ip6)); bzero((char *)tcp, sizeof(*tcp)); bzero((char *)ic6, sizeof(*ic6)); ip6->ip6_vfc = 0x60; *out = (**cpp == 'o') ? 1 : 0; cpp++; if (!*cpp) return 1; if (!strcasecmp(*cpp, "on")) { cpp++; if (!*cpp) return 1; *ifn = strdup(*cpp++); if (!*cpp) return 1; } if (!strcasecmp(*cpp, "tcp")) { ip6->ip6_nxt = IPPROTO_TCP; tx_proto = "tcp"; cpp++; } else if (!strcasecmp(*cpp, "udp")) { ip6->ip6_nxt = IPPROTO_UDP; tx_proto = "udp"; cpp++; } else if (!strcasecmp(*cpp, "icmpv6")) { ip6->ip6_nxt = IPPROTO_ICMPV6; tx_proto = "icmpv6"; cpp++; } else if (ISDIGIT(**cpp) && !index(*cpp, ':')) { ip6->ip6_nxt = atoi(*cpp); cpp++; } else ip6->ip6_nxt = IPPROTO_IPV6; if (!*cpp) return 1; switch (ip6->ip6_nxt) { case IPPROTO_TCP : ip6->ip6_plen = sizeof(struct tcphdr); break; case IPPROTO_UDP : ip6->ip6_plen = sizeof(struct udphdr); break; case IPPROTO_ICMPV6 : ip6->ip6_plen = ICMP6ERR_IPICMPHLEN; break; default : break; } if (ip6->ip6_nxt == IPPROTO_TCP || ip6->ip6_nxt == IPPROTO_UDP) { char *last; last = strchr(*cpp, ','); if (!last) { fprintf(stderr, "tcp/udp with no source port\n"); return 1; } *last++ = '\0'; tcp->th_sport = htons(tx_portnum(last)); if (ip6->ip6_nxt == IPPROTO_TCP) { tcp->th_win = htons(4096); TCP_OFF_A(tcp, sizeof(*tcp) >> 2); } } if (inet_pton(AF_INET6, *cpp, &ip6->ip6_src) != 1) { fprintf(stderr, "cannot parse source address '%s'\n", *cpp); return 1; } cpp++; if (!*cpp) return 1; if (ip6->ip6_nxt == IPPROTO_TCP || ip6->ip6_nxt == IPPROTO_UDP) { char *last; last = strchr(*cpp, ','); if (!last) { fprintf(stderr, "tcp/udp with no destination port\n"); return 1; } *last++ = '\0'; tcp->th_dport = htons(tx_portnum(last)); } if (inet_pton(AF_INET6, *cpp, &ip6->ip6_dst) != 1) { fprintf(stderr, "cannot parse destination address '%s'\n", *cpp); return 1; } cpp++; if (ip6->ip6_nxt == IPPROTO_TCP) { if (*cpp != NULL) { char *s, *t; tcp->th_flags = 0; for (s = *cpp; *s; s++) if ((t = strchr(myflagset, *s))) tcp->th_flags |= myflags[t-myflagset]; if (tcp->th_flags) cpp++; } if (tcp->th_flags & TH_URG) tcp->th_urp = htons(1); if (*cpp && !strncasecmp(*cpp, "seq=", 4)) { tcp->th_seq = htonl(atoi(*cpp + 4)); cpp++; } if (*cpp && !strncasecmp(*cpp, "ack=", 4)) { tcp->th_ack = htonl(atoi(*cpp + 4)); cpp++; } } else if (*cpp && ip6->ip6_nxt == IPPROTO_ICMPV6) { char *t; t = strchr(*cpp, ','); if (t != NULL) *t = '\0'; ic6->icmp6_type = geticmptype(AF_INET6, *cpp); if (t != NULL) ic6->icmp6_code = atoi(t + 1); if (ic6->icmp6_type == ICMP6_ECHO_REQUEST || ic6->icmp6_type == ICMP6_ECHO_REPLY) ic6->icmp6_id = htons(getpid()); if (t != NULL) *t = ','; } if (ip6->ip6_nxt == IPPROTO_TCP || ip6->ip6_nxt == IPPROTO_UDP) { bcopy((char *)tcp, (char *)ip6 + sizeof(*ip6), sizeof(*tcp)); } else if (ip6->ip6_nxt == IPPROTO_ICMPV6) { bcopy((char *)ic6, (char *)ip6 + sizeof(*ip6), sizeof(*ic6)); } /* * Because a length of 0 == jumbo gram... */ if (ip6->ip6_plen == 0) { ip6->ip6_plen++; } ip6->ip6_plen = htons(ip6->ip6_plen); return 0; } #endif diff --git a/sbin/ipf/libipf/ipoptsec.c b/sbin/ipf/libipf/ipoptsec.c index 5e585ba57ef8..e6c8f042748c 100644 --- a/sbin/ipf/libipf/ipoptsec.c +++ b/sbin/ipf/libipf/ipoptsec.c @@ -1,61 +1,61 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" struct ipopt_names secclass[] = { { IPSO_CLASS_RES4, 0x01, 0, "reserv-4" }, { IPSO_CLASS_TOPS, 0x02, 0, "topsecret" }, { IPSO_CLASS_SECR, 0x04, 0, "secret" }, { IPSO_CLASS_RES3, 0x08, 0, "reserv-3" }, { IPSO_CLASS_CONF, 0x10, 0, "confid" }, { IPSO_CLASS_UNCL, 0x20, 0, "unclass" }, { IPSO_CLASS_RES2, 0x40, 0, "reserv-2" }, { IPSO_CLASS_RES1, 0x80, 0, "reserv-1" }, { 0, 0, 0, NULL } /* must be last */ }; -u_char seclevel(slevel) - char *slevel; +u_char +seclevel(char *slevel) { struct ipopt_names *so; if (slevel == NULL || *slevel == '\0') return 0; for (so = secclass; so->on_name; so++) if (!strcasecmp(slevel, so->on_name)) break; if (!so->on_name) { fprintf(stderr, "no such security level: '%s'\n", slevel); return 0; } return (u_char)so->on_value; } -u_char secbit(class) - int class; +u_char +secbit(int class) { struct ipopt_names *so; for (so = secclass; so->on_name; so++) if (so->on_value == class) break; if (!so->on_name) { fprintf(stderr, "no such security class: %d.\n", class); return 0; } return (u_char)so->on_bit; } diff --git a/sbin/ipf/libipf/kmem.c b/sbin/ipf/libipf/kmem.c index 26252a02f0bf..635f84507d1a 100644 --- a/sbin/ipf/libipf/kmem.c +++ b/sbin/ipf/libipf/kmem.c @@ -1,118 +1,114 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ /* * kmemcpy() - copies n bytes from kernel memory into user buffer. * returns 0 on success, -1 on error. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kmem.h" #if !defined(lint) static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif static kvm_t *kvm_f = NULL; -int openkmem(kern, core) - char *kern, *core; +int +openkmem(char *kern, char *core) { kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL); if (kvm_f == NULL) { perror("openkmem:open"); return -1; } return kvm_f != NULL; } -int kmemcpy(buf, pos, n) - register char *buf; - long pos; - register int n; +int +kmemcpy(register char *buf, long pos, register int n) { register int r; if (!n) return 0; if (kvm_f == NULL) if (openkmem(NULL, NULL) == -1) return -1; while ((r = kvm_read(kvm_f, pos, buf, n)) < n) if (r <= 0) { fprintf(stderr, "pos=0x%lx ", (u_long)pos); perror("kmemcpy:read"); return -1; } else { buf += r; pos += r; n -= r; } return 0; } -int kstrncpy(buf, pos, n) - register char *buf; - long pos; - register int n; +int +kstrncpy(register char *buf, long pos, register int n) { register int r; if (!n) return 0; if (kvm_f == NULL) if (openkmem(NULL, NULL) == -1) return -1; while (n > 0) { r = kvm_read(kvm_f, pos, buf, 1); if (r <= 0) { fprintf(stderr, "pos=0x%lx ", (u_long)pos); perror("kmemcpy:read"); return -1; } else { if (*buf == '\0') break; buf++; pos++; n--; } } return 0; } diff --git a/sbin/ipf/libipf/kmemcpywrap.c b/sbin/ipf/libipf/kmemcpywrap.c index 6c398d6d39f3..c5c5739a33ba 100644 --- a/sbin/ipf/libipf/kmemcpywrap.c +++ b/sbin/ipf/libipf/kmemcpywrap.c @@ -1,23 +1,22 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #include "kmem.h" -int kmemcpywrap(from, to, size) - void *from, *to; - size_t size; +int +kmemcpywrap(void *from, void *to, size_t size) { int ret; ret = kmemcpy((caddr_t)to, (u_long)from, size); return ret; } diff --git a/sbin/ipf/libipf/kvatoname.c b/sbin/ipf/libipf/kvatoname.c index 65b524082df4..bc59960a51b0 100644 --- a/sbin/ipf/libipf/kvatoname.c +++ b/sbin/ipf/libipf/kvatoname.c @@ -1,39 +1,38 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #include #include -char *kvatoname(func, iocfunc) - ipfunc_t func; - ioctlfunc_t iocfunc; +char * +kvatoname(ipfunc_t func, ioctlfunc_t iocfunc) { static char funcname[40]; ipfunc_resolve_t res; int fd; res.ipfu_addr = func; res.ipfu_name[0] = '\0'; fd = -1; if ((opts & OPT_DONTOPEN) == 0) { fd = open(IPL_NAME, O_RDONLY); if (fd == -1) return NULL; } (void) (*iocfunc)(fd, SIOCFUNCL, &res); if (fd >= 0) close(fd); strncpy(funcname, res.ipfu_name, sizeof(funcname)); funcname[sizeof(funcname) - 1] = '\0'; return funcname; } diff --git a/sbin/ipf/libipf/load_dstlist.c b/sbin/ipf/libipf/load_dstlist.c index 760699dafeae..484968532a3c 100644 --- a/sbin/ipf/libipf/load_dstlist.c +++ b/sbin/ipf/libipf/load_dstlist.c @@ -1,69 +1,66 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: load_dstlist.c,v 1.1.2.5 2012/07/22 08:04:24 darren_r Exp $ */ #include #include #include "ipf.h" #include "netinet/ip_lookup.h" #include "netinet/ip_dstlist.h" int -load_dstlist(dst, iocfunc, nodes) - ippool_dst_t *dst; - ioctlfunc_t iocfunc; - ipf_dstnode_t *nodes; +load_dstlist(ippool_dst_t *dst, ioctlfunc_t iocfunc, ipf_dstnode_t *nodes) { iplookupop_t op; ipf_dstnode_t *a; ippool_dst_t dest; if (dst->ipld_name[0] == '\0') return -1; if (pool_open() == -1) return -1; op.iplo_unit = dst->ipld_unit; op.iplo_type = IPLT_DSTLIST; op.iplo_arg = 0; strncpy(op.iplo_name, dst->ipld_name, sizeof(op.iplo_name)); op.iplo_size = sizeof(dest); op.iplo_struct = &dest; bzero((char *)&dest, sizeof(dest)); dest.ipld_unit = dst->ipld_unit; dest.ipld_policy = dst->ipld_policy; dest.ipld_flags = dst->ipld_flags; strncpy(dest.ipld_name, dst->ipld_name, sizeof(dest.ipld_name)); if ((opts & OPT_REMOVE) == 0) { if (pool_ioctl(iocfunc, SIOCLOOKUPADDTABLE, &op)) if ((opts & OPT_DONOTHING) == 0) { return ipf_perror_fd(pool_fd(), iocfunc, "add destination list table"); } } if ((opts & OPT_VERBOSE) != 0) { dest.ipld_dests = dst->ipld_dests; printdstlist(&dest, bcopywrap, dest.ipld_name, opts, nodes, NULL); dest.ipld_dests = NULL; } for (a = nodes; a != NULL; a = a->ipfd_next) load_dstlistnode(dst->ipld_unit, dest.ipld_name, a, iocfunc); if ((opts & OPT_REMOVE) != 0) { if (pool_ioctl(iocfunc, SIOCLOOKUPDELTABLE, &op)) if ((opts & OPT_DONOTHING) == 0) { return ipf_perror_fd(pool_fd(), iocfunc, "delete destination list table"); } } return 0; } diff --git a/sbin/ipf/libipf/load_dstlistnode.c b/sbin/ipf/libipf/load_dstlistnode.c index d8160ebaea9c..a09c7a614468 100644 --- a/sbin/ipf/libipf/load_dstlistnode.c +++ b/sbin/ipf/libipf/load_dstlistnode.c @@ -1,70 +1,67 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: load_dstlistnode.c,v 1.1.2.5 2012/07/22 08:04:24 darren_r Exp $ */ #include #include #include "ipf.h" #include "netinet/ip_lookup.h" #include "netinet/ip_pool.h" int -load_dstlistnode(role, name, node, iocfunc) - int role; - char *name; - ipf_dstnode_t *node; - ioctlfunc_t iocfunc; +load_dstlistnode(int role, char *name, ipf_dstnode_t *node, + ioctlfunc_t iocfunc) { iplookupop_t op; frdest_t *dst; char *what; int err; if (pool_open() == -1) return -1; dst = calloc(1, sizeof(*dst) + node->ipfd_dest.fd_name); if (dst == NULL) return -1; op.iplo_unit = role; op.iplo_type = IPLT_DSTLIST; op.iplo_arg = 0; op.iplo_struct = dst; op.iplo_size = sizeof(*dst); if (node->ipfd_dest.fd_name >= 0) op.iplo_size += node->ipfd_dest.fd_name; (void) strncpy(op.iplo_name, name, sizeof(op.iplo_name)); dst->fd_addr = node->ipfd_dest.fd_addr; dst->fd_type = node->ipfd_dest.fd_type; dst->fd_name = node->ipfd_dest.fd_name; if (node->ipfd_dest.fd_name >= 0) bcopy(node->ipfd_names, (char *)dst + sizeof(*dst), node->ipfd_dest.fd_name); if ((opts & OPT_REMOVE) == 0) { what = "add"; err = pool_ioctl(iocfunc, SIOCLOOKUPADDNODE, &op); } else { what = "delete"; err = pool_ioctl(iocfunc, SIOCLOOKUPDELNODE, &op); } free(dst); if (err != 0) { if ((opts & OPT_DONOTHING) == 0) { char msg[80]; (void) snprintf(msg, sizeof(msg), "%s lookup node", what); return ipf_perror_fd(pool_fd(), iocfunc, msg); } } return 0; } diff --git a/sbin/ipf/libipf/load_hash.c b/sbin/ipf/libipf/load_hash.c index 7ec79a91258f..390195c02d72 100644 --- a/sbin/ipf/libipf/load_hash.c +++ b/sbin/ipf/libipf/load_hash.c @@ -1,103 +1,100 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include #include "ipf.h" #include "netinet/ip_lookup.h" #include "netinet/ip_htable.h" int -load_hash(iphp, list, iocfunc) - iphtable_t *iphp; - iphtent_t *list; - ioctlfunc_t iocfunc; +load_hash(iphtable_t *iphp, iphtent_t *list, ioctlfunc_t iocfunc) { iplookupop_t op; iphtable_t iph; iphtent_t *a; size_t size; int n; if (pool_open() == -1) return -1; for (n = 0, a = list; a != NULL; a = a->ipe_next) n++; bzero((char *)&iph, sizeof(iph)); op.iplo_arg = 0; op.iplo_type = IPLT_HASH; op.iplo_unit = iphp->iph_unit; strncpy(op.iplo_name, iphp->iph_name, sizeof(op.iplo_name)); if (*op.iplo_name == '\0') op.iplo_arg = IPHASH_ANON; op.iplo_size = sizeof(iph); op.iplo_struct = &iph; iph = *iphp; if (n <= 0) n = 1; if (iphp->iph_size == 0) size = n * 2 - 1; else size = iphp->iph_size; if ((list == NULL) && (size == 1)) { fprintf(stderr, "WARNING: empty hash table %s, recommend setting %s\n", iphp->iph_name, "size to match expected use"); } iph.iph_size = size; iph.iph_table = NULL; iph.iph_list = NULL; iph.iph_ref = 0; if ((opts & OPT_REMOVE) == 0) { if (pool_ioctl(iocfunc, SIOCLOOKUPADDTABLE, &op)) if ((opts & OPT_DONOTHING) == 0) { return ipf_perror_fd(pool_fd(), iocfunc, "add lookup hash table"); } } strncpy(iph.iph_name, op.iplo_name, sizeof(op.iplo_name)); strncpy(iphp->iph_name, op.iplo_name, sizeof(op.iplo_name)); if (opts & OPT_VERBOSE) { iph.iph_table = calloc(size, sizeof(*iph.iph_table)); if (iph.iph_table == NULL) { perror("calloc(size, sizeof(*iph.iph_table))"); return -1; } iph.iph_list = list; printhash(&iph, bcopywrap, iph.iph_name, opts, NULL); free(iph.iph_table); for (a = list; a != NULL; a = a->ipe_next) { a->ipe_addr.in4_addr = htonl(a->ipe_addr.in4_addr); a->ipe_mask.in4_addr = htonl(a->ipe_mask.in4_addr); } } if (opts & OPT_DEBUG) printf("Hash %s:\n", iph.iph_name); for (a = list; a != NULL; a = a->ipe_next) load_hashnode(iphp->iph_unit, iph.iph_name, a, 0, iocfunc); if ((opts & OPT_REMOVE) != 0) { if (pool_ioctl(iocfunc, SIOCLOOKUPDELTABLE, &op)) if ((opts & OPT_DONOTHING) == 0) { return ipf_perror_fd(pool_fd(), iocfunc, "delete lookup hash table"); } } return 0; } diff --git a/sbin/ipf/libipf/load_hashnode.c b/sbin/ipf/libipf/load_hashnode.c index 203d75484ec3..2ccd8a181ac8 100644 --- a/sbin/ipf/libipf/load_hashnode.c +++ b/sbin/ipf/libipf/load_hashnode.c @@ -1,67 +1,63 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include #include "ipf.h" #include "netinet/ip_lookup.h" #include "netinet/ip_htable.h" int -load_hashnode(unit, name, node, ttl, iocfunc) - int unit; - char *name; - iphtent_t *node; - int ttl; - ioctlfunc_t iocfunc; +load_hashnode(int unit, char *name, iphtent_t *node, int ttl, + ioctlfunc_t iocfunc) { iplookupop_t op; iphtent_t ipe; char *what; int err; if (pool_open() == -1) return -1; op.iplo_type = IPLT_HASH; op.iplo_unit = unit; op.iplo_arg = 0; op.iplo_size = sizeof(ipe); op.iplo_struct = &ipe; strncpy(op.iplo_name, name, sizeof(op.iplo_name)); bzero((char *)&ipe, sizeof(ipe)); ipe.ipe_family = node->ipe_family; ipe.ipe_die = ttl; bcopy((char *)&node->ipe_addr, (char *)&ipe.ipe_addr, sizeof(ipe.ipe_addr)); bcopy((char *)&node->ipe_mask, (char *)&ipe.ipe_mask, sizeof(ipe.ipe_mask)); bcopy((char *)&node->ipe_group, (char *)&ipe.ipe_group, sizeof(ipe.ipe_group)); if ((opts & OPT_REMOVE) == 0) { what = "add"; err = pool_ioctl(iocfunc, SIOCLOOKUPADDNODE, &op); } else { what = "delete"; err = pool_ioctl(iocfunc, SIOCLOOKUPDELNODE, &op); } if (err != 0) if (!(opts & OPT_DONOTHING)) { char msg[80]; snprintf(msg, sizeof(msg), "%s node from lookup hash table", what); return ipf_perror_fd(pool_fd(), iocfunc, msg); } return 0; } diff --git a/sbin/ipf/libipf/load_pool.c b/sbin/ipf/libipf/load_pool.c index 190a2dff2520..74048388c21a 100644 --- a/sbin/ipf/libipf/load_pool.c +++ b/sbin/ipf/libipf/load_pool.c @@ -1,72 +1,70 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include #include "ipf.h" #include "netinet/ip_lookup.h" #include "netinet/ip_pool.h" int -load_pool(plp, iocfunc) - ip_pool_t *plp; - ioctlfunc_t iocfunc; +load_pool(ip_pool_t *plp, ioctlfunc_t iocfunc) { iplookupop_t op; ip_pool_node_t *a; ip_pool_t pool; if (pool_open() == -1) return -1; op.iplo_unit = plp->ipo_unit; op.iplo_type = IPLT_POOL; op.iplo_arg = 0; strncpy(op.iplo_name, plp->ipo_name, sizeof(op.iplo_name)); op.iplo_size = sizeof(pool); op.iplo_struct = &pool; bzero((char *)&pool, sizeof(pool)); pool.ipo_unit = plp->ipo_unit; strncpy(pool.ipo_name, plp->ipo_name, sizeof(pool.ipo_name)); if (plp->ipo_name[0] == '\0') op.iplo_arg |= IPOOL_ANON; if ((opts & OPT_REMOVE) == 0) { if (pool_ioctl(iocfunc, SIOCLOOKUPADDTABLE, &op)) { if ((opts & OPT_DONOTHING) == 0) { return ipf_perror_fd(pool_fd(), iocfunc, "add lookup table"); } } } if (op.iplo_arg & IPOOL_ANON) strncpy(pool.ipo_name, op.iplo_name, sizeof(pool.ipo_name)); if ((opts & OPT_VERBOSE) != 0) { pool.ipo_list = plp->ipo_list; (void) printpool(&pool, bcopywrap, pool.ipo_name, opts, NULL); pool.ipo_list = NULL; } for (a = plp->ipo_list; a != NULL; a = a->ipn_next) load_poolnode(plp->ipo_unit, pool.ipo_name, a, 0, iocfunc); if ((opts & OPT_REMOVE) != 0) { if (pool_ioctl(iocfunc, SIOCLOOKUPDELTABLE, &op)) if ((opts & OPT_DONOTHING) == 0) { return ipf_perror_fd(pool_fd(), iocfunc, "delete lookup table"); } } return 0; } diff --git a/sbin/ipf/libipf/load_poolnode.c b/sbin/ipf/libipf/load_poolnode.c index 0dfc1d25a8f7..d72321d06b6c 100644 --- a/sbin/ipf/libipf/load_poolnode.c +++ b/sbin/ipf/libipf/load_poolnode.c @@ -1,70 +1,66 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include #include "ipf.h" #include "netinet/ip_lookup.h" #include "netinet/ip_pool.h" int -load_poolnode(role, name, node, ttl, iocfunc) - int role; - char *name; - ip_pool_node_t *node; - int ttl; - ioctlfunc_t iocfunc; +load_poolnode(int role, char *name, ip_pool_node_t *node, int ttl, + ioctlfunc_t iocfunc) { ip_pool_node_t pn; iplookupop_t op; char *what; int err; if (pool_open() == -1) return -1; op.iplo_unit = role; op.iplo_type = IPLT_POOL; op.iplo_arg = 0; op.iplo_struct = &pn; op.iplo_size = sizeof(pn); strncpy(op.iplo_name, name, sizeof(op.iplo_name)); bzero((char *)&pn, sizeof(pn)); bcopy((char *)&node->ipn_addr, (char *)&pn.ipn_addr, sizeof(pn.ipn_addr)); bcopy((char *)&node->ipn_mask, (char *)&pn.ipn_mask, sizeof(pn.ipn_mask)); pn.ipn_info = node->ipn_info; pn.ipn_die = ttl; strncpy(pn.ipn_name, node->ipn_name, sizeof(pn.ipn_name)); if ((opts & OPT_REMOVE) == 0) { what = "add"; err = pool_ioctl(iocfunc, SIOCLOOKUPADDNODE, &op); } else { what = "delete"; err = pool_ioctl(iocfunc, SIOCLOOKUPDELNODE, &op); } if (err != 0) { if ((opts & OPT_DONOTHING) == 0) { char msg[80]; snprintf(msg, sizeof(msg), "%s pool node(%s/", what, inet_ntoa(pn.ipn_addr.adf_addr.in4)); strcat(msg, inet_ntoa(pn.ipn_mask.adf_addr.in4)); return ipf_perror_fd(pool_fd(), iocfunc, msg); } } return 0; } diff --git a/sbin/ipf/libipf/mb_hexdump.c b/sbin/ipf/libipf/mb_hexdump.c index 6da65633191c..91351c3f815e 100644 --- a/sbin/ipf/libipf/mb_hexdump.c +++ b/sbin/ipf/libipf/mb_hexdump.c @@ -1,32 +1,30 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: mb_hexdump.c,v 1.1.2.3 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" void -mb_hexdump(m, fp) - mb_t *m; - FILE *fp; +mb_hexdump(mb_t *m, FILE *fp) { u_char *s; int len; int i; for (; m != NULL; m = m->mb_next) { len = m->mb_len; for (s = (u_char *)m->mb_data, i = 0; i < len; i++) { fprintf(fp, "%02x", *s++ & 0xff); if (len - i > 1) { i++; fprintf(fp, "%02x", *s++ & 0xff); } fputc(' ', fp); } } fputc('\n', fp); } diff --git a/sbin/ipf/libipf/msgdsize.c b/sbin/ipf/libipf/msgdsize.c index 9bdc584bc008..e0e57ce5e8e3 100644 --- a/sbin/ipf/libipf/msgdsize.c +++ b/sbin/ipf/libipf/msgdsize.c @@ -1,20 +1,19 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: msgdsize.c,v 1.2.4.3 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" -size_t msgdsize(orig) - mb_t *orig; +size_t msgdsize(mb_t *orig) { size_t sz = 0; mb_t *m; for (m = orig; m != NULL; m = m->mb_next) sz += m->mb_len; return sz; } diff --git a/sbin/ipf/libipf/mutex_emul.c b/sbin/ipf/libipf/mutex_emul.c index 1846701fa40a..3152d2e47013 100644 --- a/sbin/ipf/libipf/mutex_emul.c +++ b/sbin/ipf/libipf/mutex_emul.c @@ -1,133 +1,123 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #define EMM_MAGIC 0x9d7adba3 static int mutex_debug = 0; static FILE *mutex_file = NULL; static int initcount = 0; void -eMmutex_enter(mtx, file, line) - eMmutex_t *mtx; - char *file; - int line; +eMmutex_enter(eMmutex_t *mtx, char *file, int line) { if (mutex_debug & 2) fprintf(mutex_file, "%s:%d:eMmutex_enter(%s)\n", file, line, mtx->eMm_owner); if (mtx->eMm_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMmutex_enter(%p): bad magic: %#x\n", mtx->eMm_owner, mtx, mtx->eMm_magic); abort(); } if (mtx->eMm_held != 0) { fprintf(stderr, "%s:eMmutex_enter(%p): already locked: %d\n", mtx->eMm_owner, mtx, mtx->eMm_held); abort(); } mtx->eMm_held++; mtx->eMm_heldin = file; mtx->eMm_heldat = line; } void -eMmutex_exit(mtx, file, line) - eMmutex_t *mtx; - char *file; - int line; +eMmutex_exit(eMmutex_t *mtx, char *file, int line) { if (mutex_debug & 2) fprintf(mutex_file, "%s:%d:eMmutex_exit(%s)\n", file, line, mtx->eMm_owner); if (mtx->eMm_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMmutex_exit(%p): bad magic: %#x\n", mtx->eMm_owner, mtx, mtx->eMm_magic); abort(); } if (mtx->eMm_held != 1) { fprintf(stderr, "%s:eMmutex_exit(%p): not locked: %d\n", mtx->eMm_owner, mtx, mtx->eMm_held); abort(); } mtx->eMm_held--; mtx->eMm_heldin = NULL; mtx->eMm_heldat = 0; } void -eMmutex_init(mtx, who, file, line) - eMmutex_t *mtx; - char *who; - char *file; - int line; +eMmutex_init(eMmutex_t *mtx, char *who, char *file, int line) { if (mutex_file == NULL && mutex_debug) mutex_file = fopen("ipf_mutex_log", "w"); if (mutex_debug & 1) fprintf(mutex_file, "%s:%d:eMmutex_init(%p,%s)\n", file, line, mtx, who); if (mtx->eMm_magic == EMM_MAGIC) { /* safe bet ? */ fprintf(stderr, "%s:eMmutex_init(%p): already initialised?: %#x\n", mtx->eMm_owner, mtx, mtx->eMm_magic); abort(); } mtx->eMm_magic = EMM_MAGIC; mtx->eMm_held = 0; if (who != NULL) mtx->eMm_owner = strdup(who); else mtx->eMm_owner = NULL; initcount++; } void eMmutex_destroy(mtx, file, line) eMmutex_t *mtx; char *file; int line; { if (mutex_debug & 1) fprintf(mutex_file, "%s:%d:eMmutex_destroy(%p,%s)\n", file, line, mtx, mtx->eMm_owner); if (mtx->eMm_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMmutex_destroy(%p): bad magic: %#x\n", mtx->eMm_owner, mtx, mtx->eMm_magic); abort(); } if (mtx->eMm_held != 0) { fprintf(stderr, "%s:eMmutex_enter(%p): still locked: %d\n", mtx->eMm_owner, mtx, mtx->eMm_held); abort(); } if (mtx->eMm_owner != NULL) free(mtx->eMm_owner); memset(mtx, 0xa5, sizeof(*mtx)); initcount--; } void -ipf_mutex_clean() +ipf_mutex_clean(void) { if (initcount != 0) { if (mutex_file) fprintf(mutex_file, "initcount %d\n", initcount); abort(); } } diff --git a/sbin/ipf/libipf/nametokva.c b/sbin/ipf/libipf/nametokva.c index 8e7af944d508..c1467e21eac2 100644 --- a/sbin/ipf/libipf/nametokva.c +++ b/sbin/ipf/libipf/nametokva.c @@ -1,38 +1,37 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #include #include -ipfunc_t nametokva(name, iocfunc) - char *name; - ioctlfunc_t iocfunc; +ipfunc_t +nametokva(char *name, ioctlfunc_t iocfunc) { ipfunc_resolve_t res; int fd; strncpy(res.ipfu_name, name, sizeof(res.ipfu_name)); res.ipfu_addr = NULL; fd = -1; if ((opts & OPT_DONTOPEN) == 0) { fd = open(IPL_NAME, O_RDONLY); if (fd == -1) return NULL; } (void) (*iocfunc)(fd, SIOCFUNCL, &res); if (fd >= 0) close(fd); if (res.ipfu_addr == NULL) res.ipfu_addr = (ipfunc_t)-1; return res.ipfu_addr; } diff --git a/sbin/ipf/libipf/nat_setgroupmap.c b/sbin/ipf/libipf/nat_setgroupmap.c index 15c21f6ced12..8a4b461c5a88 100644 --- a/sbin/ipf/libipf/nat_setgroupmap.c +++ b/sbin/ipf/libipf/nat_setgroupmap.c @@ -1,34 +1,34 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) static const char rcsid[] = "@(#)$Id$"; #endif #include "ipf.h" -void nat_setgroupmap(n) - ipnat_t *n; +void +nat_setgroupmap(ipnat_t *n) { if (n->in_nsrcmsk == n->in_osrcmsk) n->in_ippip = 1; else if (n->in_flags & IPN_AUTOPORTMAP) { n->in_ippip = ~ntohl(n->in_osrcmsk); if (n->in_nsrcmsk != 0xffffffff) n->in_ippip /= (~ntohl(n->in_nsrcmsk) + 1); n->in_ippip++; if (n->in_ippip == 0) n->in_ippip = 1; n->in_ppip = USABLE_PORTS / n->in_ippip; } else { n->in_space = USABLE_PORTS * ~ntohl(n->in_nsrcmsk); n->in_snip = 0; if (!(n->in_ppip = n->in_spmin)) n->in_ppip = 1; n->in_ippip = USABLE_PORTS / n->in_ppip; } } diff --git a/sbin/ipf/libipf/ntomask.c b/sbin/ipf/libipf/ntomask.c index 98e3b26119b0..0f0887fe1f7f 100644 --- a/sbin/ipf/libipf/ntomask.c +++ b/sbin/ipf/libipf/ntomask.c @@ -1,47 +1,46 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -int ntomask(family, nbits, ap) - int family, nbits; - u_32_t *ap; +int +ntomask(int family, int nbits, u_32_t *ap) { u_32_t mask; if (nbits < 0) return -1; switch (family) { case AF_INET : if (nbits > 32 || use_inet6 == 1) return -1; if (nbits == 0) { mask = 0; } else { mask = 0xffffffff; mask <<= (32 - nbits); } *ap = htonl(mask); break; case 0 : case AF_INET6 : if ((nbits > 128) || (use_inet6 == -1)) return -1; fill6bits(nbits, ap); break; default : return -1; } return 0; } diff --git a/sbin/ipf/libipf/optname.c b/sbin/ipf/libipf/optname.c index 2bc811b8dbe5..adf12e9c5fc3 100644 --- a/sbin/ipf/libipf/optname.c +++ b/sbin/ipf/libipf/optname.c @@ -1,65 +1,63 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -u_32_t optname(cp, sp, linenum) - char ***cp; - u_short *sp; - int linenum; +u_32_t +optname(char ***cp, u_short *sp, int linenum) { struct ipopt_names *io, *so; u_long msk = 0; u_short smsk = 0; char *s; int sec = 0; for (s = strtok(**cp, ","); s; s = strtok(NULL, ",")) { for (io = ionames; io->on_name; io++) if (!strcasecmp(s, io->on_name)) { msk |= io->on_bit; break; } if (!io->on_name) { fprintf(stderr, "%d: unknown IP option name %s\n", linenum, s); return 0; } if (!strcasecmp(s, "sec-class")) sec = 1; } if (sec && !*(*cp + 1)) { fprintf(stderr, "%d: missing security level after sec-class\n", linenum); return 0; } if (sec) { (*cp)++; for (s = strtok(**cp, ","); s; s = strtok(NULL, ",")) { for (so = secclass; so->on_name; so++) if (!strcasecmp(s, so->on_name)) { smsk |= so->on_bit; break; } if (!so->on_name) { fprintf(stderr, "%d: no such security level: %s\n", linenum, s); return 0; } } if (smsk) *sp = smsk; } return msk; } diff --git a/sbin/ipf/libipf/optprint.c b/sbin/ipf/libipf/optprint.c index 8b1f5cd9d042..f18ad00dba2a 100644 --- a/sbin/ipf/libipf/optprint.c +++ b/sbin/ipf/libipf/optprint.c @@ -1,83 +1,82 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -void optprint(sec, optmsk, optbits) - u_short *sec; - u_long optmsk, optbits; +void +optprint(u_short *sec, u_long optmsk, u_long optbits) { u_short secmsk = sec[0], secbits = sec[1]; struct ipopt_names *io, *so; char *s; s = " opt "; for (io = ionames; io->on_name; io++) if ((io->on_bit & optmsk) && ((io->on_bit & optmsk) == (io->on_bit & optbits))) { if ((io->on_value != IPOPT_SECURITY) || (!secmsk && !secbits)) { printf("%s%s", s, io->on_name); /* * Because the ionames table has this entry * twice. */ if (io->on_value == IPOPT_SECURITY) io++; s = ","; } } if (secmsk & secbits) { printf("%ssec-class", s); s = " "; for (so = secclass; so->on_name; so++) if ((secmsk & so->on_bit) && ((so->on_bit & secmsk) == (so->on_bit & secbits))) { printf("%s%s", s, so->on_name); s = ","; } } if ((optmsk && (optmsk != optbits)) || (secmsk && (secmsk != secbits))) { s = " "; printf(" not opt"); if (optmsk != optbits) { for (io = ionames; io->on_name; io++) if ((io->on_bit & optmsk) && ((io->on_bit & optmsk) != (io->on_bit & optbits))) { if ((io->on_value != IPOPT_SECURITY) || (!secmsk && !secbits)) { printf("%s%s", s, io->on_name); s = ","; if (io->on_value == IPOPT_SECURITY) io++; } else io++; } } if (secmsk != secbits) { printf("%ssec-class", s); s = " "; for (so = secclass; so->on_name; so++) if ((so->on_bit & secmsk) && ((so->on_bit & secmsk) != (so->on_bit & secbits))) { printf("%s%s", s, so->on_name); s = ","; } } } } diff --git a/sbin/ipf/libipf/optprintv6.c b/sbin/ipf/libipf/optprintv6.c index 752d1b353485..d043ff774031 100644 --- a/sbin/ipf/libipf/optprintv6.c +++ b/sbin/ipf/libipf/optprintv6.c @@ -1,47 +1,46 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #ifdef USE_INET6 -void optprintv6(sec, optmsk, optbits) - u_short *sec; - u_long optmsk, optbits; +void +optprintv6(u_short *sec, u_long optmsk, u_long optbits) { u_short secmsk = sec[0], secbits = sec[1]; struct ipopt_names *io; char *s; s = " v6hdr "; for (io = v6ionames; io->on_name; io++) if ((io->on_bit & optmsk) && ((io->on_bit & optmsk) == (io->on_bit & optbits))) { printf("%s%s", s, io->on_name); s = ","; } if ((optmsk && (optmsk != optbits)) || (secmsk && (secmsk != secbits))) { s = " "; printf(" not v6hdrs"); if (optmsk != optbits) { for (io = v6ionames; io->on_name; io++) if ((io->on_bit & optmsk) && ((io->on_bit & optmsk) != (io->on_bit & optbits))) { printf("%s%s", s, io->on_name); s = ","; } } } } #endif diff --git a/sbin/ipf/libipf/optvalue.c b/sbin/ipf/libipf/optvalue.c index 5bc1f4298a25..896d5fb7185f 100644 --- a/sbin/ipf/libipf/optvalue.c +++ b/sbin/ipf/libipf/optvalue.c @@ -1,34 +1,34 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -u_32_t getoptbyname(optname) - char *optname; +u_32_t +getoptbyname(char *optname) { struct ipopt_names *io; for (io = ionames; io->on_name; io++) if (!strcasecmp(optname, io->on_name)) return io->on_bit; return -1; } -u_32_t getoptbyvalue(optval) - int optval; +u_32_t +getoptbyvalue(int optval) { struct ipopt_names *io; for (io = ionames; io->on_name; io++) if (io->on_value == optval) return io->on_bit; return -1; } diff --git a/sbin/ipf/libipf/parsefields.c b/sbin/ipf/libipf/parsefields.c index 93c3601c9557..f79159f5419b 100644 --- a/sbin/ipf/libipf/parsefields.c +++ b/sbin/ipf/libipf/parsefields.c @@ -1,53 +1,51 @@ #include "ipf.h" #include extern int nohdrfields; -wordtab_t *parsefields(table, arg) - wordtab_t *table; - char *arg; +wordtab_t *parsefields(wordtab_t *table, char *arg) { wordtab_t *f, *fields; char *s, *t; int num; fields = NULL; num = 0; for (s = strtok(arg, ","); s != NULL; s = strtok(NULL, ",")) { t = strchr(s, '='); if (t != NULL) { *t++ = '\0'; if (*t == '\0') nohdrfields = 1; } f = findword(table, s); if (f == NULL) { fprintf(stderr, "Unknown field '%s'\n", s); exit(1); } num++; if (fields == NULL) { fields = malloc(2 * sizeof(*fields)); } else { fields = reallocarray(fields, num + 1, sizeof(*fields)); if (fields == NULL) { warnx("memory allocation error at %d in %s in %s", __LINE__, __FUNCTION__, __FILE__); abort(); } } if (t == NULL) { fields[num - 1].w_word = f->w_word; } else { fields[num - 1].w_word = t; } fields[num - 1].w_value = f->w_value; fields[num].w_word = NULL; fields[num].w_value = 0; } return fields; } diff --git a/sbin/ipf/libipf/parseipfexpr.c b/sbin/ipf/libipf/parseipfexpr.c index b4b00f91bfca..415c4b543a8e 100644 --- a/sbin/ipf/libipf/parseipfexpr.c +++ b/sbin/ipf/libipf/parseipfexpr.c @@ -1,283 +1,281 @@ #include "ipf.h" #include typedef struct ipfopentry { int ipoe_cmd; int ipoe_nbasearg; int ipoe_maxarg; int ipoe_argsize; char *ipoe_word; } ipfopentry_t; static ipfopentry_t opwords[17] = { { IPF_EXP_IP_ADDR, 2, 0, 1, "ip.addr" }, { IPF_EXP_IP6_ADDR, 2, 0, 4, "ip6.addr" }, { IPF_EXP_IP_PR, 1, 0, 1, "ip.p" }, { IPF_EXP_IP_SRCADDR, 2, 0, 1, "ip.src" }, { IPF_EXP_IP_DSTADDR, 2, 0, 1, "ip.dst" }, { IPF_EXP_IP6_SRCADDR, 2, 0, 4, "ip6.src" }, { IPF_EXP_IP6_DSTADDR, 2, 0, 4, "ip6.dst" }, { IPF_EXP_TCP_PORT, 1, 0, 1, "tcp.port" }, { IPF_EXP_TCP_DPORT, 1, 0, 1, "tcp.dport" }, { IPF_EXP_TCP_SPORT, 1, 0, 1, "tcp.sport" }, { IPF_EXP_TCP_FLAGS, 2, 0, 1, "tcp.flags" }, { IPF_EXP_UDP_PORT, 1, 0, 1, "udp.port" }, { IPF_EXP_UDP_DPORT, 1, 0, 1, "udp.dport" }, { IPF_EXP_UDP_SPORT, 1, 0, 1, "udp.sport" }, { IPF_EXP_TCP_STATE, 1, 0, 1, "tcp.state" }, { IPF_EXP_IDLE_GT, 1, 1, 1, "idle-gt" }, { -1, 0, 0, 0, NULL } }; int * -parseipfexpr(line, errorptr) - char *line; - char **errorptr; +parseipfexpr(char *line, char **errorptr) { int not, items, asize, *oplist, osize, i; char *temp, *arg, *s, *t, *ops, *error; ipfopentry_t *e; ipfexp_t *ipfe; asize = 0; error = NULL; oplist = NULL; temp = strdup(line); if (temp == NULL) { error = "strdup failed"; goto parseerror; } /* * Eliminate any white spaces to make parsing easier. */ for (s = temp; *s != '\0'; ) { if (ISSPACE(*s)) strcpy(s, s + 1); else s++; } /* * Parse the string. * It should be sets of "ip.dst=1.2.3.4/32;" things. * There must be a "=" or "!=" and it must end in ";". */ if (temp[strlen(temp) - 1] != ';') { error = "last character not ';'"; goto parseerror; } /* * Work through the list of complete operands present. */ for (ops = strtok(temp, ";"); ops != NULL; ops = strtok(NULL, ";")) { arg = strchr(ops, '='); if ((arg < ops + 2) || (arg == NULL)) { error = "bad 'arg' vlaue"; goto parseerror; } if (*(arg - 1) == '!') { *(arg - 1) = '\0'; not = 1; } else { not = 0; } *arg++ = '\0'; for (e = opwords; e->ipoe_word; e++) { if (strcmp(ops, e->ipoe_word) == 0) break; } if (e->ipoe_word == NULL) { error = malloc(32); if (error != NULL) { snprintf(error, sizeof(error), "keyword (%.10s) not found", ops); } goto parseerror; } /* * Count the number of commas so we know how big to * build the array */ for (s = arg, items = 1; *s != '\0'; s++) if (*s == ',') items++; if ((e->ipoe_maxarg != 0) && (items > e->ipoe_maxarg)) { error = "too many items"; goto parseerror; } /* * osize will mark the end of where we have filled up to * and is thus where we start putting new data. */ osize = asize; asize += 4 + (items * e->ipoe_nbasearg * e->ipoe_argsize); if (oplist == NULL) oplist = calloc(asize + 2, sizeof(int)); else oplist = reallocarray(oplist, asize + 2, sizeof(int)); if (oplist == NULL) { error = "oplist alloc failed"; goto parseerror; } ipfe = (ipfexp_t *)(oplist + osize); osize += 4; ipfe->ipfe_cmd = e->ipoe_cmd; ipfe->ipfe_not = not; ipfe->ipfe_narg = items * e->ipoe_nbasearg; ipfe->ipfe_size = items * e->ipoe_nbasearg * e->ipoe_argsize; ipfe->ipfe_size += 4; for (s = arg; (*s != '\0') && (osize < asize); s = t) { /* * Look for the end of this arg or the ',' to say * there is another following. */ for (t = s; (*t != '\0') && (*t != ','); t++) ; if (*t == ',') *t++ = '\0'; if (!strcasecmp(ops, "ip.addr") || !strcasecmp(ops, "ip.src") || !strcasecmp(ops, "ip.dst")) { i6addr_t mask, addr; char *delim; delim = strchr(s, '/'); if (delim != NULL) { *delim++ = '\0'; if (genmask(AF_INET, delim, &mask) == -1) { error = "genmask failed"; goto parseerror; } } else { mask.in4.s_addr = 0xffffffff; } if (gethost(AF_INET, s, &addr) == -1) { error = "gethost failed"; goto parseerror; } oplist[osize++] = addr.in4.s_addr; oplist[osize++] = mask.in4.s_addr; #ifdef USE_INET6 } else if (!strcasecmp(ops, "ip6.addr") || !strcasecmp(ops, "ip6.src") || !strcasecmp(ops, "ip6.dst")) { i6addr_t mask, addr; char *delim; delim = strchr(s, '/'); if (delim != NULL) { *delim++ = '\0'; if (genmask(AF_INET6, delim, &mask) == -1) { error = "genmask failed"; goto parseerror; } } else { mask.i6[0] = 0xffffffff; mask.i6[1] = 0xffffffff; mask.i6[2] = 0xffffffff; mask.i6[3] = 0xffffffff; } if (gethost(AF_INET6, s, &addr) == -1) { error = "gethost failed"; goto parseerror; } oplist[osize++] = addr.i6[0]; oplist[osize++] = addr.i6[1]; oplist[osize++] = addr.i6[2]; oplist[osize++] = addr.i6[3]; oplist[osize++] = mask.i6[0]; oplist[osize++] = mask.i6[1]; oplist[osize++] = mask.i6[2]; oplist[osize++] = mask.i6[3]; #endif } else if (!strcasecmp(ops, "ip.p")) { int p; p = getproto(s); if (p == -1) goto parseerror; oplist[osize++] = p; } else if (!strcasecmp(ops, "tcp.flags")) { u_32_t mask, flags; char *delim; delim = strchr(s, '/'); if (delim != NULL) { *delim++ = '\0'; mask = tcpflags(delim); } else { mask = 0xff; } flags = tcpflags(s); oplist[osize++] = flags; oplist[osize++] = mask; } else if (!strcasecmp(ops, "tcp.port") || !strcasecmp(ops, "tcp.sport") || !strcasecmp(ops, "tcp.dport") || !strcasecmp(ops, "udp.port") || !strcasecmp(ops, "udp.sport") || !strcasecmp(ops, "udp.dport")) { char proto[4]; u_short port; strncpy(proto, ops, 3); proto[3] = '\0'; if (getport(NULL, s, &port, proto) == -1) goto parseerror; oplist[osize++] = port; } else if (!strcasecmp(ops, "tcp.state")) { oplist[osize++] = atoi(s); } else { error = "unknown word"; goto parseerror; } } } free(temp); if (errorptr != NULL) *errorptr = NULL; for (i = asize; i > 0; i--) oplist[i] = oplist[i - 1]; oplist[0] = asize + 2; oplist[asize + 1] = IPF_EXP_END; return oplist; parseerror: if (errorptr != NULL) *errorptr = error; if (oplist != NULL) free(oplist); if (temp != NULL) free(temp); return NULL; } diff --git a/sbin/ipf/libipf/parsewhoisline.c b/sbin/ipf/libipf/parsewhoisline.c index 526935ca23a5..eb26a3efa348 100644 --- a/sbin/ipf/libipf/parsewhoisline.c +++ b/sbin/ipf/libipf/parsewhoisline.c @@ -1,132 +1,129 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: parsewhoisline.c,v 1.2.2.5 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" /* Microsoft Corp MICROSOFT19 (NET-198-136-97-0-1) 198.137.97.0 - 198.137.97.255 Microsoft Corp SAVV-S233053-6 (NET-206-79-74-32-1) 206.79.74.32 - 206.79.74.47 */ int -parsewhoisline(line, addrp, maskp) - char *line; - addrfamily_t *addrp; - addrfamily_t *maskp; +parsewhoisline(char *line, addrfamily_t *addrp, addrfamily_t *maskp) { struct in_addr a1, a2; char *src = line; char *s = NULL; if (line == NULL) return -1; while (*src != '\0') { s = strchr(src, '('); if (s == NULL) break; if (strncmp(s, "(NET", 4)) { src = s + 1; } break; } if (s == NULL) return -1; memset(addrp, 0x00, sizeof(*maskp)); memset(maskp, 0x00, sizeof(*maskp)); if (*(s + 4) == '6') { #ifdef USE_INET6 i6addr_t a61, a62; s = strchr(s, ')'); if (s == NULL || *++s != ' ') return -1; /* * Parse the IPv6 */ if (inet_pton(AF_INET6, s, &a61.in6) != 1) return -1; s = strchr(s, ' '); if (s == NULL || strncmp(s, " - ", 3)) return -1; s += 3; if (inet_pton(AF_INET6, s, &a62) != 1) return -1; addrp->adf_addr = a61; addrp->adf_family = AF_INET6; addrp->adf_len = offsetof(addrfamily_t, adf_addr) + sizeof(struct in6_addr); maskp->adf_addr.i6[0] = ~(a62.i6[0] ^ a61.i6[0]); maskp->adf_addr.i6[1] = ~(a62.i6[1] ^ a61.i6[1]); maskp->adf_addr.i6[2] = ~(a62.i6[2] ^ a61.i6[2]); maskp->adf_addr.i6[3] = ~(a62.i6[3] ^ a61.i6[3]); /* * If the mask that's been generated isn't a consecutive mask * then we can't add it into a pool. */ if (count6bits(maskp->adf_addr.i6) == -1) return -1; maskp->adf_family = AF_INET6; maskp->adf_len = addrp->adf_len; if (IP6_MASKNEQ(&addrp->adf_addr.in6, &maskp->adf_addr.in6, &addrp->adf_addr.in6)) { return -1; } return 0; #else return -1; #endif } s = strchr(s, ')'); if (s == NULL || *++s != ' ') return -1; s++; if (inet_aton(s, &a1) != 1) return -1; s = strchr(s, ' '); if (s == NULL || strncmp(s, " - ", 3)) return -1; s += 3; if (inet_aton(s, &a2) != 1) return -1; addrp->adf_addr.in4 = a1; addrp->adf_family = AF_INET; addrp->adf_len = offsetof(addrfamily_t, adf_addr) + sizeof(struct in_addr); maskp->adf_addr.in4.s_addr = ~(a2.s_addr ^ a1.s_addr); /* * If the mask that's been generated isn't a consecutive mask then * we can't add it into a pool. */ if (count4bits(maskp->adf_addr.in4.s_addr) == -1) return -1; maskp->adf_family = AF_INET; maskp->adf_len = addrp->adf_len; bzero((char *)maskp + maskp->adf_len, sizeof(*maskp) - maskp->adf_len); if ((addrp->adf_addr.in4.s_addr & maskp->adf_addr.in4.s_addr) != addrp->adf_addr.in4.s_addr) return -1; return 0; } diff --git a/sbin/ipf/libipf/poolio.c b/sbin/ipf/libipf/poolio.c index 18cf698222a8..83cfb8cf5047 100644 --- a/sbin/ipf/libipf/poolio.c +++ b/sbin/ipf/libipf/poolio.c @@ -1,53 +1,53 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: poolio.c,v 1.1.2.3 2012/07/22 08:04:24 darren_r Exp $ */ #include #include #include "ipf.h" #include "netinet/ip_lookup.h" #include "netinet/ip_pool.h" static int poolfd = -1; int -pool_open() +pool_open(void) { if ((opts & OPT_DONTOPEN) != 0) return 0; if (poolfd == -1) poolfd = open(IPLOOKUP_NAME, O_RDWR); return poolfd; } int pool_ioctl(iocfunc, cmd, ptr) ioctlfunc_t iocfunc; ioctlcmd_t cmd; void *ptr; { return (*iocfunc)(poolfd, cmd, ptr); } void -pool_close() +pool_close(void) { if (poolfd != -1) { close(poolfd); poolfd = -1; } } int -pool_fd() +pool_fd(void) { return poolfd; } diff --git a/sbin/ipf/libipf/prependmbt.c b/sbin/ipf/libipf/prependmbt.c index 4f7220ba236a..871e46be15a2 100644 --- a/sbin/ipf/libipf/prependmbt.c +++ b/sbin/ipf/libipf/prependmbt.c @@ -1,18 +1,16 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: prependmbt.c,v 1.3.2.3 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" -int prependmbt(fin, m) - fr_info_t *fin; - mb_t *m; +int prependmbt( fr_info_t *fin, mb_t *m) { m->mb_next = *fin->fin_mp; *fin->fin_mp = m; return 0; } diff --git a/sbin/ipf/libipf/print_toif.c b/sbin/ipf/libipf/print_toif.c index fb4a266318b4..438207bf7e72 100644 --- a/sbin/ipf/libipf/print_toif.c +++ b/sbin/ipf/libipf/print_toif.c @@ -1,50 +1,46 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" void -print_toif(family, tag, base, fdp) - int family; - char *tag; - char *base; - frdest_t *fdp; +print_toif(int family, char *tag, char *base, frdest_t *fdp) { switch (fdp->fd_type) { case FRD_NORMAL : PRINTF("%s %s%s", tag, base + fdp->fd_name, (fdp->fd_ptr || (long)fdp->fd_ptr == -1) ? "" : "(!)"); #ifdef USE_INET6 if (family == AF_INET6) { if (IP6_NOTZERO(&fdp->fd_ip6)) { char ipv6addr[80]; inet_ntop(AF_INET6, &fdp->fd_ip6, ipv6addr, sizeof(fdp->fd_ip6)); PRINTF(":%s", ipv6addr); } } else #endif if (fdp->fd_ip.s_addr) PRINTF(":%s", inet_ntoa(fdp->fd_ip)); putchar(' '); break; case FRD_DSTLIST : PRINTF("%s dstlist/%s ", tag, base + fdp->fd_name); break; default : PRINTF("%s <%d>", tag, fdp->fd_type); break; } } diff --git a/sbin/ipf/libipf/printactiveaddr.c b/sbin/ipf/libipf/printactiveaddr.c index 531cdc1fc782..66b5b00aaf98 100644 --- a/sbin/ipf/libipf/printactiveaddr.c +++ b/sbin/ipf/libipf/printactiveaddr.c @@ -1,37 +1,34 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) */ #include "ipf.h" #if !defined(lint) static const char rcsid[] = "@(#)$Id: printactiveaddr.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $"; #endif void -printactiveaddress(v, fmt, addr, ifname) - int v; - char *fmt, *ifname; - i6addr_t *addr; +printactiveaddress(int v, char *fmt, i6addr_t *addr, char *ifname) { switch (v) { case 4 : PRINTF(fmt, inet_ntoa(addr->in4)); break; #ifdef USE_INET6 case 6 : printaddr(AF_INET6, FRI_NORMAL, ifname, 0, (u_32_t *)&addr->in6, NULL); break; #endif default : break; } } diff --git a/sbin/ipf/libipf/printactivenat.c b/sbin/ipf/libipf/printactivenat.c index c696c0b2cacd..fcef19a4efa7 100644 --- a/sbin/ipf/libipf/printactivenat.c +++ b/sbin/ipf/libipf/printactivenat.c @@ -1,149 +1,146 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) */ #include "ipf.h" #if !defined(lint) static const char rcsid[] = "@(#)$Id$"; #endif void -printactivenat(nat, opts, ticks) - nat_t *nat; - int opts; - u_long ticks; +printactivenat(nat_t *nat, int opts, u_long ticks) { PRINTF("%s", getnattype(nat)); if (nat->nat_flags & SI_CLONE) PRINTF(" CLONE"); if (nat->nat_phnext[0] == NULL && nat->nat_phnext[1] == NULL) PRINTF(" ORPHAN"); putchar(' '); if (nat->nat_redir & NAT_REWRITE) { printactiveaddress(nat->nat_v[0], "%-15s", &nat->nat_osrc6, nat->nat_ifnames[0]); if ((nat->nat_flags & IPN_TCPUDP) != 0) PRINTF(" %-5hu", ntohs(nat->nat_osport)); putchar(' '); printactiveaddress(nat->nat_v[0], "%-15s", &nat->nat_odst6, nat->nat_ifnames[0]); if ((nat->nat_flags & IPN_TCPUDP) != 0) PRINTF(" %-5hu", ntohs(nat->nat_odport)); PRINTF("<- -> "); printactiveaddress(nat->nat_v[1], "%-15s", &nat->nat_nsrc6, nat->nat_ifnames[0]); if ((nat->nat_flags & IPN_TCPUDP) != 0) PRINTF(" %-5hu", ntohs(nat->nat_nsport)); putchar(' '); printactiveaddress(nat->nat_v[1], "%-15s", &nat->nat_ndst6, nat->nat_ifnames[0]); if ((nat->nat_flags & IPN_TCPUDP) != 0) PRINTF(" %-5hu", ntohs(nat->nat_ndport)); } else if (nat->nat_dir == NAT_OUTBOUND) { printactiveaddress(nat->nat_v[0], "%-15s", &nat->nat_osrc6, nat->nat_ifnames[0]); if ((nat->nat_flags & IPN_TCPUDP) != 0) PRINTF(" %-5hu", ntohs(nat->nat_osport)); PRINTF(" <- -> "); printactiveaddress(nat->nat_v[1], "%-15s", &nat->nat_nsrc6, nat->nat_ifnames[0]); if ((nat->nat_flags & IPN_TCPUDP) != 0) PRINTF(" %-5hu", ntohs(nat->nat_nsport)); PRINTF(" ["); printactiveaddress(nat->nat_v[0], "%s", &nat->nat_odst6, nat->nat_ifnames[0]); if ((nat->nat_flags & IPN_TCPUDP) != 0) PRINTF(" %hu", ntohs(nat->nat_odport)); PRINTF("]"); } else { printactiveaddress(nat->nat_v[1], "%-15s", &nat->nat_ndst6, nat->nat_ifnames[0]); if ((nat->nat_flags & IPN_TCPUDP) != 0) PRINTF(" %-5hu", ntohs(nat->nat_ndport)); PRINTF(" <- -> "); printactiveaddress(nat->nat_v[0], "%-15s", &nat->nat_odst6, nat->nat_ifnames[0]); if ((nat->nat_flags & IPN_TCPUDP) != 0) PRINTF(" %-5hu", ntohs(nat->nat_odport)); PRINTF(" ["); printactiveaddress(nat->nat_v[0], "%s", &nat->nat_osrc6, nat->nat_ifnames[0]); if ((nat->nat_flags & IPN_TCPUDP) != 0) PRINTF(" %hu", ntohs(nat->nat_osport)); PRINTF("]"); } if (opts & OPT_VERBOSE) { PRINTF("\n\tttl %lu use %hu sumd %s/", nat->nat_age - ticks, nat->nat_use, getsumd(nat->nat_sumd[0])); PRINTF("%s pr %u/%u hash %u/%u flags %x\n", getsumd(nat->nat_sumd[1]), nat->nat_pr[0], nat->nat_pr[1], nat->nat_hv[0], nat->nat_hv[1], nat->nat_flags); PRINTF("\tifp %s", getifname(nat->nat_ifps[0])); PRINTF(",%s ", getifname(nat->nat_ifps[1])); #ifdef USE_QUAD_T PRINTF("bytes %"PRIu64"/%"PRIu64" pkts %"PRIu64"/%"PRIu64"", (unsigned long long)nat->nat_bytes[0], (unsigned long long)nat->nat_bytes[1], (unsigned long long)nat->nat_pkts[0], (unsigned long long)nat->nat_pkts[1]); #else PRINTF("bytes %lu/%lu pkts %lu/%lu", nat->nat_bytes[0], nat->nat_bytes[1], nat->nat_pkts[0], nat->nat_pkts[1]); #endif PRINTF(" ipsumd %x", nat->nat_ipsumd); } if (opts & OPT_DEBUG) { PRINTF("\n\tnat_next %p _pnext %p _hm %p\n", nat->nat_next, nat->nat_pnext, nat->nat_hm); PRINTF("\t_hnext %p/%p _phnext %p/%p\n", nat->nat_hnext[0], nat->nat_hnext[1], nat->nat_phnext[0], nat->nat_phnext[1]); PRINTF("\t_data %p _me %p _state %p _aps %p\n", nat->nat_data, nat->nat_me, nat->nat_state, nat->nat_aps); PRINTF("\tfr %p ptr %p ifps %p/%p sync %p\n", nat->nat_fr, nat->nat_ptr, nat->nat_ifps[0], nat->nat_ifps[1], nat->nat_sync); PRINTF("\ttqe:pnext %p next %p ifq %p parent %p/%p\n", nat->nat_tqe.tqe_pnext, nat->nat_tqe.tqe_next, nat->nat_tqe.tqe_ifq, nat->nat_tqe.tqe_parent, nat); PRINTF("\ttqe:die %d touched %d flags %x state %d/%d\n", nat->nat_tqe.tqe_die, nat->nat_tqe.tqe_touched, nat->nat_tqe.tqe_flags, nat->nat_tqe.tqe_state[0], nat->nat_tqe.tqe_state[1]); } putchar('\n'); } diff --git a/sbin/ipf/libipf/printaddr.c b/sbin/ipf/libipf/printaddr.c index 03fbacbcce74..461f62bcad55 100644 --- a/sbin/ipf/libipf/printaddr.c +++ b/sbin/ipf/libipf/printaddr.c @@ -1,75 +1,73 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" void -printaddr(family, type, base, ifidx, addr, mask) - int family, type, ifidx; - char *base; - u_32_t *addr, *mask; +printaddr(int family, int type, char *base, int ifidx, u_32_t *addr, + u_32_t *mask) { char *suffix; switch (type) { case FRI_BROADCAST : suffix = "bcast"; break; case FRI_DYNAMIC : PRINTF("%s", base + ifidx); printmask(family, mask); suffix = NULL; break; case FRI_NETWORK : suffix = "net"; break; case FRI_NETMASKED : suffix = "netmasked"; break; case FRI_PEERADDR : suffix = "peer"; break; case FRI_LOOKUP : suffix = NULL; printlookup(base, (i6addr_t *)addr, (i6addr_t *)mask); break; case FRI_NONE : case FRI_NORMAL : printhostmask(family, addr, mask); suffix = NULL; break; case FRI_RANGE : printhost(family, addr); putchar('-'); printhost(family, mask); suffix = NULL; break; case FRI_SPLIT : printhost(family, addr); putchar(','); printhost(family, mask); suffix = NULL; break; default : PRINTF("<%d>", type); printmask(family, mask); suffix = NULL; break; } if (suffix != NULL) { PRINTF("%s/%s", base + ifidx, suffix); } } diff --git a/sbin/ipf/libipf/printaps.c b/sbin/ipf/libipf/printaps.c index 47c8def6106b..00e4db4cb2b8 100644 --- a/sbin/ipf/libipf/printaps.c +++ b/sbin/ipf/libipf/printaps.c @@ -1,113 +1,111 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) */ #include "ipf.h" #include "kmem.h" #if !defined(lint) static const char rcsid[] = "@(#)$Id$"; #endif void -printaps(aps, opts, proto) - ap_session_t *aps; - int opts, proto; +printaps(ap_session_t *aps, int opts, int proto) { ipsec_pxy_t ipsec; ap_session_t ap; ftpinfo_t ftp; aproxy_t apr; raudio_t ra; if (kmemcpy((char *)&ap, (long)aps, sizeof(ap))) return; if (kmemcpy((char *)&apr, (long)ap.aps_apr, sizeof(apr))) return; PRINTF("\tproxy %s/%d use %d flags %x\n", apr.apr_label, apr.apr_p, apr.apr_ref, apr.apr_flags); #ifdef USE_QUAD_T PRINTF("\tbytes %"PRIu64" pkts %"PRIu64"", (unsigned long long)ap.aps_bytes, (unsigned long long)ap.aps_pkts); #else PRINTF("\tbytes %lu pkts %lu", ap.aps_bytes, ap.aps_pkts); #endif PRINTF(" data %s\n", ap.aps_data ? "YES" : "NO"); if ((proto == IPPROTO_TCP) && (opts & OPT_VERBOSE)) { PRINTF("\t\tstate[%u,%u], sel[%d,%d]\n", ap.aps_state[0], ap.aps_state[1], ap.aps_sel[0], ap.aps_sel[1]); #if (defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011)) || \ defined(__FreeBSD__) PRINTF("\t\tseq: off %hd/%hd min %x/%x\n", ap.aps_seqoff[0], ap.aps_seqoff[1], ap.aps_seqmin[0], ap.aps_seqmin[1]); PRINTF("\t\tack: off %hd/%hd min %x/%x\n", ap.aps_ackoff[0], ap.aps_ackoff[1], ap.aps_ackmin[0], ap.aps_ackmin[1]); #else PRINTF("\t\tseq: off %hd/%hd min %lx/%lx\n", ap.aps_seqoff[0], ap.aps_seqoff[1], ap.aps_seqmin[0], ap.aps_seqmin[1]); PRINTF("\t\tack: off %hd/%hd min %lx/%lx\n", ap.aps_ackoff[0], ap.aps_ackoff[1], ap.aps_ackmin[0], ap.aps_ackmin[1]); #endif } if (!strcmp(apr.apr_label, "raudio") && ap.aps_psiz == sizeof(ra)) { if (kmemcpy((char *)&ra, (long)ap.aps_data, sizeof(ra))) return; PRINTF("\tReal Audio Proxy:\n"); PRINTF("\t\tSeen PNA: %d\tVersion: %d\tEOS: %d\n", ra.rap_seenpna, ra.rap_version, ra.rap_eos); PRINTF("\t\tMode: %#x\tSBF: %#x\n", ra.rap_mode, ra.rap_sbf); PRINTF("\t\tPorts:pl %hu, pr %hu, sr %hu\n", ra.rap_plport, ra.rap_prport, ra.rap_srport); } else if (!strcmp(apr.apr_label, "ftp") && (ap.aps_psiz == sizeof(ftp))) { if (kmemcpy((char *)&ftp, (long)ap.aps_data, sizeof(ftp))) return; PRINTF("\tFTP Proxy:\n"); PRINTF("\t\tpassok: %d\n", ftp.ftp_passok); ftp.ftp_side[0].ftps_buf[FTP_BUFSZ - 1] = '\0'; ftp.ftp_side[1].ftps_buf[FTP_BUFSZ - 1] = '\0'; PRINTF("\tClient:\n"); PRINTF("\t\tseq %x (ack %x) len %d junk %d cmds %d\n", ftp.ftp_side[0].ftps_seq[0], ftp.ftp_side[0].ftps_seq[1], ftp.ftp_side[0].ftps_len, ftp.ftp_side[0].ftps_junk, ftp.ftp_side[0].ftps_cmds); PRINTF("\t\tbuf ["); printbuf(ftp.ftp_side[0].ftps_buf, FTP_BUFSZ, 1); PRINTF("]\n\tServer:\n"); PRINTF("\t\tseq %x (ack %x) len %d junk %d cmds %d\n", ftp.ftp_side[1].ftps_seq[0], ftp.ftp_side[1].ftps_seq[1], ftp.ftp_side[1].ftps_len, ftp.ftp_side[1].ftps_junk, ftp.ftp_side[1].ftps_cmds); PRINTF("\t\tbuf ["); printbuf(ftp.ftp_side[1].ftps_buf, FTP_BUFSZ, 1); PRINTF("]\n"); } else if (!strcmp(apr.apr_label, "ipsec") && (ap.aps_psiz == sizeof(ipsec))) { if (kmemcpy((char *)&ipsec, (long)ap.aps_data, sizeof(ipsec))) return; PRINTF("\tIPSec Proxy:\n"); PRINTF("\t\tICookie %08x%08x RCookie %08x%08x %s\n", (u_int)ntohl(ipsec.ipsc_icookie[0]), (u_int)ntohl(ipsec.ipsc_icookie[1]), (u_int)ntohl(ipsec.ipsc_rcookie[0]), (u_int)ntohl(ipsec.ipsc_rcookie[1]), ipsec.ipsc_rckset ? "(Set)" : "(Not set)"); } } diff --git a/sbin/ipf/libipf/printbuf.c b/sbin/ipf/libipf/printbuf.c index 4e9236f0d02d..3a9281217f6a 100644 --- a/sbin/ipf/libipf/printbuf.c +++ b/sbin/ipf/libipf/printbuf.c @@ -1,34 +1,32 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include "ipf.h" void -printbuf(buf, len, zend) - char *buf; - int len, zend; +printbuf(char *buf, int len, int zend) { char *s; int c; int i; for (s = buf, i = len; i; i--) { c = *s++; if (isprint(c)) putchar(c); else PRINTF("\\%03o", c); if ((c == '\0') && zend) break; } } diff --git a/sbin/ipf/libipf/printdstl_live.c b/sbin/ipf/libipf/printdstl_live.c index c8741ed4005a..684da8f0003a 100644 --- a/sbin/ipf/libipf/printdstl_live.c +++ b/sbin/ipf/libipf/printdstl_live.c @@ -1,84 +1,80 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include #include "ipf.h" #include "netinet/ipl.h" /* * Because the ipf_dstnode_t can vary in size because of the interface name, * the size may be larger than just sizeof(). */ ippool_dst_t * -printdstl_live(d, fd, name, opts, fields) - ippool_dst_t *d; - int fd; - char *name; - int opts; - wordtab_t *fields; +printdstl_live( ippool_dst_t *d, int fd, char *name, int opts, + wordtab_t *fields) { ipf_dstnode_t *entry, *zero; ipflookupiter_t iter; int printed, last; ipfobj_t obj; if ((name != NULL) && strncmp(name, d->ipld_name, FR_GROUPLEN)) return d->ipld_next; entry = calloc(1, sizeof(*entry) + 64); if (entry == NULL) return d->ipld_next; zero = calloc(1, sizeof(*zero) + 64); if (zero == NULL) { free(entry); return d->ipld_next; } if (fields == NULL) printdstlistdata(d, opts); if ((d->ipld_flags & IPHASH_DELETE) != 0) PRINTF("# "); if ((opts & OPT_DEBUG) == 0) PRINTF("\t{"); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_LOOKUPITER; obj.ipfo_ptr = &iter; obj.ipfo_size = sizeof(iter); iter.ili_data = entry; iter.ili_type = IPLT_DSTLIST; iter.ili_otype = IPFLOOKUPITER_NODE; iter.ili_ival = IPFGENITER_LOOKUP; iter.ili_unit = d->ipld_unit; strncpy(iter.ili_name, d->ipld_name, FR_GROUPLEN); last = 0; printed = 0; while (!last && (ioctl(fd, SIOCLOOKUPITER, &obj) == 0)) { if (entry->ipfd_next == NULL) last = 1; if (bcmp((char *)zero, (char *)entry, sizeof(*zero)) == 0) break; (void) printdstlistnode(entry, bcopywrap, opts, fields); printed++; } (void) ioctl(fd, SIOCIPFDELTOK, &iter.ili_key); free(entry); free(zero); if (printed == 0) putchar(';'); if ((opts & OPT_DEBUG) == 0) PRINTF(" };\n"); return d->ipld_next; } diff --git a/sbin/ipf/libipf/printdstlist.c b/sbin/ipf/libipf/printdstlist.c index 829a1d2e69ce..6468e6ca8ef6 100644 --- a/sbin/ipf/libipf/printdstlist.c +++ b/sbin/ipf/libipf/printdstlist.c @@ -1,60 +1,55 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" ippool_dst_t * -printdstlist(pp, copyfunc, name, opts, nodes, fields) - ippool_dst_t *pp; - copyfunc_t copyfunc; - char *name; - int opts; - ipf_dstnode_t *nodes; - wordtab_t *fields; +printdstlist( ippool_dst_t *pp, copyfunc_t copyfunc, char *name, int opts, + ipf_dstnode_t *nodes, wordtab_t *fields) { ipf_dstnode_t *node; ippool_dst_t dst; if ((*copyfunc)(pp, &dst, sizeof(dst))) return NULL; if ((name != NULL) && strncmp(name, dst.ipld_name, FR_GROUPLEN)) return dst.ipld_next; if (fields == NULL) printdstlistdata(&dst, opts); if ((dst.ipld_flags & IPDST_DELETE) != 0) PRINTF("# "); if ((opts & OPT_DEBUG) == 0) PRINTF("\t{"); if (nodes == NULL) { putchar(';'); } else { for (node = nodes; node != NULL; ) { ipf_dstnode_t *n; n = calloc(1, node->ipfd_size); if (n == NULL) break; if ((*copyfunc)(node, n, node->ipfd_size)) { free(n); return NULL; } node = printdstlistnode(n, bcopywrap, opts, fields); free(n); } } if ((opts & OPT_DEBUG) == 0) PRINTF(" };\n"); return dst.ipld_next; } diff --git a/sbin/ipf/libipf/printdstlistdata.c b/sbin/ipf/libipf/printdstlistdata.c index 8b55afdb57c7..7940d2ae021b 100644 --- a/sbin/ipf/libipf/printdstlistdata.c +++ b/sbin/ipf/libipf/printdstlistdata.c @@ -1,47 +1,45 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" #include void -printdstlistdata(pool, opts) - ippool_dst_t *pool; - int opts; +printdstlistdata( ippool_dst_t *pool, int opts) { if ((opts & OPT_DEBUG) == 0) { if ((pool->ipld_flags & IPDST_DELETE) != 0) PRINTF("# "); PRINTF("pool "); } else { if ((pool->ipld_flags & IPDST_DELETE) != 0) PRINTF("# "); PRINTF("Name: %s\tRole: ", pool->ipld_name); } printunit(pool->ipld_unit); if ((opts & OPT_DEBUG) == 0) { PRINTF("/dstlist (name %s;", pool->ipld_name); if (pool->ipld_policy != IPLDP_NONE) { PRINTF(" policy "); printdstlistpolicy(pool->ipld_policy); putchar(';'); } PRINTF(")\n"); } else { putchar(' '); PRINTF("\tReferences: %d\n", pool->ipld_ref); if ((pool->ipld_flags & IPDST_DELETE) != 0) PRINTF("# "); PRINTF("Policy: \n"); printdstlistpolicy(pool->ipld_policy); PRINTF("\n\tNodes Starting at %p\n", pool->ipld_dests); } } diff --git a/sbin/ipf/libipf/printdstlistnode.c b/sbin/ipf/libipf/printdstlistnode.c index 898986d1c066..1728a5b88594 100644 --- a/sbin/ipf/libipf/printdstlistnode.c +++ b/sbin/ipf/libipf/printdstlistnode.c @@ -1,78 +1,75 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" ipf_dstnode_t * -printdstlistnode(inp, copyfunc, opts, fields) - ipf_dstnode_t *inp; - copyfunc_t copyfunc; - int opts; - wordtab_t *fields; +printdstlistnode(ipf_dstnode_t *inp, copyfunc_t copyfunc, int opts, + wordtab_t *fields) { ipf_dstnode_t node, *np; int i; #ifdef USE_INET6 char buf[INET6_ADDRSTRLEN+1]; const char *str; #endif if ((*copyfunc)(inp, &node, sizeof(node))) return NULL; np = calloc(1, node.ipfd_size); if (np == NULL) return node.ipfd_next; if ((*copyfunc)(inp, np, node.ipfd_size)) return NULL; if (fields != NULL) { for (i = 0; fields[i].w_value != 0; i++) { printpoolfield(np, IPLT_DSTLIST, i); if (fields[i + 1].w_value != 0) printf("\t"); } printf("\n"); } else if ((opts & OPT_DEBUG) == 0) { putchar(' '); if (np->ipfd_dest.fd_name >= 0) PRINTF("%s:", np->ipfd_names); if (np->ipfd_dest.fd_addr.adf_family == AF_INET) { printip(AF_INET, (u_32_t *)&np->ipfd_dest.fd_ip); } else { #ifdef USE_INET6 str = inet_ntop(AF_INET6, &np->ipfd_dest.fd_ip6, buf, sizeof(buf) - 1); if (str != NULL) PRINTF("%s", str); #endif } putchar(';'); } else { PRINTF("Interface: [%s]/%d\n", np->ipfd_names, np->ipfd_dest.fd_name); #ifdef USE_INET6 str = inet_ntop(np->ipfd_dest.fd_addr.adf_family, &np->ipfd_dest.fd_ip6, buf, sizeof(buf) - 1); if (str != NULL) { PRINTF("\tAddress: %s\n", str); } #else PRINTF("\tAddress: %s\n", inet_ntoa(np->ipfd_dest.fd_ip)); #endif PRINTF( #ifdef USE_QUAD_T "\t\tStates %d\tRef %d\tName [%s]\tUid %d\n", #else "\t\tStates %d\tRef %d\tName [%s]\tUid %d\n", #endif np->ipfd_states, np->ipfd_ref, np->ipfd_names, np->ipfd_uid); } free(np); return node.ipfd_next; } diff --git a/sbin/ipf/libipf/printdstlistpolicy.c b/sbin/ipf/libipf/printdstlistpolicy.c index 4873b95e207f..96df1bc0bce1 100644 --- a/sbin/ipf/libipf/printdstlistpolicy.c +++ b/sbin/ipf/libipf/printdstlistpolicy.c @@ -1,31 +1,30 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" void -printdstlistpolicy(policy) - ippool_policy_t policy; +printdstlistpolicy(ippool_policy_t policy) { switch (policy) { case IPLDP_NONE : PRINTF("none"); break; case IPLDP_ROUNDROBIN : PRINTF("round-robin"); break; case IPLDP_CONNECTION : PRINTF("weighting connection"); break; case IPLDP_RANDOM : PRINTF("random"); break; default : break; } } diff --git a/sbin/ipf/libipf/printfieldhdr.c b/sbin/ipf/libipf/printfieldhdr.c index f796f6fed62f..ba14af40499c 100644 --- a/sbin/ipf/libipf/printfieldhdr.c +++ b/sbin/ipf/libipf/printfieldhdr.c @@ -1,54 +1,53 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: printfieldhdr.c,v 1.5.2.3 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" #include void -printfieldhdr(words, field) - wordtab_t *words, *field; +printfieldhdr(wordtab_t *words, wordtab_t *field) { wordtab_t *w; char *s, *t; if (field->w_value == -2) { for (w = words; w->w_word != NULL; ) { if (w->w_value > 0) { printfieldhdr(words, w); w++; if (w->w_value > 0) putchar('\t'); } else { w++; } } return; } for (w = words; w->w_word != NULL; w++) { if (w->w_value == field->w_value) { if (w->w_word == field->w_word) { s = strdup(w->w_word); } else { s = NULL; } if ((w->w_word != field->w_word) || (s == NULL)) { PRINTF("%s", field->w_word); } else { for (t = s; *t != '\0'; t++) { if (ISALPHA(*t) && ISLOWER(*t)) *t = TOUPPER(*t); } PRINTF("%s", s); free(s); } } } } diff --git a/sbin/ipf/libipf/printfr.c b/sbin/ipf/libipf/printfr.c index 9883df48f8f4..2ffb65f69207 100644 --- a/sbin/ipf/libipf/printfr.c +++ b/sbin/ipf/libipf/printfr.c @@ -1,473 +1,471 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" /* * print the filter structure in a useful way */ void -printfr(fp, iocfunc) - struct frentry *fp; - ioctlfunc_t iocfunc; +printfr( struct frentry *fp, ioctlfunc_t iocfunc) { struct protoent *p; u_short sec[2]; u_32_t type; int pr, af; char *s; int hash; pr = -2; type = fp->fr_type & ~FR_T_BUILTIN; if ((fp->fr_type & FR_T_BUILTIN) != 0) PRINTF("# Builtin: "); if (fp->fr_collect != 0) PRINTF("%u ", fp->fr_collect); if (fp->fr_type == FR_T_CALLFUNC) { ; } else if (fp->fr_func != NULL) { PRINTF("call"); if ((fp->fr_flags & FR_CALLNOW) != 0) PRINTF(" now"); s = kvatoname(fp->fr_func, iocfunc); PRINTF(" %s/%u", s ? s : "?", fp->fr_arg); } else if (FR_ISPASS(fp->fr_flags)) PRINTF("pass"); else if (FR_ISBLOCK(fp->fr_flags)) { PRINTF("block"); } else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) { printlog(fp); } else if (FR_ISACCOUNT(fp->fr_flags)) PRINTF("count"); else if (FR_ISAUTH(fp->fr_flags)) PRINTF("auth"); else if (FR_ISPREAUTH(fp->fr_flags)) PRINTF("preauth"); else if (FR_ISNOMATCH(fp->fr_flags)) PRINTF("nomatch"); else if (FR_ISDECAPS(fp->fr_flags)) PRINTF("decapsulate"); else if (FR_ISSKIP(fp->fr_flags)) PRINTF("skip %u", fp->fr_arg); else { PRINTF("%x", fp->fr_flags); } if (fp->fr_flags & FR_RETICMP) { if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP) PRINTF(" return-icmp-as-dest"); else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP) PRINTF(" return-icmp"); if (fp->fr_icode) { if (fp->fr_icode <= MAX_ICMPCODE) PRINTF("(%s)", icmpcodes[(int)fp->fr_icode]); else PRINTF("(%d)", fp->fr_icode); } } else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST) PRINTF(" return-rst"); if (fp->fr_flags & FR_OUTQUE) PRINTF(" out "); else if (fp->fr_flags & FR_INQUE) PRINTF(" in "); if (((fp->fr_flags & FR_LOGB) == FR_LOGB) || ((fp->fr_flags & FR_LOGP) == FR_LOGP)) { printlog(fp); putchar(' '); } if (fp->fr_flags & FR_QUICK) PRINTF("quick "); if (fp->fr_ifnames[0] != -1) { printifname("on ", fp->fr_names + fp->fr_ifnames[0], fp->fr_ifa); if (fp->fr_ifnames[1] != -1 && strcmp(fp->fr_names + fp->fr_ifnames[1], "*")) printifname(",", fp->fr_names + fp->fr_ifnames[1], fp->fr_ifas[1]); putchar(' '); } if (fp->fr_tif.fd_name != -1) print_toif(fp->fr_family, "to", fp->fr_names, &fp->fr_tif); if (fp->fr_dif.fd_name != -1) print_toif(fp->fr_family, "dup-to", fp->fr_names, &fp->fr_dif); if (fp->fr_rif.fd_name != -1) print_toif(fp->fr_family, "reply-to", fp->fr_names, &fp->fr_rif); if (fp->fr_flags & FR_FASTROUTE) PRINTF("fastroute "); if ((fp->fr_ifnames[2] != -1 && strcmp(fp->fr_names + fp->fr_ifnames[2], "*")) || (fp->fr_ifnames[3] != -1 && strcmp(fp->fr_names + fp->fr_ifnames[3], "*"))) { if (fp->fr_flags & FR_OUTQUE) PRINTF("in-via "); else PRINTF("out-via "); if (fp->fr_ifnames[2] != -1) { printifname("", fp->fr_names + fp->fr_ifnames[2], fp->fr_ifas[2]); if (fp->fr_ifnames[3] != -1) { printifname(",", fp->fr_names + fp->fr_ifnames[3], fp->fr_ifas[3]); } putchar(' '); } } if (fp->fr_family == AF_INET) { PRINTF("inet "); af = AF_INET; #ifdef USE_INET6 } else if (fp->fr_family == AF_INET6) { PRINTF("inet6 "); af = AF_INET6; #endif } else { af = -1; } if (type == FR_T_IPF) { if (fp->fr_mip.fi_tos) PRINTF("tos %#x ", fp->fr_tos); if (fp->fr_mip.fi_ttl) PRINTF("ttl %d ", fp->fr_ttl); if (fp->fr_flx & FI_TCPUDP) { PRINTF("proto tcp/udp "); pr = -1; } else if (fp->fr_mip.fi_p) { pr = fp->fr_ip.fi_p; p = getprotobynumber(pr); PRINTF("proto "); printproto(p, pr, NULL); putchar(' '); } } switch (type) { case FR_T_NONE : PRINTF("all"); break; case FR_T_IPF : PRINTF("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : ""); printaddr(af, fp->fr_satype, fp->fr_names, fp->fr_ifnames[0], &fp->fr_src.s_addr, &fp->fr_smsk.s_addr); if (fp->fr_scmp) printportcmp(pr, &fp->fr_tuc.ftu_src); PRINTF(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : ""); printaddr(af, fp->fr_datype, fp->fr_names, fp->fr_ifnames[0], &fp->fr_dst.s_addr, &fp->fr_dmsk.s_addr); if (fp->fr_dcmp) printportcmp(pr, &fp->fr_tuc.ftu_dst); if (((fp->fr_proto == IPPROTO_ICMP) || (fp->fr_proto == IPPROTO_ICMPV6)) && fp->fr_icmpm) { int type = fp->fr_icmp, code; char *name; type = ntohs(fp->fr_icmp); code = type & 0xff; type /= 256; name = icmptypename(fp->fr_family, type); if (name == NULL) PRINTF(" icmp-type %d", type); else PRINTF(" icmp-type %s", name); if (ntohs(fp->fr_icmpm) & 0xff) PRINTF(" code %d", code); } if ((fp->fr_proto == IPPROTO_TCP) && (fp->fr_tcpf || fp->fr_tcpfm)) { PRINTF(" flags "); printtcpflags(fp->fr_tcpf, fp->fr_tcpfm); } break; case FR_T_BPFOPC : { fakebpf_t *fb; int i; PRINTF("bpf-v%d { \"", fp->fr_family); i = fp->fr_dsize / sizeof(*fb); for (fb = fp->fr_data, s = ""; i; i--, fb++, s = " ") PRINTF("%s%#x %#x %#x %#x", s, fb->fb_c, fb->fb_t, fb->fb_f, fb->fb_k); PRINTF("\" }"); break; } case FR_T_COMPIPF : break; case FR_T_CALLFUNC : PRINTF("call function at %p", fp->fr_data); break; case FR_T_IPFEXPR : PRINTF("exp { \""); printipfexpr(fp->fr_data); PRINTF("\" } "); break; default : PRINTF("[unknown filter type %#x]", fp->fr_type); break; } if ((type == FR_T_IPF) && ((fp->fr_flx & FI_WITH) || (fp->fr_mflx & FI_WITH) || fp->fr_optbits || fp->fr_optmask || fp->fr_secbits || fp->fr_secmask)) { char *comma = " "; PRINTF(" with"); if (fp->fr_optbits || fp->fr_optmask || fp->fr_secbits || fp->fr_secmask) { sec[0] = fp->fr_secmask; sec[1] = fp->fr_secbits; if (fp->fr_family == AF_INET) optprint(sec, fp->fr_optmask, fp->fr_optbits); #ifdef USE_INET6 else optprintv6(sec, fp->fr_optmask, fp->fr_optbits); #endif } else if (fp->fr_mflx & FI_OPTIONS) { fputs(comma, stdout); if (!(fp->fr_flx & FI_OPTIONS)) PRINTF("not "); PRINTF("ipopts"); comma = ","; } if (fp->fr_mflx & FI_SHORT) { fputs(comma, stdout); if (!(fp->fr_flx & FI_SHORT)) PRINTF("not "); PRINTF("short"); comma = ","; } if (fp->fr_mflx & FI_FRAG) { fputs(comma, stdout); if (!(fp->fr_flx & FI_FRAG)) PRINTF("not "); PRINTF("frag"); comma = ","; } if (fp->fr_mflx & FI_FRAGBODY) { fputs(comma, stdout); if (!(fp->fr_flx & FI_FRAGBODY)) PRINTF("not "); PRINTF("frag-body"); comma = ","; } if (fp->fr_mflx & FI_NATED) { fputs(comma, stdout); if (!(fp->fr_flx & FI_NATED)) PRINTF("not "); PRINTF("nat"); comma = ","; } if (fp->fr_mflx & FI_LOWTTL) { fputs(comma, stdout); if (!(fp->fr_flx & FI_LOWTTL)) PRINTF("not "); PRINTF("lowttl"); comma = ","; } if (fp->fr_mflx & FI_BAD) { fputs(comma, stdout); if (!(fp->fr_flx & FI_BAD)) PRINTF("not "); PRINTF("bad"); comma = ","; } if (fp->fr_mflx & FI_BADSRC) { fputs(comma, stdout); if (!(fp->fr_flx & FI_BADSRC)) PRINTF("not "); PRINTF("bad-src"); comma = ","; } if (fp->fr_mflx & FI_BADNAT) { fputs(comma, stdout); if (!(fp->fr_flx & FI_BADNAT)) PRINTF("not "); PRINTF("bad-nat"); comma = ","; } if (fp->fr_mflx & FI_OOW) { fputs(comma, stdout); if (!(fp->fr_flx & FI_OOW)) PRINTF("not "); PRINTF("oow"); comma = ","; } if (fp->fr_mflx & FI_MBCAST) { fputs(comma, stdout); if (!(fp->fr_flx & FI_MBCAST)) PRINTF("not "); PRINTF("mbcast"); comma = ","; } if (fp->fr_mflx & FI_BROADCAST) { fputs(comma, stdout); if (!(fp->fr_flx & FI_BROADCAST)) PRINTF("not "); PRINTF("bcast"); comma = ","; } if (fp->fr_mflx & FI_MULTICAST) { fputs(comma, stdout); if (!(fp->fr_flx & FI_MULTICAST)) PRINTF("not "); PRINTF("mcast"); comma = ","; } if (fp->fr_mflx & FI_STATE) { fputs(comma, stdout); if (!(fp->fr_flx & FI_STATE)) PRINTF("not "); PRINTF("state"); comma = ","; } if (fp->fr_mflx & FI_V6EXTHDR) { fputs(comma, stdout); if (!(fp->fr_flx & FI_V6EXTHDR)) PRINTF("not "); PRINTF("v6hdrs"); comma = ","; } } if (fp->fr_flags & FR_KEEPSTATE) { host_track_t *src = &fp->fr_srctrack; PRINTF(" keep state"); if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN| FR_NOICMPERR|FR_STATESYNC)) || (fp->fr_statemax != 0) || (fp->fr_age[0] != 0) || (src->ht_max_nodes != 0)) { char *comma = ""; PRINTF(" ("); if (fp->fr_statemax != 0) { PRINTF("limit %u", fp->fr_statemax); comma = ","; } if (src->ht_max_nodes != 0) { PRINTF("%smax-nodes %d", comma, src->ht_max_nodes); if (src->ht_max_per_node) PRINTF(", max-per-src %d/%d", src->ht_max_per_node, src->ht_netmask); comma = ","; } if (fp->fr_flags & FR_STSTRICT) { PRINTF("%sstrict", comma); comma = ","; } if (fp->fr_flags & FR_STLOOSE) { PRINTF("%sloose", comma); comma = ","; } if (fp->fr_flags & FR_NEWISN) { PRINTF("%snewisn", comma); comma = ","; } if (fp->fr_flags & FR_NOICMPERR) { PRINTF("%sno-icmp-err", comma); comma = ","; } if (fp->fr_flags & FR_STATESYNC) { PRINTF("%ssync", comma); comma = ","; } if (fp->fr_age[0] || fp->fr_age[1]) PRINTF("%sage %d/%d", comma, fp->fr_age[0], fp->fr_age[1]); PRINTF(")"); } } if (fp->fr_flags & FR_KEEPFRAG) { PRINTF(" keep frags"); if (fp->fr_flags & (FR_FRSTRICT)) { PRINTF(" ("); if (fp->fr_flags & FR_FRSTRICT) PRINTF("strict"); PRINTF(")"); } } if (fp->fr_isc != (struct ipscan *)-1) { if (fp->fr_isctag != -1) PRINTF(" scan %s", fp->fr_isctag + fp->fr_names); else PRINTF(" scan *"); } if (fp->fr_grhead != -1) PRINTF(" head %s", fp->fr_names + fp->fr_grhead); if (fp->fr_group != -1) PRINTF(" group %s", fp->fr_names + fp->fr_group); if (fp->fr_logtag != FR_NOLOGTAG || *fp->fr_nattag.ipt_tag) { char *s = ""; PRINTF(" set-tag("); if (fp->fr_logtag != FR_NOLOGTAG) { PRINTF("log=%u", fp->fr_logtag); s = ", "; } if (*fp->fr_nattag.ipt_tag) { PRINTF("%snat=%-.*s", s, IPFTAG_LEN, fp->fr_nattag.ipt_tag); } PRINTF(")"); } if (fp->fr_pps) PRINTF(" pps %d", fp->fr_pps); if (fp->fr_comment != -1) PRINTF(" comment \"%s\"", fp->fr_names + fp->fr_comment); hash = 0; if ((fp->fr_flags & FR_KEEPSTATE) && (opts & OPT_VERBOSE)) { PRINTF(" # count %d", fp->fr_statecnt); if (fp->fr_die != 0) PRINTF(" rule-ttl %u", fp->fr_die); hash = 1; } else if (fp->fr_die != 0) { PRINTF(" # rule-ttl %u", fp->fr_die); hash = 1; } if (opts & OPT_DEBUG) { if (hash == 0) putchar('#'); PRINTF(" ref %d", fp->fr_ref); } (void)putchar('\n'); } diff --git a/sbin/ipf/libipf/printfraginfo.c b/sbin/ipf/libipf/printfraginfo.c index dd2966fc05b5..fcafdde707be 100644 --- a/sbin/ipf/libipf/printfraginfo.c +++ b/sbin/ipf/libipf/printfraginfo.c @@ -1,42 +1,40 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #include "kmem.h" void -printfraginfo(prefix, ifr) - char *prefix; - struct ipfr *ifr; +printfraginfo(char *prefix, struct ipfr *ifr) { frentry_t fr; int family; PRINTF("%s", prefix); if (ifr->ipfr_v == 6) { PRINTF("inet6"); family = AF_INET6; } else { PRINTF("inet"); family = AF_INET; } fr.fr_flags = 0xffffffff; PRINTF(" %s -> ", hostname(family, &ifr->ipfr_src)); /* if (kmemcpy((char *)&fr, (u_long)ifr->ipfr_rule, sizeof(fr)) == -1) return; */ PRINTF("%s id %x ttl %lu pr %d pkts %u bytes %u seen0 %d ref %d\n", hostname(family, &ifr->ipfr_dst), ifr->ipfr_id, ifr->ipfr_ttl, ifr->ipfr_p, ifr->ipfr_pkts, ifr->ipfr_bytes, ifr->ipfr_seen0, ifr->ipfr_ref); } diff --git a/sbin/ipf/libipf/printhash.c b/sbin/ipf/libipf/printhash.c index 37796620fc1d..6961cb170f60 100644 --- a/sbin/ipf/libipf/printhash.c +++ b/sbin/ipf/libipf/printhash.c @@ -1,58 +1,54 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" iphtable_t * -printhash(hp, copyfunc, name, opts, fields) - iphtable_t *hp; - copyfunc_t copyfunc; - char *name; - int opts; - wordtab_t *fields; +printhash( iphtable_t *hp, copyfunc_t copyfunc, char *name, int opts, + wordtab_t *fields) { iphtent_t *ipep, **table; iphtable_t iph; int printed; size_t sz; if ((*copyfunc)((char *)hp, (char *)&iph, sizeof(iph))) return NULL; if ((name != NULL) && strncmp(name, iph.iph_name, FR_GROUPLEN)) return iph.iph_next; if (fields == NULL) printhashdata(hp, opts); if ((hp->iph_flags & IPHASH_DELETE) != 0) PRINTF("# "); if ((opts & OPT_DEBUG) == 0) PRINTF("\t{"); sz = iph.iph_size * sizeof(*table); table = malloc(sz); if ((*copyfunc)((char *)iph.iph_table, (char *)table, sz)) return NULL; for (printed = 0, ipep = iph.iph_list; ipep != NULL; ) { ipep = printhashnode(&iph, ipep, copyfunc, opts, fields); printed++; } if (printed == 0) putchar(';'); free(table); if ((opts & OPT_DEBUG) == 0) PRINTF(" };\n"); return iph.iph_next; } diff --git a/sbin/ipf/libipf/printhash_live.c b/sbin/ipf/libipf/printhash_live.c index 6003a63f60d2..edf85675474a 100644 --- a/sbin/ipf/libipf/printhash_live.c +++ b/sbin/ipf/libipf/printhash_live.c @@ -1,70 +1,65 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include #include "ipf.h" #include "netinet/ipl.h" iphtable_t * -printhash_live(hp, fd, name, opts, fields) - iphtable_t *hp; - int fd; - char *name; - int opts; - wordtab_t *fields; +printhash_live(iphtable_t *hp, int fd, char *name, int opts, wordtab_t *fields) { iphtent_t entry, zero; ipflookupiter_t iter; int last, printed; ipfobj_t obj; if ((name != NULL) && strncmp(name, hp->iph_name, FR_GROUPLEN)) return hp->iph_next; if (fields == NULL) printhashdata(hp, opts); if ((hp->iph_flags & IPHASH_DELETE) != 0) PRINTF("# "); if ((opts & OPT_DEBUG) == 0) PRINTF("\t{"); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_LOOKUPITER; obj.ipfo_ptr = &iter; obj.ipfo_size = sizeof(iter); iter.ili_data = &entry; iter.ili_type = IPLT_HASH; iter.ili_otype = IPFLOOKUPITER_NODE; iter.ili_ival = IPFGENITER_LOOKUP; iter.ili_unit = hp->iph_unit; strncpy(iter.ili_name, hp->iph_name, FR_GROUPLEN); last = 0; printed = 0; bzero((char *)&zero, sizeof(zero)); while (!last && (ioctl(fd, SIOCLOOKUPITER, &obj) == 0)) { if (entry.ipe_next == NULL) last = 1; if (bcmp(&zero, &entry, sizeof(zero)) == 0) break; (void) printhashnode(hp, &entry, bcopywrap, opts, fields); printed++; } if (last == 0) ipferror(fd, "walking hash nodes"); if (printed == 0) putchar(';'); if ((opts & OPT_DEBUG) == 0) PRINTF(" };\n"); return hp->iph_next; } diff --git a/sbin/ipf/libipf/printhashdata.c b/sbin/ipf/libipf/printhashdata.c index ea2d41636e46..690243d63f1e 100644 --- a/sbin/ipf/libipf/printhashdata.c +++ b/sbin/ipf/libipf/printhashdata.c @@ -1,94 +1,92 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" #include void -printhashdata(hp, opts) - iphtable_t *hp; - int opts; +printhashdata(iphtable_t *hp, int opts) { if ((opts & OPT_DEBUG) == 0) { if ((hp->iph_type & IPHASH_ANON) == IPHASH_ANON) PRINTF("# 'anonymous' table refs %d\n", hp->iph_ref); if ((hp->iph_flags & IPHASH_DELETE) == IPHASH_DELETE) PRINTF("# "); switch (hp->iph_type & ~IPHASH_ANON) { case IPHASH_LOOKUP : PRINTF("table"); break; case IPHASH_GROUPMAP : PRINTF("group-map"); if (hp->iph_flags & FR_INQUE) PRINTF(" in"); else if (hp->iph_flags & FR_OUTQUE) PRINTF(" out"); else PRINTF(" ???"); break; default : PRINTF("%#x", hp->iph_type); break; } PRINTF(" role="); } else { PRINTF("Hash Table %s: %s", ISDIGIT(*hp->iph_name) ? "Number" : "Name", hp->iph_name); if ((hp->iph_type & IPHASH_ANON) == IPHASH_ANON) PRINTF("(anon)"); putchar(' '); PRINTF("Role: "); } printunit(hp->iph_unit); if ((opts & OPT_DEBUG) == 0) { if ((hp->iph_type & ~IPHASH_ANON) == IPHASH_LOOKUP) PRINTF(" type=hash"); PRINTF(" %s=%s size=%lu", ISDIGIT(*hp->iph_name) ? "number" : "name", hp->iph_name, (u_long)hp->iph_size); if (hp->iph_seed != 0) PRINTF(" seed=%lu", hp->iph_seed); putchar('\n'); } else { PRINTF(" Type: "); switch (hp->iph_type & ~IPHASH_ANON) { case IPHASH_LOOKUP : PRINTF("lookup"); break; case IPHASH_GROUPMAP : PRINTF("groupmap Group. %s", hp->iph_name); break; default : break; } putchar('\n'); PRINTF("\t\tSize: %lu\tSeed: %lu", (u_long)hp->iph_size, hp->iph_seed); PRINTF("\tRef. Count: %d\tMasks: %#x\n", hp->iph_ref, hp->iph_maskset[0]); } if ((opts & OPT_DEBUG) != 0) { struct in_addr m; int i; for (i = 0; i < 32; i++) { if ((1 << i) & hp->iph_maskset[0]) { ntomask(AF_INET, i, &m.s_addr); PRINTF("\t\tMask: %s\n", inet_ntoa(m)); } } } } diff --git a/sbin/ipf/libipf/printhashnode.c b/sbin/ipf/libipf/printhashnode.c index 8a45d86c5134..18cd7a1d9f84 100644 --- a/sbin/ipf/libipf/printhashnode.c +++ b/sbin/ipf/libipf/printhashnode.c @@ -1,98 +1,94 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" iphtent_t * -printhashnode(iph, ipep, copyfunc, opts, fields) - iphtable_t *iph; - iphtent_t *ipep; - copyfunc_t copyfunc; - int opts; - wordtab_t *fields; +printhashnode(iphtable_t *iph, iphtent_t *ipep, copyfunc_t copyfunc, int opts, + wordtab_t *fields) { iphtent_t ipe; u_int hv; int i; if ((*copyfunc)(ipep, &ipe, sizeof(ipe))) return NULL; hv = IPE_V4_HASH_FN(ipe.ipe_addr.i6[0], ipe.ipe_mask.i6[0], iph->iph_size); if (fields != NULL) { for (i = 0; fields[i].w_value != 0; i++) { printpoolfield(&ipe, IPLT_HASH, i); if (fields[i + 1].w_value != 0) printf("\t"); } printf("\n"); } else if ((opts & OPT_DEBUG) != 0) { #ifdef USE_INET6 if (ipe.ipe_family == AF_INET6) { char buf[INET6_ADDRSTRLEN + 1]; const char *str; buf[0] = '\0'; str = inet_ntop(AF_INET6, &ipe.ipe_addr.in6, buf, sizeof(buf) - 1); if (str == NULL) str = "???"; PRINTF("\t%d\tAddress: %s", hv, str); printmask(ipe.ipe_family, (u_32_t *)&ipe.ipe_mask.in4_addr); PRINTF("\tRef. Count: %d\tGroup: %s\n", ipe.ipe_ref, ipe.ipe_group); #ifdef USE_QUAD_T PRINTF("\tHits: %"PRIu64"\tBytes: %"PRIu64"\n", ipe.ipe_hits, ipe.ipe_bytes); #else PRINTF("\tHits: %lu\tBytes: %lu\n", ipe.ipe_hits, ipe.ipe_bytes); #endif /* USE_QUAD_T */ } else if (ipe.ipe_family == AF_INET) { #else if (ipe.ipe_family == AF_INET) { #endif /* USE_INET6 */ PRINTF("\t%d\tAddress: %s", hv, inet_ntoa(ipe.ipe_addr.in4)); printmask(ipe.ipe_family, (u_32_t *)&ipe.ipe_mask.in4_addr); PRINTF("\tRef. Count: %d\tGroup: %s\n", ipe.ipe_ref, ipe.ipe_group); #ifdef USE_QUAD_T PRINTF("\tHits: %"PRIu64"\tBytes: %"PRIu64"\n", ipe.ipe_hits, ipe.ipe_bytes); #else PRINTF("\tHits: %lu\tBytes: %lu\n", ipe.ipe_hits, ipe.ipe_bytes); #endif /* USE_QUAD_T */ } else { PRINTF("\tAddress: family: %d\n", ipe.ipe_family); } } else { putchar(' '); printip(ipe.ipe_family, (u_32_t *)&ipe.ipe_addr.in4_addr); printmask(ipe.ipe_family, (u_32_t *)&ipe.ipe_mask.in4_addr); if (ipe.ipe_value != 0) { switch (iph->iph_type & ~IPHASH_ANON) { case IPHASH_GROUPMAP : if (strncmp(ipe.ipe_group, iph->iph_name, FR_GROUPLEN)) PRINTF(", group=%s", ipe.ipe_group); break; } } putchar(';'); } ipep = ipe.ipe_next; return ipep; } diff --git a/sbin/ipf/libipf/printhost.c b/sbin/ipf/libipf/printhost.c index 009a9bb1803e..e04882ffe614 100644 --- a/sbin/ipf/libipf/printhost.c +++ b/sbin/ipf/libipf/printhost.c @@ -1,35 +1,33 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: printhost.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" void -printhost(family, addr) - int family; - u_32_t *addr; +printhost(int family, u_32_t *addr) { #ifdef USE_INET6 char ipbuf[64]; #else struct in_addr ipa; #endif if ((family == -1) || !*addr) PRINTF("any"); else { #ifdef USE_INET6 void *ptr = addr; PRINTF("%s", inet_ntop(family, ptr, ipbuf, sizeof(ipbuf))); #else ipa.s_addr = *addr; PRINTF("%s", inet_ntoa(ipa)); #endif } } diff --git a/sbin/ipf/libipf/printhostmap.c b/sbin/ipf/libipf/printhostmap.c index 714bc416932b..bdb15d84995f 100644 --- a/sbin/ipf/libipf/printhostmap.c +++ b/sbin/ipf/libipf/printhostmap.c @@ -1,31 +1,29 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" void -printhostmap(hmp, hv) - hostmap_t *hmp; - u_int hv; +printhostmap(hostmap_t *hmp, u_int hv) { printactiveaddress(hmp->hm_v, "%s", &hmp->hm_osrcip6, NULL); putchar(','); printactiveaddress(hmp->hm_v, "%s", &hmp->hm_odstip6, NULL); PRINTF(" -> "); printactiveaddress(hmp->hm_v, "%s", &hmp->hm_nsrcip6, NULL); putchar(','); printactiveaddress(hmp->hm_v, "%s", &hmp->hm_ndstip6, NULL); putchar(' '); PRINTF("(use = %d", hmp->hm_ref); if (opts & OPT_VERBOSE) PRINTF(" hv = %u", hv); printf(")\n"); } diff --git a/sbin/ipf/libipf/printhostmask.c b/sbin/ipf/libipf/printhostmask.c index b1e41f9c0a87..f5495458fa04 100644 --- a/sbin/ipf/libipf/printhostmask.c +++ b/sbin/ipf/libipf/printhostmask.c @@ -1,39 +1,37 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" void -printhostmask(family, addr, mask) - int family; - u_32_t *addr, *mask; +printhostmask( int family, u_32_t *addr, u_32_t *mask) { #ifdef USE_INET6 char ipbuf[64]; #else struct in_addr ipa; #endif if ((family == -1) || ((!addr || !*addr) && (!mask || !*mask))) PRINTF("any"); else { #ifdef USE_INET6 void *ptr = addr; PRINTF("%s", inet_ntop(family, ptr, ipbuf, sizeof(ipbuf))); #else ipa.s_addr = *addr; PRINTF("%s", inet_ntoa(ipa)); #endif if (mask != NULL) printmask(family, mask); } } diff --git a/sbin/ipf/libipf/printifname.c b/sbin/ipf/libipf/printifname.c index 2e554d950aed..e6a38a8692ad 100644 --- a/sbin/ipf/libipf/printifname.c +++ b/sbin/ipf/libipf/printifname.c @@ -1,22 +1,20 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" void -printifname(format, name, ifp) - char *format, *name; - void *ifp; +printifname(char *format, char *name, void *ifp) { PRINTF("%s%s", format, name); if ((ifp == NULL) && strcmp(name, "-") && strcmp(name, "*")) PRINTF("(!)"); } diff --git a/sbin/ipf/libipf/printip.c b/sbin/ipf/libipf/printip.c index a0b8bd37f277..7cf55f04afec 100644 --- a/sbin/ipf/libipf/printip.c +++ b/sbin/ipf/libipf/printip.c @@ -1,43 +1,41 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" void -printip(family, addr) - int family; - u_32_t *addr; +printip(int family, u_32_t *addr) { struct in_addr ipa; if (family == AF_INET) { ipa.s_addr = *addr; if (ntohl(ipa.s_addr) < 256) PRINTF("%lu", (u_long)ntohl(ipa.s_addr)); else PRINTF("%s", inet_ntoa(ipa)); } #ifdef USE_INET6 else if (family == AF_INET6) { char buf[INET6_ADDRSTRLEN + 1]; const char *str; buf[0] = '\0'; str = inet_ntop(AF_INET6, addr, buf, sizeof(buf) - 1); if (str != NULL) PRINTF("%s", str); else PRINTF("???"); } #endif else PRINTF("?(%d)?", family); } diff --git a/sbin/ipf/libipf/printipfexpr.c b/sbin/ipf/libipf/printipfexpr.c index 6fb74c1e2e26..535bee6f6b3e 100644 --- a/sbin/ipf/libipf/printipfexpr.c +++ b/sbin/ipf/libipf/printipfexpr.c @@ -1,199 +1,194 @@ #include "ipf.h" static void printport(int *); static void printhosts(int *); static void printsingle(int *); #ifdef USE_INET6 static void printhostsv6(int *); #endif void -printipfexpr(array) - int *array; +printipfexpr(int *array) { int i, nelems, j, not; ipfexp_t *ipfe; nelems = array[0]; for (i = 1; i < nelems; ) { ipfe = (ipfexp_t *)(array + i); if (ipfe->ipfe_cmd == IPF_EXP_END) break; not = ipfe->ipfe_not; switch (ipfe->ipfe_cmd) { case IPF_EXP_IP_ADDR : PRINTF("ip.addr %s= ", not ? "!" : ""); printhosts(array + i); break; case IPF_EXP_IP_PR : PRINTF("ip.p %s= ", not ? "!" : ""); printsingle(array + i); break; case IPF_EXP_IP_SRCADDR : PRINTF("ip.src %s= ", not ? "!" : ""); printhosts(array + i); break; case IPF_EXP_IP_DSTADDR : PRINTF("ip.dst %s= ", not ? "!" : ""); printhosts(array + i); break; case IPF_EXP_TCP_PORT : PRINTF("tcp.port %s= ", not ? "!" : ""); printport(array + i); break; case IPF_EXP_TCP_DPORT : PRINTF("tcp.dport %s= ", not ? "!" : ""); printport(array + i); break; case IPF_EXP_TCP_SPORT : PRINTF("tcp.sport %s= ", not ? "!" : ""); printport(array + i); break; case IPF_EXP_TCP_FLAGS : PRINTF("tcp.flags %s= ", not ? "!" : ""); for (j = 0; j < ipfe->ipfe_narg; ) { printtcpflags(array[i + 4], array[i + 5]); j += 2; if (j < array[4]) putchar(','); } break; case IPF_EXP_UDP_PORT : PRINTF("udp.port %s= ", not ? "!" : ""); printport(array + i); break; case IPF_EXP_UDP_DPORT : PRINTF("udp.dport %s= ", not ? "!" : ""); printport(array + i); break; case IPF_EXP_UDP_SPORT : PRINTF("udp.sport %s= ", not ? "!" : ""); printport(array + i); break; case IPF_EXP_IDLE_GT : PRINTF("idle-gt %s= ", not ? "!" : ""); printsingle(array + i); break; case IPF_EXP_TCP_STATE : PRINTF("tcp-state %s= ", not ? "!" : ""); printsingle(array + i); break; #ifdef USE_INET6 case IPF_EXP_IP6_ADDR : PRINTF("ip6.addr %s= ", not ? "!" : ""); printhostsv6(array + i); break; case IPF_EXP_IP6_SRCADDR : PRINTF("ip6.src %s= ", not ? "!" : ""); printhostsv6(array + i); break; case IPF_EXP_IP6_DSTADDR : PRINTF("ip6.dst %s= ", not ? "!" : ""); printhostsv6(array + i); break; #endif case IPF_EXP_END : break; default : PRINTF("#%#x,len=%d;", ipfe->ipfe_cmd, ipfe->ipfe_narg); } if (array[i] != IPF_EXP_END) putchar(';'); i += ipfe->ipfe_size; if (array[i] != IPF_EXP_END) putchar(' '); } } static void -printsingle(array) - int *array; +printsingle(int *array) { ipfexp_t *ipfe = (ipfexp_t *)array; int i; for (i = 0; i < ipfe->ipfe_narg; ) { PRINTF("%d", array[i + 4]); i++; if (i < ipfe->ipfe_narg) putchar(','); } } static void -printport(array) - int *array; +printport(int *array) { ipfexp_t *ipfe = (ipfexp_t *)array; int i; for (i = 0; i < ipfe->ipfe_narg; ) { PRINTF("%d", ntohs(array[i + 4])); i++; if (i < ipfe->ipfe_narg) putchar(','); } } static void -printhosts(array) - int *array; +printhosts(int *array) { ipfexp_t *ipfe = (ipfexp_t *)array; int i, j; for (i = 0, j = 0; i < ipfe->ipfe_narg; j++) { printhostmask(AF_INET, (u_32_t *)ipfe->ipfe_arg0 + j * 2, (u_32_t *)ipfe->ipfe_arg0 + j * 2 + 1); i += 2; if (i < ipfe->ipfe_narg) putchar(','); } } #ifdef USE_INET6 static void -printhostsv6(array) - int *array; +printhostsv6(int *array) { ipfexp_t *ipfe = (ipfexp_t *)array; int i, j; for (i = 4, j= 0; i < ipfe->ipfe_size; j++) { printhostmask(AF_INET6, (u_32_t *)ipfe->ipfe_arg0 + j * 8, (u_32_t *)ipfe->ipfe_arg0 + j * 8 + 4); i += 8; if (i < ipfe->ipfe_size) putchar(','); } } #endif diff --git a/sbin/ipf/libipf/printiphdr.c b/sbin/ipf/libipf/printiphdr.c index fdf0f75f9079..500b4dcb6ad4 100644 --- a/sbin/ipf/libipf/printiphdr.c +++ b/sbin/ipf/libipf/printiphdr.c @@ -1,20 +1,19 @@ /* * Copyright (C) by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: printiphdr.c,v 1.1 2009/03/01 12:48:32 darren_r Exp $ */ #include "ipf.h" void -printiphdr(ip) - ip_t *ip; +printiphdr(ip_t *ip) { PRINTF("ip(v=%d,hl=%d,len=%d,tos=%#x,off=%#x,sum=%#x,src=%#x,dst=%#x", ip->ip_v, ip->ip_hl, ntohs(ip->ip_len), ip->ip_tos, ntohs(ip->ip_off), ntohs(ip->ip_sum), ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr)); } diff --git a/sbin/ipf/libipf/printlog.c b/sbin/ipf/libipf/printlog.c index c5278cdfdd6a..a04842530504 100644 --- a/sbin/ipf/libipf/printlog.c +++ b/sbin/ipf/libipf/printlog.c @@ -1,39 +1,38 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #include void -printlog(fp) - frentry_t *fp; +printlog(frentry_t *fp) { char *s, *u; PRINTF("log"); if (fp->fr_flags & FR_LOGBODY) PRINTF(" body"); if (fp->fr_flags & FR_LOGFIRST) PRINTF(" first"); if (fp->fr_flags & FR_LOGORBLOCK) PRINTF(" or-block"); if (fp->fr_loglevel != 0xffff) { PRINTF(" level "); s = fac_toname(fp->fr_loglevel); if (s == NULL || *s == '\0') s = "!!!"; u = pri_toname(fp->fr_loglevel); if (u == NULL || *u == '\0') u = "!!!"; PRINTF("%s.%s", s, u); } } diff --git a/sbin/ipf/libipf/printlookup.c b/sbin/ipf/libipf/printlookup.c index 51f8d6e3b2df..c18faf61fbbb 100644 --- a/sbin/ipf/libipf/printlookup.c +++ b/sbin/ipf/libipf/printlookup.c @@ -1,42 +1,40 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" void -printlookup(base, addr, mask) - char *base; - i6addr_t *addr, *mask; +printlookup(char *base, i6addr_t *addr, i6addr_t *mask) { char name[32]; switch (addr->iplookuptype) { case IPLT_POOL : PRINTF("pool/"); break; case IPLT_HASH : PRINTF("hash/"); break; case IPLT_DSTLIST : PRINTF("dstlist/"); break; default : PRINTF("lookup(%x)=", addr->iplookuptype); break; } if (addr->iplookupsubtype == 0) PRINTF("%u", addr->iplookupnum); else if (addr->iplookupsubtype == 1) { strncpy(name, base + addr->iplookupname, sizeof(name)); name[sizeof(name) - 1] = '\0'; PRINTF("%s", name); } } diff --git a/sbin/ipf/libipf/printmask.c b/sbin/ipf/libipf/printmask.c index 365d7ffeba14..1130c5190f58 100644 --- a/sbin/ipf/libipf/printmask.c +++ b/sbin/ipf/libipf/printmask.c @@ -1,30 +1,28 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" void -printmask(family, mask) - int family; - u_32_t *mask; +printmask(int family, u_32_t *mask) { struct in_addr ipa; int ones; if (family == AF_INET6) { PRINTF("/%d", count6bits(mask)); } else if ((ones = count4bits(*mask)) == -1) { ipa.s_addr = *mask; PRINTF("/%s", inet_ntoa(ipa)); } else { PRINTF("/%d", ones); } } diff --git a/sbin/ipf/libipf/printnat.c b/sbin/ipf/libipf/printnat.c index a94d4ee6105e..e778d9393d9a 100644 --- a/sbin/ipf/libipf/printnat.c +++ b/sbin/ipf/libipf/printnat.c @@ -1,353 +1,351 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) */ #include "ipf.h" #include "kmem.h" #if !defined(lint) static const char rcsid[] = "@(#)$Id$"; #endif /* * Print out a NAT rule */ void -printnat(np, opts) - ipnat_t *np; - int opts; +printnat(ipnat_t *np, int opts) { struct protoent *pr; char *base; int family; int proto; if (np->in_v[0] == 4) family = AF_INET; #ifdef USE_INET6 else if (np->in_v[0] == 6) family = AF_INET6; #endif else family = AF_UNSPEC; if (np->in_flags & IPN_NO) PRINTF("no "); switch (np->in_redir) { case NAT_REDIRECT|NAT_ENCAP : PRINTF("encap in on"); proto = np->in_pr[0]; break; case NAT_MAP|NAT_ENCAP : PRINTF("encap out on"); proto = np->in_pr[1]; break; case NAT_REDIRECT|NAT_DIVERTUDP : PRINTF("divert in on"); proto = np->in_pr[0]; break; case NAT_MAP|NAT_DIVERTUDP : PRINTF("divert out on"); proto = np->in_pr[1]; break; case NAT_REDIRECT|NAT_REWRITE : PRINTF("rewrite in on"); proto = np->in_pr[0]; break; case NAT_MAP|NAT_REWRITE : PRINTF("rewrite out on"); proto = np->in_pr[1]; break; case NAT_REDIRECT : PRINTF("rdr"); proto = np->in_pr[0]; break; case NAT_MAP : PRINTF("map"); proto = np->in_pr[1]; break; case NAT_MAPBLK : PRINTF("map-block"); proto = np->in_pr[1]; break; case NAT_BIMAP : PRINTF("bimap"); proto = np->in_pr[0]; break; default : FPRINTF(stderr, "unknown value for in_redir: %#x\n", np->in_redir); proto = np->in_pr[0]; break; } pr = getprotobynumber(proto); base = np->in_names; if (!strcmp(base + np->in_ifnames[0], "-")) PRINTF(" \"%s\"", base + np->in_ifnames[0]); else PRINTF(" %s", base + np->in_ifnames[0]); if ((np->in_ifnames[1] != -1) && (strcmp(base + np->in_ifnames[0], base + np->in_ifnames[1]) != 0)) { if (!strcmp(base + np->in_ifnames[1], "-")) PRINTF(",\"%s\"", base + np->in_ifnames[1]); else PRINTF(",%s", base + np->in_ifnames[1]); } putchar(' '); if (family == AF_INET6) PRINTF("inet6 "); if (np->in_redir & (NAT_REWRITE|NAT_ENCAP|NAT_DIVERTUDP)) { if ((proto != 0) || (np->in_flags & IPN_TCPUDP)) { PRINTF("proto "); printproto(pr, proto, np); putchar(' '); } } if (np->in_flags & IPN_FILTER) { if (np->in_flags & IPN_NOTSRC) PRINTF("! "); PRINTF("from "); printnataddr(np->in_v[0], np->in_names, &np->in_osrc, np->in_ifnames[0]); if (np->in_scmp) printportcmp(proto, &np->in_tuc.ftu_src); if (np->in_flags & IPN_NOTDST) PRINTF(" !"); PRINTF(" to "); printnataddr(np->in_v[0], np->in_names, &np->in_odst, np->in_ifnames[0]); if (np->in_dcmp) printportcmp(proto, &np->in_tuc.ftu_dst); } if (np->in_redir & (NAT_ENCAP|NAT_DIVERTUDP)) { PRINTF(" -> src "); printnataddr(np->in_v[1], np->in_names, &np->in_nsrc, np->in_ifnames[0]); if ((np->in_redir & NAT_DIVERTUDP) != 0) PRINTF(",%u", np->in_spmin); PRINTF(" dst "); printnataddr(np->in_v[1], np->in_names, &np->in_ndst, np->in_ifnames[0]); if ((np->in_redir & NAT_DIVERTUDP) != 0) PRINTF(",%u udp", np->in_dpmin); if ((np->in_flags & IPN_PURGE) != 0) PRINTF(" purge"); PRINTF(";\n"); } else if (np->in_redir & NAT_REWRITE) { PRINTF(" -> src "); if (np->in_nsrc.na_atype == FRI_LOOKUP && np->in_nsrc.na_type == IPLT_DSTLIST) { PRINTF("dstlist/"); if (np->in_nsrc.na_subtype == 0) PRINTF("%d", np->in_nsrc.na_num); else PRINTF("%s", base + np->in_nsrc.na_num); } else { printnataddr(np->in_v[1], np->in_names, &np->in_nsrc, np->in_ifnames[0]); } if ((((np->in_flags & IPN_TCPUDP) != 0)) && (np->in_spmin != 0)) { if ((np->in_flags & IPN_FIXEDSPORT) != 0) { PRINTF(",port = %u", np->in_spmin); } else { PRINTF(",%u", np->in_spmin); if (np->in_spmax != np->in_spmin) PRINTF("-%u", np->in_spmax); } } PRINTF(" dst "); if (np->in_ndst.na_atype == FRI_LOOKUP && np->in_ndst.na_type == IPLT_DSTLIST) { PRINTF("dstlist/"); if (np->in_ndst.na_subtype == 0) PRINTF("%d", np->in_nsrc.na_num); else PRINTF("%s", base + np->in_ndst.na_num); } else { printnataddr(np->in_v[1], np->in_names, &np->in_ndst, np->in_ifnames[0]); } if ((((np->in_flags & IPN_TCPUDP) != 0)) && (np->in_dpmin != 0)) { if ((np->in_flags & IPN_FIXEDDPORT) != 0) { PRINTF(",port = %u", np->in_dpmin); } else { PRINTF(",%u", np->in_dpmin); if (np->in_dpmax != np->in_dpmin) PRINTF("-%u", np->in_dpmax); } } if ((np->in_flags & IPN_PURGE) != 0) PRINTF(" purge"); PRINTF(";\n"); } else if (np->in_redir == NAT_REDIRECT) { if (!(np->in_flags & IPN_FILTER)) { printnataddr(np->in_v[0], np->in_names, &np->in_odst, np->in_ifnames[0]); if (np->in_flags & IPN_TCPUDP) { PRINTF(" port %d", np->in_odport); if (np->in_odport != np->in_dtop) PRINTF("-%d", np->in_dtop); } } if (np->in_flags & IPN_NO) { putchar(' '); printproto(pr, proto, np); PRINTF(";\n"); return; } PRINTF(" -> "); printnataddr(np->in_v[1], np->in_names, &np->in_ndst, np->in_ifnames[0]); if (np->in_flags & IPN_TCPUDP) { if ((np->in_flags & IPN_FIXEDDPORT) != 0) PRINTF(" port = %d", np->in_dpmin); else { PRINTF(" port %d", np->in_dpmin); if (np->in_dpmin != np->in_dpmax) PRINTF("-%d", np->in_dpmax); } } putchar(' '); printproto(pr, proto, np); if (np->in_flags & IPN_ROUNDR) PRINTF(" round-robin"); if (np->in_flags & IPN_FRAG) PRINTF(" frag"); if (np->in_age[0] != 0 || np->in_age[1] != 0) { PRINTF(" age %d/%d", np->in_age[0], np->in_age[1]); } if (np->in_flags & IPN_STICKY) PRINTF(" sticky"); if (np->in_mssclamp != 0) PRINTF(" mssclamp %d", np->in_mssclamp); if (np->in_plabel != -1) PRINTF(" proxy %s", np->in_names + np->in_plabel); if (np->in_tag.ipt_tag[0] != '\0') PRINTF(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag); if ((np->in_flags & IPN_PURGE) != 0) PRINTF(" purge"); PRINTF("\n"); if (opts & OPT_DEBUG) PRINTF("\tpmax %u\n", np->in_dpmax); } else { int protoprinted = 0; if (!(np->in_flags & IPN_FILTER)) { printnataddr(np->in_v[0], np->in_names, &np->in_osrc, np->in_ifnames[0]); } if (np->in_flags & IPN_NO) { putchar(' '); printproto(pr, proto, np); PRINTF(";\n"); return; } PRINTF(" -> "); if (np->in_flags & IPN_SIPRANGE) { PRINTF("range "); printnataddr(np->in_v[1], np->in_names, &np->in_nsrc, np->in_ifnames[0]); } else { printnataddr(np->in_v[1], np->in_names, &np->in_nsrc, np->in_ifnames[0]); } if (np->in_plabel != -1) { PRINTF(" proxy port "); if (np->in_odport != 0) { char *s; s = portname(proto, np->in_odport); if (s != NULL) fputs(s, stdout); else fputs("???", stdout); } PRINTF(" %s/", np->in_names + np->in_plabel); printproto(pr, proto, NULL); protoprinted = 1; } else if (np->in_redir == NAT_MAPBLK) { if ((np->in_spmin == 0) && (np->in_flags & IPN_AUTOPORTMAP)) PRINTF(" ports auto"); else PRINTF(" ports %d", np->in_spmin); if (opts & OPT_DEBUG) PRINTF("\n\tip modulous %d", np->in_spmax); } else if (np->in_spmin || np->in_spmax) { if (np->in_flags & IPN_ICMPQUERY) { PRINTF(" icmpidmap "); } else { PRINTF(" portmap "); } printproto(pr, proto, np); protoprinted = 1; if (np->in_flags & IPN_AUTOPORTMAP) { PRINTF(" auto"); if (opts & OPT_DEBUG) PRINTF(" [%d:%d %d %d]", np->in_spmin, np->in_spmax, np->in_ippip, np->in_ppip); } else { PRINTF(" %d:%d", np->in_spmin, np->in_spmax); } if (np->in_flags & IPN_SEQUENTIAL) PRINTF(" sequential"); } if (np->in_flags & IPN_FRAG) PRINTF(" frag"); if (np->in_age[0] != 0 || np->in_age[1] != 0) { PRINTF(" age %d/%d", np->in_age[0], np->in_age[1]); } if (np->in_mssclamp != 0) PRINTF(" mssclamp %d", np->in_mssclamp); if (np->in_tag.ipt_tag[0] != '\0') PRINTF(" tag %s", np->in_tag.ipt_tag); if (!protoprinted && (np->in_flags & IPN_TCPUDP || proto)) { putchar(' '); printproto(pr, proto, np); } if ((np->in_flags & IPN_PURGE) != 0) PRINTF(" purge"); PRINTF("\n"); if (opts & OPT_DEBUG) { PRINTF("\tnextip "); printip(family, &np->in_snip); PRINTF(" pnext %d\n", np->in_spnext); } } if (opts & OPT_DEBUG) { PRINTF("\tspace %lu use %u hits %lu flags %#x proto %d/%d", np->in_space, np->in_use, np->in_hits, np->in_flags, np->in_pr[0], np->in_pr[1]); PRINTF(" hv %u/%u\n", np->in_hv[0], np->in_hv[1]); PRINTF("\tifp[0] %p ifp[1] %p apr %p\n", np->in_ifps[0], np->in_ifps[1], np->in_apr); PRINTF("\ttqehead %p/%p comment %p\n", np->in_tqehead[0], np->in_tqehead[1], np->in_comment); } } diff --git a/sbin/ipf/libipf/printnataddr.c b/sbin/ipf/libipf/printnataddr.c index 89faa624193c..ee00b5b14d6c 100644 --- a/sbin/ipf/libipf/printnataddr.c +++ b/sbin/ipf/libipf/printnataddr.c @@ -1,48 +1,44 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) */ #include "ipf.h" #include "kmem.h" #if !defined(lint) static const char rcsid[] = "@(#)$Id: printnataddr.c,v 1.4.2.2 2012/07/22 08:04:24 darren_r Exp $"; #endif void -printnataddr(v, base, addr, ifidx) - int v; - char *base; - nat_addr_t *addr; - int ifidx; +printnataddr( int v, char *base, nat_addr_t *addr, int ifidx) { switch (v) { case 4 : if (addr->na_atype == FRI_NORMAL && addr->na_addr[0].in4.s_addr == 0) { PRINTF("0/%d", count4bits(addr->na_addr[1].in4.s_addr)); } else { printaddr(AF_INET, addr->na_atype, base, ifidx, (u_32_t *)&addr->na_addr[0].in4.s_addr, (u_32_t *)&addr->na_addr[1].in4.s_addr); } break; #ifdef USE_INET6 case 6 : printaddr(AF_INET6, addr->na_atype, base, ifidx, (u_32_t *)&addr->na_addr[0].in6, (u_32_t *)&addr->na_addr[1].in6); break; #endif default : printf("{v=%d}", v); break; } } diff --git a/sbin/ipf/libipf/printnatfield.c b/sbin/ipf/libipf/printnatfield.c index 49596f607170..7a4986ac8e72 100644 --- a/sbin/ipf/libipf/printnatfield.c +++ b/sbin/ipf/libipf/printnatfield.c @@ -1,220 +1,218 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: printnatfield.c,v 1.6.2.2 2012/01/26 05:44:26 darren_r Exp $ */ #include "ipf.h" wordtab_t natfields[] = { { "all", -2 }, { "ifp0", 1 }, { "ifp1", 2 }, { "mtu0", 3 }, { "mtu1", 4 }, { "ifname0", 5 }, { "ifname1", 6 }, { "sumd0", 7 }, { "sumd1", 8 }, { "pkts0", 9 }, { "pkts1", 10 }, { "bytes0", 11 }, { "bytes1", 12 }, { "proto0", 13 }, { "proto1", 14 }, { "hash0", 15 }, { "hash1", 16 }, { "ref", 17 }, { "rev", 18 }, { "v0", 19 }, { "redir", 20 }, { "use", 21 }, { "ipsumd", 22 }, { "dir", 23 }, { "olddstip", 24 }, { "oldsrcip", 25 }, { "newdstip", 26 }, { "newsrcip", 27 }, { "olddport", 28 }, { "oldsport", 29 }, { "newdport", 30 }, { "newsport", 31 }, { "age", 32 }, { "v1", 33 }, { NULL, 0 } }; void -printnatfield(n, fieldnum) - nat_t *n; - int fieldnum; +printnatfield( nat_t *n, int fieldnum) { int i; switch (fieldnum) { case -2 : for (i = 1; natfields[i].w_word != NULL; i++) { if (natfields[i].w_value > 0) { printnatfield(n, i); if (natfields[i + 1].w_value > 0) putchar('\t'); } } break; case 1: PRINTF("%#lx", (u_long)n->nat_ifps[0]); break; case 2: PRINTF("%#lx", (u_long)n->nat_ifps[1]); break; case 3: PRINTF("%d", n->nat_mtu[0]); break; case 4: PRINTF("%d", n->nat_mtu[1]); break; case 5: PRINTF("%s", n->nat_ifnames[0]); break; case 6: PRINTF("%s", n->nat_ifnames[1]); break; case 7: PRINTF("%d", n->nat_sumd[0]); break; case 8: PRINTF("%d", n->nat_sumd[1]); break; case 9: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", n->nat_pkts[0]); #else PRINTF("%lu", n->nat_pkts[0]); #endif break; case 10: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", n->nat_pkts[1]); #else PRINTF("%lu", n->nat_pkts[1]); #endif break; case 11: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", n->nat_bytes[0]); #else PRINTF("%lu", n->nat_bytes[0]); #endif break; case 12: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", n->nat_bytes[1]); #else PRINTF("%lu", n->nat_bytes[1]); #endif break; case 13: PRINTF("%d", n->nat_pr[0]); break; case 14: PRINTF("%d", n->nat_pr[1]); break; case 15: PRINTF("%u", n->nat_hv[0]); break; case 16: PRINTF("%u", n->nat_hv[1]); break; case 17: PRINTF("%d", n->nat_ref); break; case 18: PRINTF("%d", n->nat_rev); break; case 19: PRINTF("%d", n->nat_v[0]); break; case 33: PRINTF("%d", n->nat_v[0]); break; case 20: PRINTF("%d", n->nat_redir); break; case 21: PRINTF("%d", n->nat_use); break; case 22: PRINTF("%u", n->nat_ipsumd); break; case 23: PRINTF("%d", n->nat_dir); break; case 24: PRINTF("%s", hostname(n->nat_v[0], &n->nat_odstip)); break; case 25: PRINTF("%s", hostname(n->nat_v[0], &n->nat_osrcip)); break; case 26: PRINTF("%s", hostname(n->nat_v[1], &n->nat_ndstip)); break; case 27: PRINTF("%s", hostname(n->nat_v[1], &n->nat_nsrcip)); break; case 28: PRINTF("%hu", ntohs(n->nat_odport)); break; case 29: PRINTF("%hu", ntohs(n->nat_osport)); break; case 30: PRINTF("%hu", ntohs(n->nat_ndport)); break; case 31: PRINTF("%hu", ntohs(n->nat_nsport)); break; case 32: PRINTF("%u", n->nat_age); break; default: break; } } diff --git a/sbin/ipf/libipf/printnatside.c b/sbin/ipf/libipf/printnatside.c index 37e1cb8d1e3a..9329623d03e5 100644 --- a/sbin/ipf/libipf/printnatside.c +++ b/sbin/ipf/libipf/printnatside.c @@ -1,55 +1,53 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: printnatside.c,v 1.2.2.6 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" void -printnatside(side, ns) - char *side; - nat_stat_side_t *ns; +printnatside(char *side, nat_stat_side_t *ns) { PRINTF("%lu\tproxy create fail %s\n", ns->ns_appr_fail, side); PRINTF("%lu\tproxy fail %s\n", ns->ns_ipf_proxy_fail, side); PRINTF("%lu\tbad nat %s\n", ns->ns_badnat, side); PRINTF("%lu\tbad nat new %s\n", ns->ns_badnatnew, side); PRINTF("%lu\tbad next addr %s\n", ns->ns_badnextaddr, side); PRINTF("%lu\tbucket max %s\n", ns->ns_bucket_max, side); PRINTF("%lu\tclone nomem %s\n", ns->ns_clone_nomem, side); PRINTF("%lu\tdecap bad %s\n", ns->ns_decap_bad, side); PRINTF("%lu\tdecap fail %s\n", ns->ns_decap_fail, side); PRINTF("%lu\tdecap pullup %s\n", ns->ns_decap_pullup, side); PRINTF("%lu\tdivert dup %s\n", ns->ns_divert_dup, side); PRINTF("%lu\tdivert exist %s\n", ns->ns_divert_exist, side); PRINTF("%lu\tdrop %s\n", ns->ns_drop, side); PRINTF("%lu\texhausted %s\n", ns->ns_exhausted, side); PRINTF("%lu\ticmp address %s\n", ns->ns_icmp_address, side); PRINTF("%lu\ticmp basic %s\n", ns->ns_icmp_basic, side); PRINTF("%lu\tinuse %s\n", ns->ns_inuse, side); PRINTF("%lu\ticmp mbuf wrong size %s\n", ns->ns_icmp_mbuf, side); PRINTF("%lu\ticmp header unmatched %s\n", ns->ns_icmp_notfound, side); PRINTF("%lu\ticmp rebuild failures %s\n", ns->ns_icmp_rebuild, side); PRINTF("%lu\ticmp short %s\n", ns->ns_icmp_short, side); PRINTF("%lu\ticmp packet size wrong %s\n", ns->ns_icmp_size, side); PRINTF("%lu\tIFP address fetch failures %s\n", ns->ns_ifpaddrfail, side); PRINTF("%lu\tpackets untranslated %s\n", ns->ns_ignored, side); PRINTF("%lu\tNAT insert failures %s\n", ns->ns_insert_fail, side); PRINTF("%lu\tNAT lookup misses %s\n", ns->ns_lookup_miss, side); PRINTF("%lu\tNAT lookup nowild %s\n", ns->ns_lookup_nowild, side); PRINTF("%lu\tnew ifpaddr failed %s\n", ns->ns_new_ifpaddr, side); PRINTF("%lu\tmemory requests failed %s\n", ns->ns_memfail, side); PRINTF("%lu\ttable max reached %s\n", ns->ns_table_max, side); PRINTF("%lu\tpackets translated %s\n", ns->ns_translated, side); PRINTF("%lu\tfinalised failed %s\n", ns->ns_unfinalised, side); PRINTF("%lu\tsearch wraps %s\n", ns->ns_wrap, side); PRINTF("%lu\tnull translations %s\n", ns->ns_xlate_null, side); PRINTF("%lu\ttranslation exists %s\n", ns->ns_xlate_exists, side); PRINTF("%lu\tno memory %s\n", ns->ns_memfail, side); if (opts & OPT_VERBOSE) PRINTF("%p table %s\n", ns->ns_table, side); } diff --git a/sbin/ipf/libipf/printpacket.c b/sbin/ipf/libipf/printpacket.c index 5c4a74975cb6..9444f93fe840 100644 --- a/sbin/ipf/libipf/printpacket.c +++ b/sbin/ipf/libipf/printpacket.c @@ -1,110 +1,108 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #ifndef IP_OFFMASK # define IP_OFFMASK 0x3fff #endif void -printpacket(dir, m) - int dir; - mb_t *m; +printpacket(int dir, mb_t *m) { u_short len, off; tcphdr_t *tcp; ip_t *ip; ip = MTOD(m, ip_t *); if (IP_V(ip) == 6) { #ifdef USE_INET6 len = ntohs(((ip6_t *)ip)->ip6_plen); #else len = ntohs(((u_short *)ip)[2]); #endif len += 40; } else { len = ntohs(ip->ip_len); } ASSERT(len == msgdsize(m)); if ((opts & OPT_HEX) == OPT_HEX) { u_char *s; int i; for (; m != NULL; m = m->mb_next) { len = m->mb_len; for (s = (u_char *)m->mb_data, i = 0; i < len; i++) { PRINTF("%02x", *s++ & 0xff); if (len - i > 1) { i++; PRINTF("%02x", *s++ & 0xff); } putchar(' '); } } putchar('\n'); putchar('\n'); return; } if (IP_V(ip) == 6) { printpacket6(dir, m); return; } if (dir) PRINTF("> "); else PRINTF("< "); PRINTF("%s ", IFNAME(m->mb_ifp)); off = ntohs(ip->ip_off); tcp = (struct tcphdr *)((char *)ip + (IP_HL(ip) << 2)); PRINTF("ip #%d %d(%d) %d", ntohs(ip->ip_id), ntohs(ip->ip_len), IP_HL(ip) << 2, ip->ip_p); if (off & IP_OFFMASK) PRINTF(" @%d", off << 3); PRINTF(" %s", inet_ntoa(ip->ip_src)); if (!(off & IP_OFFMASK)) if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) PRINTF(",%d", ntohs(tcp->th_sport)); PRINTF(" > "); PRINTF("%s", inet_ntoa(ip->ip_dst)); if (!(off & IP_OFFMASK)) { if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) PRINTF(",%d", ntohs(tcp->th_dport)); if ((ip->ip_p == IPPROTO_TCP) && (tcp->th_flags != 0)) { putchar(' '); if (tcp->th_flags & TH_FIN) putchar('F'); if (tcp->th_flags & TH_SYN) putchar('S'); if (tcp->th_flags & TH_RST) putchar('R'); if (tcp->th_flags & TH_PUSH) putchar('P'); if (tcp->th_flags & TH_ACK) putchar('A'); if (tcp->th_flags & TH_URG) putchar('U'); if (tcp->th_flags & TH_ECN) putchar('E'); if (tcp->th_flags & TH_CWR) putchar('C'); } } putchar('\n'); } diff --git a/sbin/ipf/libipf/printpacket6.c b/sbin/ipf/libipf/printpacket6.c index 6363e55fc76d..42d1a36b96b3 100644 --- a/sbin/ipf/libipf/printpacket6.c +++ b/sbin/ipf/libipf/printpacket6.c @@ -1,60 +1,58 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" /* * This is meant to work without the IPv6 header files being present or * the inet_ntop() library. */ void -printpacket6(dir, m) - int dir; - mb_t *m; +printpacket6(int dir, mb_t *m) { u_char *buf, p; u_short plen, *addrs; tcphdr_t *tcp; u_32_t flow; buf = (u_char *)m->mb_data; tcp = (tcphdr_t *)(buf + 40); p = buf[6]; flow = ntohl(*(u_32_t *)buf); flow &= 0xfffff; plen = ntohs(*((u_short *)buf +2)); addrs = (u_short *)buf + 4; if (dir) PRINTF("> "); else PRINTF("< "); PRINTF("%s ", IFNAME(m->mb_ifp)); PRINTF("ip6/%d %d %#x %d", buf[0] & 0xf, plen, flow, p); PRINTF(" %x:%x:%x:%x:%x:%x:%x:%x", ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]), ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]), ntohs(addrs[6]), ntohs(addrs[7])); if (plen >= 4) if (p == IPPROTO_TCP || p == IPPROTO_UDP) (void)PRINTF(",%d", ntohs(tcp->th_sport)); PRINTF(" >"); addrs += 8; PRINTF(" %x:%x:%x:%x:%x:%x:%x:%x", ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]), ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]), ntohs(addrs[6]), ntohs(addrs[7])); if (plen >= 4) if (p == IPPROTO_TCP || p == IPPROTO_UDP) PRINTF(",%d", ntohs(tcp->th_dport)); putchar('\n'); } diff --git a/sbin/ipf/libipf/printpool.c b/sbin/ipf/libipf/printpool.c index 8d8cdccea59f..ccbfd84d3b67 100644 --- a/sbin/ipf/libipf/printpool.c +++ b/sbin/ipf/libipf/printpool.c @@ -1,65 +1,61 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" ip_pool_t * -printpool(pp, copyfunc, name, opts, fields) - ip_pool_t *pp; - copyfunc_t copyfunc; - char *name; - int opts; - wordtab_t *fields; +printpool(ip_pool_t *pp, copyfunc_t copyfunc, char *name, int opts, + wordtab_t *fields) { ip_pool_node_t *ipnp, *ipnpn, ipn, **pnext; ip_pool_t ipp; if ((*copyfunc)(pp, &ipp, sizeof(ipp))) return NULL; if ((name != NULL) && strncmp(name, ipp.ipo_name, FR_GROUPLEN)) return ipp.ipo_next; printpooldata(&ipp, opts); if ((ipp.ipo_flags & IPOOL_DELETE) != 0) PRINTF("# "); if ((opts & OPT_DEBUG) == 0) PRINTF("\t{"); ipnpn = ipp.ipo_list; ipp.ipo_list = NULL; pnext = &ipp.ipo_list; while (ipnpn != NULL) { ipnp = (ip_pool_node_t *)malloc(sizeof(*ipnp)); (*copyfunc)(ipnpn, ipnp, sizeof(ipn)); ipnpn = ipnp->ipn_next; *pnext = ipnp; pnext = &ipnp->ipn_next; ipnp->ipn_next = NULL; } if (ipp.ipo_list == NULL) { putchar(';'); } else { for (ipnp = ipp.ipo_list; ipnp != NULL; ipnp = ipnpn) { ipnpn = printpoolnode(ipnp, opts, fields); free(ipnp); if ((opts & OPT_DEBUG) == 0) { putchar(';'); } } } if ((opts & OPT_DEBUG) == 0) PRINTF(" };\n"); return ipp.ipo_next; } diff --git a/sbin/ipf/libipf/printpool_live.c b/sbin/ipf/libipf/printpool_live.c index 2aabf32bc14a..15f563277309 100644 --- a/sbin/ipf/libipf/printpool_live.c +++ b/sbin/ipf/libipf/printpool_live.c @@ -1,71 +1,67 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include #include "ipf.h" #include "netinet/ipl.h" ip_pool_t * -printpool_live(pool, fd, name, opts, fields) - ip_pool_t *pool; - int fd; - char *name; - int opts; - wordtab_t *fields; +printpool_live(ip_pool_t *pool, int fd, char *name, int opts, + wordtab_t *fields) { ip_pool_node_t entry; ipflookupiter_t iter; int printed, last; ipfobj_t obj; if ((name != NULL) && strncmp(name, pool->ipo_name, FR_GROUPLEN)) return pool->ipo_next; if (fields == NULL) printpooldata(pool, opts); if ((pool->ipo_flags & IPOOL_DELETE) != 0) PRINTF("# "); if ((opts & OPT_DEBUG) == 0) PRINTF("\t{"); obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_LOOKUPITER; obj.ipfo_ptr = &iter; obj.ipfo_size = sizeof(iter); iter.ili_data = &entry; iter.ili_type = IPLT_POOL; iter.ili_otype = IPFLOOKUPITER_NODE; iter.ili_ival = IPFGENITER_LOOKUP; iter.ili_unit = pool->ipo_unit; strncpy(iter.ili_name, pool->ipo_name, FR_GROUPLEN); last = 0; printed = 0; if (pool->ipo_list != NULL) { while (!last && (ioctl(fd, SIOCLOOKUPITER, &obj) == 0)) { if (entry.ipn_next == NULL) last = 1; (void) printpoolnode(&entry, opts, fields); if ((opts & OPT_DEBUG) == 0) putchar(';'); printed++; } } if (printed == 0) putchar(';'); if ((opts & OPT_DEBUG) == 0) PRINTF(" };\n"); (void) ioctl(fd,SIOCIPFDELTOK, &iter.ili_key); return pool->ipo_next; } diff --git a/sbin/ipf/libipf/printpooldata.c b/sbin/ipf/libipf/printpooldata.c index a1591774b4df..ce754f9a89bb 100644 --- a/sbin/ipf/libipf/printpooldata.c +++ b/sbin/ipf/libipf/printpooldata.c @@ -1,50 +1,48 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" #include void -printpooldata(pool, opts) - ip_pool_t *pool; - int opts; +printpooldata(ip_pool_t *pool, int opts) { if ((opts & OPT_DEBUG) == 0) { if ((pool->ipo_flags & IPOOL_ANON) != 0) PRINTF("# 'anonymous' tree %s\n", pool->ipo_name); if ((pool->ipo_flags & IPOOL_DELETE) != 0) PRINTF("# "); PRINTF("table role="); } else { if ((pool->ipo_flags & IPOOL_DELETE) != 0) PRINTF("# "); PRINTF("%s: %s", ISDIGIT(*pool->ipo_name) ? "Number" : "Name", pool->ipo_name); if ((pool->ipo_flags & IPOOL_ANON) == IPOOL_ANON) PRINTF("(anon)"); putchar(' '); PRINTF("Role: "); } printunit(pool->ipo_unit); if ((opts & OPT_DEBUG) == 0) { PRINTF(" type=tree %s=%s\n", (!*pool->ipo_name || ISDIGIT(*pool->ipo_name)) ? \ "number" : "name", pool->ipo_name); } else { putchar(' '); PRINTF("\tReferences: %d\tHits: %lu\n", pool->ipo_ref, pool->ipo_hits); if ((pool->ipo_flags & IPOOL_DELETE) != 0) PRINTF("# "); PRINTF("\tNodes Starting at %p\n", pool->ipo_list); } } diff --git a/sbin/ipf/libipf/printpoolfield.c b/sbin/ipf/libipf/printpoolfield.c index 9254ab844615..2a461239ad91 100644 --- a/sbin/ipf/libipf/printpoolfield.c +++ b/sbin/ipf/libipf/printpoolfield.c @@ -1,168 +1,165 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: printpoolfield.c,v 1.1.2.4 2012/01/26 05:44:26 darren_r Exp $ */ #include "ipf.h" wordtab_t poolfields[] = { { "all", -2 }, { "address", 1 }, { "mask", 2 }, { "ifname", 3 }, { "pkts", 4 }, { "bytes", 5 }, { "family", 6 }, { NULL, 0 } }; void -printpoolfield(p, ptype, fieldnum) - void *p; - int ptype; - int fieldnum; +printpoolfield(void *p, int ptype, int fieldnum) { addrfamily_t *a; char abuf[80]; int i; switch (fieldnum) { case -2 : for (i = 1; poolfields[i].w_word != NULL; i++) { if (poolfields[i].w_value > 0) { printpoolfield(p, ptype, i); if (poolfields[i + 1].w_value > 0) putchar('\t'); } } break; case 1: if (ptype == IPLT_POOL) { ip_pool_node_t *node = (ip_pool_node_t *)p; if (node->ipn_info) PRINTF("!"); a = &node->ipn_addr; PRINTF("%s", inet_ntop(a->adf_family, &a->adf_addr, abuf, sizeof(abuf))); } else if (ptype == IPLT_HASH) { iphtent_t *node = (iphtent_t *)p; PRINTF("%s", inet_ntop(node->ipe_family, &node->ipe_addr, abuf, sizeof(abuf))); } else if (ptype == IPLT_DSTLIST) { ipf_dstnode_t *node = (ipf_dstnode_t *)p; a = &node->ipfd_dest.fd_addr; PRINTF("%s", inet_ntop(a->adf_family, &a->adf_addr, abuf, sizeof(abuf))); } break; case 2: if (ptype == IPLT_POOL) { ip_pool_node_t *node = (ip_pool_node_t *)p; a = &node->ipn_mask; PRINTF("%s", inet_ntop(a->adf_family, &a->adf_addr, abuf, sizeof(abuf))); } else if (ptype == IPLT_HASH) { iphtent_t *node = (iphtent_t *)p; PRINTF("%s", inet_ntop(node->ipe_family, &node->ipe_mask, abuf, sizeof(abuf))); } else if (ptype == IPLT_DSTLIST) { PRINTF("%s", ""); } break; case 3: if (ptype == IPLT_POOL) { PRINTF("%s", ""); } else if (ptype == IPLT_HASH) { PRINTF("%s", ""); } else if (ptype == IPLT_DSTLIST) { ipf_dstnode_t *node = (ipf_dstnode_t *)p; if (node->ipfd_dest.fd_name == -1) { PRINTF("%s", ""); } else { PRINTF("%s", node->ipfd_names + node->ipfd_dest.fd_name); } } break; case 4: if (ptype == IPLT_POOL) { ip_pool_node_t *node = (ip_pool_node_t *)p; #ifdef USE_QUAD_T PRINTF("%"PRIu64"", node->ipn_hits); #else PRINTF("%lu", node->ipn_hits); #endif } else if (ptype == IPLT_HASH) { iphtent_t *node = (iphtent_t *)p; #ifdef USE_QUAD_T PRINTF("%"PRIu64"", node->ipe_hits); #else PRINTF("%lu", node->ipe_hits); #endif } else if (ptype == IPLT_DSTLIST) { printf("0"); } break; case 5: if (ptype == IPLT_POOL) { ip_pool_node_t *node = (ip_pool_node_t *)p; #ifdef USE_QUAD_T PRINTF("%"PRIu64"", node->ipn_bytes); #else PRINTF("%lu", node->ipn_bytes); #endif } else if (ptype == IPLT_HASH) { iphtent_t *node = (iphtent_t *)p; #ifdef USE_QUAD_T PRINTF("%"PRIu64"", node->ipe_bytes); #else PRINTF("%lu", node->ipe_bytes); #endif } else if (ptype == IPLT_DSTLIST) { printf("0"); } break; case 6: if (ptype == IPLT_POOL) { ip_pool_node_t *node = (ip_pool_node_t *)p; PRINTF("%s", familyname(node->ipn_addr.adf_family)); } else if (ptype == IPLT_HASH) { iphtent_t *node = (iphtent_t *)p; PRINTF("%s", familyname(node->ipe_family)); } else if (ptype == IPLT_DSTLIST) { ipf_dstnode_t *node = (ipf_dstnode_t *)p; a = &node->ipfd_dest.fd_addr; PRINTF("%s", familyname(a->adf_family)); } break; default : break; } } diff --git a/sbin/ipf/libipf/printpoolnode.c b/sbin/ipf/libipf/printpoolnode.c index 6b58b8459327..4198603c7548 100644 --- a/sbin/ipf/libipf/printpoolnode.c +++ b/sbin/ipf/libipf/printpoolnode.c @@ -1,71 +1,68 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" ip_pool_node_t * -printpoolnode(np, opts, fields) - ip_pool_node_t *np; - int opts; - wordtab_t *fields; +printpoolnode(ip_pool_node_t *np, int opts, wordtab_t *fields) { int i; if (fields != NULL) { for (i = 0; fields[i].w_value != 0; i++) { printpoolfield(np, IPLT_POOL, i); if (fields[i + 1].w_value != 0) printf("\t"); } printf("\n"); } else if ((opts & OPT_DEBUG) == 0) { putchar(' '); if (np->ipn_info == 1) PRINTF("! "); printip(np->ipn_addr.adf_family, (u_32_t *)&np->ipn_addr.adf_addr.in4); printmask(np->ipn_addr.adf_family, (u_32_t *)&np->ipn_mask.adf_addr); } else { #ifdef USE_INET6 if (np->ipn_addr.adf_family == AF_INET6) { char buf[INET6_ADDRSTRLEN + 1]; const char *str; buf[0] = '\0'; str = inet_ntop(AF_INET6, &np->ipn_addr.adf_addr.in6, buf, sizeof(buf) - 1); if (str == NULL) str = "???"; PRINTF("\tAddress: %s%s", np->ipn_info ? "! " : "", str); } else if (np->ipn_addr.adf_family == AF_INET) { #else if (np->ipn_addr.adf_family == AF_INET) { #endif PRINTF("\tAddress: %s%s", np->ipn_info ? "! " : "", inet_ntoa(np->ipn_addr.adf_addr.in4)); } else { PRINTF("\tAddress: family: %d\n", np->ipn_addr.adf_family); } printmask(np->ipn_addr.adf_family, (u_32_t *)&np->ipn_mask.adf_addr); #ifdef USE_QUAD_T PRINTF("\n\t\tHits %"PRIu64"\tBytes %"PRIu64"\tName %s\tRef %d\n", np->ipn_hits, np->ipn_bytes, np->ipn_name, np->ipn_ref); #else PRINTF("\n\t\tHits %lu\tBytes %lu\tName %s\tRef %d\n", np->ipn_hits, np->ipn_bytes, np->ipn_name, np->ipn_ref); #endif } return np->ipn_next; } diff --git a/sbin/ipf/libipf/printportcmp.c b/sbin/ipf/libipf/printportcmp.c index 2a5bd0229201..556a3ac2fb0b 100644 --- a/sbin/ipf/libipf/printportcmp.c +++ b/sbin/ipf/libipf/printportcmp.c @@ -1,30 +1,28 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" void -printportcmp(pr, frp) - int pr; - frpcmp_t *frp; +printportcmp(int pr, frpcmp_t *frp) { static char *pcmp1[] = { "*", "=", "!=", "<", ">", "<=", ">=", "<>", "><", ":" }; if (frp->frp_cmp == FR_INRANGE || frp->frp_cmp == FR_OUTRANGE) PRINTF(" port %d %s %d", frp->frp_port, pcmp1[frp->frp_cmp], frp->frp_top); else if (frp->frp_cmp == FR_INCRANGE) PRINTF(" port %d:%d", frp->frp_port, frp->frp_top); else PRINTF(" port %s %s", pcmp1[frp->frp_cmp], portname(pr, frp->frp_port)); } diff --git a/sbin/ipf/libipf/printproto.c b/sbin/ipf/libipf/printproto.c index 879da12d7857..7bc4952b3b7c 100644 --- a/sbin/ipf/libipf/printproto.c +++ b/sbin/ipf/libipf/printproto.c @@ -1,42 +1,39 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" #if !defined(lint) static const char rcsid[] = "@(#)$Id$"; #endif void -printproto(pr, p, np) - struct protoent *pr; - int p; - ipnat_t *np; +printproto(struct protoent *pr, int p, ipnat_t *np) { if (np != NULL) { if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP) PRINTF("tcp/udp"); else if (np->in_flags & IPN_TCP) PRINTF("tcp"); else if (np->in_flags & IPN_UDP) PRINTF("udp"); else if (np->in_flags & IPN_ICMPQUERY) PRINTF("icmp"); else if (np->in_pr[0] == 0) PRINTF("ip"); else if (pr != NULL) PRINTF("%s", pr->p_name); else PRINTF("%d", np->in_pr[0]); } else { if (pr != NULL) PRINTF("%s", pr->p_name); else PRINTF("%d", p); } } diff --git a/sbin/ipf/libipf/printsbuf.c b/sbin/ipf/libipf/printsbuf.c index efda99e856b8..c9c89ef6eb01 100644 --- a/sbin/ipf/libipf/printsbuf.c +++ b/sbin/ipf/libipf/printsbuf.c @@ -1,42 +1,40 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #ifdef IPFILTER_SCAN #include #include #include "ipf.h" #include "netinet/ip_scan.h" void -printsbuf(buf) - char *buf; +printsbuf(char *buf) { u_char *s; int i; for (s = (u_char *)buf, i = ISC_TLEN; i; i--, s++) { if (ISPRINT(*s)) putchar(*s); else PRINTF("\\%o", *s); } } #else void printsbuf(char *buf); -void printsbuf(buf) - char *buf; +void printsbuf(char *buf) { #if 0 buf = buf; /* gcc -Wextra */ #endif } #endif diff --git a/sbin/ipf/libipf/printstatefields.c b/sbin/ipf/libipf/printstatefields.c index 5632d8416c47..c928c637480b 100644 --- a/sbin/ipf/libipf/printstatefields.c +++ b/sbin/ipf/libipf/printstatefields.c @@ -1,358 +1,356 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: printstatefields.c,v 1.4.2.2 2012/01/26 05:44:26 darren_r Exp $ */ #include "ipf.h" wordtab_t statefields[] = { { "all", -2 }, { "ifp0", 1 }, { "ifp1", 2 }, { "ifp2", 3 }, { "ifp3", 4 }, { "ifname0", 5 }, { "ifname1", 6 }, { "ifname2", 7 }, { "ifname3", 8 }, { "pkts0", 9 }, { "pkts1", 10 }, { "pkts2", 11 }, { "pkts3", 12 }, { "bytes0", 13 }, { "bytes1", 14 }, { "bytes2", 15 }, { "bytes3", 16 }, { "state0", 17 }, { "state1", 18 }, { "age0", 19 }, { "age1", 20 }, { "ref", 21 }, { "isn0", 22 }, { "isn1", 23 }, { "sumd0", 24 }, { "sumd1", 25 }, { "src", 26 }, { "dst", 27 }, { "sport", 28 }, { "dport", 29 }, { "icmptype", 30 }, { "-", 31 }, { "pass", 32 }, { "proto", 33 }, { "version", 34 }, { "hash", 35 }, { "tag", 36 }, { "flags", 37 }, { "rulen", 38 }, { "group", 39 }, { "flx0", 40 }, { "flx1", 41 }, { "flx2", 42 }, { "flx3", 43 }, { "opt0", 44 }, { "opt1", 45 }, { "optmsk0", 46 }, { "optmsk1", 47 }, { "sec", 48 }, { "secmsk", 49 }, { "auth", 50 }, { "authmsk", 51 }, { "icmppkts0", 52 }, { "icmppkts1", 53 }, { "icmppkts2", 54 }, { "icmppkts3", 55 }, { NULL, 0 } }; void -printstatefield(sp, fieldnum) - ipstate_t *sp; - int fieldnum; +printstatefield(ipstate_t *sp, int fieldnum) { int i; switch (fieldnum) { case -2 : for (i = 1; statefields[i].w_word != NULL; i++) { if (statefields[i].w_value > 0) { printstatefield(sp, i); if (statefields[i + 1].w_value > 0) putchar('\t'); } } break; case 1: PRINTF("%#lx", (u_long)sp->is_ifp[0]); break; case 2: PRINTF("%#lx", (u_long)sp->is_ifp[1]); break; case 3: PRINTF("%#lx", (u_long)sp->is_ifp[2]); break; case 4: PRINTF("%#lx", (u_long)sp->is_ifp[3]); break; case 5: PRINTF("%s", sp->is_ifname[0]); break; case 6: PRINTF("%s", sp->is_ifname[1]); break; case 7: PRINTF("%s", sp->is_ifname[2]); break; case 8: PRINTF("%s", sp->is_ifname[3]); break; case 9: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", sp->is_pkts[0]); #else PRINTF("%lu", sp->is_pkts[0]); #endif break; case 10: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", sp->is_pkts[1]); #else PRINTF("%lu", sp->is_pkts[1]); #endif break; case 11: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", sp->is_pkts[2]); #else PRINTF("%lu", sp->is_pkts[2]); #endif break; case 12: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", sp->is_pkts[3]); #else PRINTF("%lu", sp->is_pkts[3]); #endif break; case 13: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", sp->is_bytes[0]); #else PRINTF("%lu", sp->is_bytes[0]); #endif break; case 14: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", sp->is_bytes[1]); #else PRINTF("%lu", sp->is_bytes[1]); #endif break; case 15: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", sp->is_bytes[2]); #else PRINTF("%lu", sp->is_bytes[2]); #endif break; case 16: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", sp->is_bytes[3]); #else PRINTF("%lu", sp->is_bytes[3]); #endif break; case 17: PRINTF("%d", sp->is_state[0]); break; case 18: PRINTF("%d", sp->is_state[1]); break; case 19: PRINTF("%d", sp->is_frage[0]); break; case 20: PRINTF("%d", sp->is_frage[1]); break; case 21: PRINTF("%d", sp->is_ref); break; case 22: PRINTF("%d", sp->is_isninc[0]); break; case 23: PRINTF("%d", sp->is_isninc[1]); break; case 24: PRINTF("%hd", sp->is_sumd[0]); break; case 25: PRINTF("%hd", sp->is_sumd[1]); break; case 26: PRINTF("%s", hostname(sp->is_v, &sp->is_src.in4)); break; case 27: PRINTF("%s", hostname(sp->is_v, &sp->is_dst.in4)); break; case 28: PRINTF("%hu", ntohs(sp->is_sport)); break; case 29: PRINTF("%hu", ntohs(sp->is_dport)); break; case 30: PRINTF("%d", sp->is_type); break; case 32: PRINTF("%#x", sp->is_pass); break; case 33: PRINTF("%d", sp->is_p); break; case 34: PRINTF("%d", sp->is_v); break; case 35: PRINTF("%d", sp->is_hv); break; case 36: PRINTF("%d", sp->is_tag); break; case 37: PRINTF("%#x", sp->is_flags); break; case 38: PRINTF("%d", sp->is_rulen); break; case 39: PRINTF("%s", sp->is_group); break; case 40: PRINTF("%#x", sp->is_flx[0][0]); break; case 41: PRINTF("%#x", sp->is_flx[0][1]); break; case 42: PRINTF("%#x", sp->is_flx[1][0]); break; case 43: PRINTF("%#x", sp->is_flx[1][1]); break; case 44: PRINTF("%#x", sp->is_opt[0]); break; case 45: PRINTF("%#x", sp->is_opt[1]); break; case 46: PRINTF("%#x", sp->is_optmsk[0]); break; case 47: PRINTF("%#x", sp->is_optmsk[1]); break; case 48: PRINTF("%#x", sp->is_sec); break; case 49: PRINTF("%#x", sp->is_secmsk); break; case 50: PRINTF("%#x", sp->is_auth); break; case 51: PRINTF("%#x", sp->is_authmsk); break; case 52: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", sp->is_icmppkts[0]); #else PRINTF("%lu", sp->is_icmppkts[0]); #endif break; case 53: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", sp->is_icmppkts[1]); #else PRINTF("%lu", sp->is_icmppkts[1]); #endif break; case 54: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", sp->is_icmppkts[2]); #else PRINTF("%lu", sp->is_icmppkts[2]); #endif break; case 55: #ifdef USE_QUAD_T PRINTF("%"PRIu64"", sp->is_icmppkts[3]); #else PRINTF("%lu", sp->is_icmppkts[3]); #endif break; default: break; } } diff --git a/sbin/ipf/libipf/printtcpflags.c b/sbin/ipf/libipf/printtcpflags.c index 9860780307a8..d134fb4a3120 100644 --- a/sbin/ipf/libipf/printtcpflags.c +++ b/sbin/ipf/libipf/printtcpflags.c @@ -1,30 +1,29 @@ #include "ipf.h" void -printtcpflags(tcpf, tcpfm) - u_32_t tcpf, tcpfm; +printtcpflags(u_32_t tcpf, u_32_t tcpfm) { u_char *t; char *s; if (tcpf & ~TCPF_ALL) { PRINTF("0x%x", tcpf); } else { for (s = flagset, t = flags; *s; s++, t++) { if (tcpf & *t) (void)putchar(*s); } } if (tcpfm) { (void)putchar('/'); if (tcpfm & ~TCPF_ALL) { PRINTF("0x%x", tcpfm); } else { for (s = flagset, t = flags; *s; s++, t++) if (tcpfm & *t) (void)putchar(*s); } } } diff --git a/sbin/ipf/libipf/printtqtable.c b/sbin/ipf/libipf/printtqtable.c index ffb512dac42e..aff8724eff60 100644 --- a/sbin/ipf/libipf/printtqtable.c +++ b/sbin/ipf/libipf/printtqtable.c @@ -1,26 +1,25 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include #include #include "ipf.h" void -printtqtable(table) - ipftq_t *table; +printtqtable(ipftq_t *table) { int i; PRINTF("TCP Entries per state\n"); for (i = 0; i < IPF_TCP_NSTATES; i++) PRINTF(" %5d", i); PRINTF("\n"); for (i = 0; i < IPF_TCP_NSTATES; i++) PRINTF(" %5d", table[i].ifq_ref - 1); PRINTF("\n"); } diff --git a/sbin/ipf/libipf/printtunable.c b/sbin/ipf/libipf/printtunable.c index aa82841b2fe1..b748efd5129a 100644 --- a/sbin/ipf/libipf/printtunable.c +++ b/sbin/ipf/libipf/printtunable.c @@ -1,30 +1,29 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" void -printtunable(tup) - ipftune_t *tup; +printtunable(ipftune_t *tup) { PRINTF("%s\tmin %lu\tmax %lu\tcurrent ", tup->ipft_name, tup->ipft_min, tup->ipft_max); if (tup->ipft_sz == sizeof(u_long)) PRINTF("%lu\n", tup->ipft_vlong); else if (tup->ipft_sz == sizeof(u_int)) PRINTF("%u\n", tup->ipft_vint); else if (tup->ipft_sz == sizeof(u_short)) PRINTF("%hu\n", tup->ipft_vshort); else if (tup->ipft_sz == sizeof(u_char)) PRINTF("%u\n", (u_int)tup->ipft_vchar); else { PRINTF("sz = %d\n", tup->ipft_sz); } } diff --git a/sbin/ipf/libipf/printunit.c b/sbin/ipf/libipf/printunit.c index bac3d45d34c5..935faf0f303a 100644 --- a/sbin/ipf/libipf/printunit.c +++ b/sbin/ipf/libipf/printunit.c @@ -1,47 +1,46 @@ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" void -printunit(unit) - int unit; +printunit(int unit) { switch (unit) { case IPL_LOGIPF : PRINTF("ipf"); break; case IPL_LOGNAT : PRINTF("nat"); break; case IPL_LOGSTATE : PRINTF("state"); break; case IPL_LOGAUTH : PRINTF("auth"); break; case IPL_LOGSYNC : PRINTF("sync"); break; case IPL_LOGSCAN : PRINTF("scan"); break; case IPL_LOGLOOKUP : PRINTF("lookup"); break; case IPL_LOGCOUNT : PRINTF("count"); break; case IPL_LOGALL : PRINTF("all"); break; default : PRINTF("unknown(%d)", unit); } } diff --git a/sbin/ipf/libipf/remove_hash.c b/sbin/ipf/libipf/remove_hash.c index a60c1fddc7e9..e76a4aca612b 100644 --- a/sbin/ipf/libipf/remove_hash.c +++ b/sbin/ipf/libipf/remove_hash.c @@ -1,50 +1,48 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include #include "ipf.h" #include "netinet/ip_lookup.h" #include "netinet/ip_htable.h" int -remove_hash(iphp, iocfunc) - iphtable_t *iphp; - ioctlfunc_t iocfunc; +remove_hash(iphtable_t *iphp, ioctlfunc_t iocfunc) { iplookupop_t op; iphtable_t iph; if (pool_open() == -1) return -1; op.iplo_type = IPLT_HASH; op.iplo_unit = iphp->iph_unit; strncpy(op.iplo_name, iphp->iph_name, sizeof(op.iplo_name)); if (*op.iplo_name == '\0') op.iplo_arg = IPHASH_ANON; op.iplo_size = sizeof(iph); op.iplo_struct = &iph; bzero((char *)&iph, sizeof(iph)); iph.iph_unit = iphp->iph_unit; iph.iph_type = iphp->iph_type; strncpy(iph.iph_name, iphp->iph_name, sizeof(iph.iph_name)); iph.iph_flags = iphp->iph_flags; if (pool_ioctl(iocfunc, SIOCLOOKUPDELTABLE, &op)) { if ((opts & OPT_DONOTHING) == 0) { return ipf_perror_fd(pool_fd(), iocfunc, "remove lookup hash table"); } } return 0; } diff --git a/sbin/ipf/libipf/remove_hashnode.c b/sbin/ipf/libipf/remove_hashnode.c index 58e9125015b6..f9d796472b1e 100644 --- a/sbin/ipf/libipf/remove_hashnode.c +++ b/sbin/ipf/libipf/remove_hashnode.c @@ -1,56 +1,52 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include #include "ipf.h" #include "netinet/ip_lookup.h" #include "netinet/ip_htable.h" int -remove_hashnode(unit, name, node, iocfunc) - int unit; - char *name; - iphtent_t *node; - ioctlfunc_t iocfunc; +remove_hashnode(int unit, char *name, iphtent_t *node, ioctlfunc_t iocfunc) { iplookupop_t op; iphtent_t ipe; if (pool_open() == -1) return -1; op.iplo_type = IPLT_HASH; op.iplo_unit = unit; op.iplo_size = sizeof(ipe); op.iplo_struct = &ipe; op.iplo_arg = 0; strncpy(op.iplo_name, name, sizeof(op.iplo_name)); bzero((char *)&ipe, sizeof(ipe)); bcopy((char *)&node->ipe_addr, (char *)&ipe.ipe_addr, sizeof(ipe.ipe_addr)); bcopy((char *)&node->ipe_mask, (char *)&ipe.ipe_mask, sizeof(ipe.ipe_mask)); if (opts & OPT_DEBUG) { printf("\t%s - ", inet_ntoa(ipe.ipe_addr.in4)); printf("%s\n", inet_ntoa(ipe.ipe_mask.in4)); } if (pool_ioctl(iocfunc, SIOCLOOKUPDELNODE, &op)) { if (!(opts & OPT_DONOTHING)) { return ipf_perror_fd(pool_fd(), iocfunc, "remove lookup hash node"); } } return 0; } diff --git a/sbin/ipf/libipf/remove_pool.c b/sbin/ipf/libipf/remove_pool.c index 8e7554963afd..157ab52179e0 100644 --- a/sbin/ipf/libipf/remove_pool.c +++ b/sbin/ipf/libipf/remove_pool.c @@ -1,47 +1,45 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include #include "ipf.h" #include "netinet/ip_lookup.h" #include "netinet/ip_htable.h" int -remove_pool(poolp, iocfunc) - ip_pool_t *poolp; - ioctlfunc_t iocfunc; +remove_pool(ip_pool_t *poolp, ioctlfunc_t iocfunc) { iplookupop_t op; ip_pool_t pool; if (pool_open() == -1) return -1; op.iplo_type = IPLT_POOL; op.iplo_unit = poolp->ipo_unit; strncpy(op.iplo_name, poolp->ipo_name, sizeof(op.iplo_name)); op.iplo_size = sizeof(pool); op.iplo_struct = &pool; bzero((char *)&pool, sizeof(pool)); pool.ipo_unit = poolp->ipo_unit; strncpy(pool.ipo_name, poolp->ipo_name, sizeof(pool.ipo_name)); pool.ipo_flags = poolp->ipo_flags; if (pool_ioctl(iocfunc, SIOCLOOKUPDELTABLE, &op)) { if ((opts & OPT_DONOTHING) == 0) { return ipf_perror_fd(pool_fd(), iocfunc, "delete lookup pool"); } } return 0; } diff --git a/sbin/ipf/libipf/remove_poolnode.c b/sbin/ipf/libipf/remove_poolnode.c index 0b78118ec582..78085c8041a4 100644 --- a/sbin/ipf/libipf/remove_poolnode.c +++ b/sbin/ipf/libipf/remove_poolnode.c @@ -1,54 +1,51 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include #include "ipf.h" #include "netinet/ip_lookup.h" #include "netinet/ip_pool.h" int -remove_poolnode(unit, name, node, iocfunc) - int unit; - char *name; - ip_pool_node_t *node; - ioctlfunc_t iocfunc; +remove_poolnode(int unit, char *name, ip_pool_node_t *node, + ioctlfunc_t iocfunc) { ip_pool_node_t pn; iplookupop_t op; if (pool_open() == -1) return -1; op.iplo_unit = unit; op.iplo_type = IPLT_POOL; op.iplo_arg = 0; strncpy(op.iplo_name, name, sizeof(op.iplo_name)); op.iplo_struct = &pn; op.iplo_size = sizeof(pn); bzero((char *)&pn, sizeof(pn)); bcopy((char *)&node->ipn_addr, (char *)&pn.ipn_addr, sizeof(pn.ipn_addr)); bcopy((char *)&node->ipn_mask, (char *)&pn.ipn_mask, sizeof(pn.ipn_mask)); pn.ipn_info = node->ipn_info; strncpy(pn.ipn_name, node->ipn_name, sizeof(pn.ipn_name)); if (pool_ioctl(iocfunc, SIOCLOOKUPDELNODE, &op)) { if ((opts & OPT_DONOTHING) == 0) { return ipf_perror_fd(pool_fd(), iocfunc, "remove lookup pool node"); } } return 0; } diff --git a/sbin/ipf/libipf/resetlexer.c b/sbin/ipf/libipf/resetlexer.c index 558db98603ed..e6fbbce4ccc0 100644 --- a/sbin/ipf/libipf/resetlexer.c +++ b/sbin/ipf/libipf/resetlexer.c @@ -1,25 +1,25 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" long string_start = -1; long string_end = -1; char *string_val = NULL; long pos = 0; -void resetlexer() +void resetlexer(void) { string_start = -1; string_end = -1; string_val = NULL; pos = 0; } diff --git a/sbin/ipf/libipf/rwlock_emul.c b/sbin/ipf/libipf/rwlock_emul.c index f2f2ed19532a..e15d9610887f 100644 --- a/sbin/ipf/libipf/rwlock_emul.c +++ b/sbin/ipf/libipf/rwlock_emul.c @@ -1,166 +1,150 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" #define EMM_MAGIC 0x97dd8b3a -void eMrwlock_read_enter(rw, file, line) - eMrwlock_t *rw; - char *file; - int line; +void eMrwlock_read_enter(eMrwlock_t *rw, char *file, int line) { if (rw->eMrw_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMrwlock_read_enter(%p): bad magic: %#x\n", rw->eMrw_owner, rw, rw->eMrw_magic); abort(); } if (rw->eMrw_read != 0 || rw->eMrw_write != 0) { fprintf(stderr, "%s:eMrwlock_read_enter(%p): already locked: %d/%d\n", rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write); abort(); } rw->eMrw_read++; rw->eMrw_heldin = file; rw->eMrw_heldat = line; } -void eMrwlock_write_enter(rw, file, line) - eMrwlock_t *rw; - char *file; - int line; +void eMrwlock_write_enter(eMrwlock_t *rw, char *file, int line) { if (rw->eMrw_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n", rw->eMrw_owner, rw, rw->eMrw_magic); abort(); } if (rw->eMrw_read != 0 || rw->eMrw_write != 0) { fprintf(stderr, "%s:eMrwlock_write_enter(%p): already locked: %d/%d\n", rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write); abort(); } rw->eMrw_write++; rw->eMrw_heldin = file; rw->eMrw_heldat = line; } -void eMrwlock_try_upgrade(rw, file, line) - eMrwlock_t *rw; - char *file; - int line; +void eMrwlock_try_upgrade(eMrwlock_t *rw, char *file, int line) { if (rw->eMrw_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n", rw->eMrw_owner, rw, rw->eMrw_magic); abort(); } if (rw->eMrw_read != 0 || rw->eMrw_write != 0) { fprintf(stderr, "%s:eMrwlock_try_upgrade(%p): already locked: %d/%d\n", rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write); abort(); } rw->eMrw_write++; rw->eMrw_heldin = file; rw->eMrw_heldat = line; } -void eMrwlock_downgrade(rw, file, line) - eMrwlock_t *rw; - char *file; - int line; +void eMrwlock_downgrade(eMrwlock_t *rw, char *file, int line) { if (rw->eMrw_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n", rw->eMrw_owner, rw, rw->eMrw_magic); abort(); } if (rw->eMrw_read != 0 || rw->eMrw_write != 1) { fprintf(stderr, "%s:eMrwlock_write_enter(%p): already locked: %d/%d\n", rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write); abort(); } rw->eMrw_write--; rw->eMrw_read++; rw->eMrw_heldin = file; rw->eMrw_heldat = line; } -void eMrwlock_exit(rw) - eMrwlock_t *rw; +void eMrwlock_exit(eMrwlock_t *rw) { if (rw->eMrw_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMrwlock_exit(%p): bad magic: %#x\n", rw->eMrw_owner, rw, rw->eMrw_magic); abort(); } if (rw->eMrw_read != 1 && rw->eMrw_write != 1) { fprintf(stderr, "%s:eMrwlock_exit(%p): not locked: %d/%d\n", rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write); abort(); } if (rw->eMrw_read == 1) rw->eMrw_read--; else if (rw->eMrw_write == 1) rw->eMrw_write--; rw->eMrw_heldin = NULL; rw->eMrw_heldat = 0; } static int initcount = 0; -void eMrwlock_init(rw, who) - eMrwlock_t *rw; - char *who; +void eMrwlock_init(eMrwlock_t *rw, char *who) { if (rw->eMrw_magic == EMM_MAGIC) { /* safe bet ? */ fprintf(stderr, "%s:eMrwlock_init(%p): already initialised?: %#x\n", rw->eMrw_owner, rw, rw->eMrw_magic); abort(); } rw->eMrw_magic = EMM_MAGIC; rw->eMrw_read = 0; rw->eMrw_write = 0; if (who != NULL) rw->eMrw_owner = strdup(who); else rw->eMrw_owner = NULL; initcount++; } -void eMrwlock_destroy(rw) - eMrwlock_t *rw; +void eMrwlock_destroy(eMrwlock_t *rw) { if (rw->eMrw_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMrwlock_destroy(%p): bad magic: %#x\n", rw->eMrw_owner, rw, rw->eMrw_magic); abort(); } if (rw->eMrw_owner != NULL) free(rw->eMrw_owner); memset(rw, 0xa5, sizeof(*rw)); initcount--; } -void ipf_rwlock_clean() +void ipf_rwlock_clean(void) { if (initcount != 0) abort(); } diff --git a/sbin/ipf/libipf/save_execute.c b/sbin/ipf/libipf/save_execute.c index 68a3a3754900..0f46ec4ee3c7 100644 --- a/sbin/ipf/libipf/save_execute.c +++ b/sbin/ipf/libipf/save_execute.c @@ -1,80 +1,76 @@ #include "ipf.h" #include "ipmon.h" static void *execute_parse(char **); static void execute_destroy(void *); static int execute_send(void *, ipmon_msg_t *); static void execute_print(void *); typedef struct execute_opts_s { char *path; } execute_opts_t; ipmon_saver_t executesaver = { "execute", execute_destroy, NULL, /* dup */ NULL, /* match */ execute_parse, execute_print, execute_send }; static void * execute_parse(char **strings) { execute_opts_t *ctx; ctx = calloc(1, sizeof(*ctx)); if (ctx != NULL && strings[0] != NULL && strings[0][0] != '\0') { ctx->path = strdup(strings[0]); } else { free(ctx); return NULL; } return ctx; } static void -execute_print(ctx) - void *ctx; +execute_print(void *ctx) { execute_opts_t *exe = ctx; printf("%s", exe->path); } static void -execute_destroy(ctx) - void *ctx; +execute_destroy(void *ctx) { execute_opts_t *exe = ctx; if (exe != NULL) free(exe->path); free(exe); } static int -execute_send(ctx, msg) - void *ctx; - ipmon_msg_t *msg; +execute_send(void *ctx, ipmon_msg_t *msg) { execute_opts_t *exe = ctx; FILE *fp; fp = popen(exe->path, "w"); if (fp != NULL) { fwrite(msg->imm_msg, msg->imm_msglen, 1, fp); pclose(fp); } return 0; } diff --git a/sbin/ipf/libipf/save_file.c b/sbin/ipf/libipf/save_file.c index 84ef157009f5..1ebcb45430af 100644 --- a/sbin/ipf/libipf/save_file.c +++ b/sbin/ipf/libipf/save_file.c @@ -1,130 +1,123 @@ #include "ipf.h" #include "ipmon.h" static void *file_parse(char **); static void file_destroy(void *); static int file_send(void *, ipmon_msg_t *); static void file_print(void *); static int file_match(void *, void *); static void *file_dup(void *); typedef struct file_opts_s { FILE *fp; int raw; char *path; int ref; } file_opts_t; ipmon_saver_t filesaver = { "file", file_destroy, file_dup, file_match, file_parse, file_print, file_send }; static void * -file_parse(strings) - char **strings; +file_parse(char **strings) { file_opts_t *ctx; ctx = calloc(1, sizeof(*ctx)); if (ctx == NULL) return NULL; if (strings[0] != NULL && strings[0][0] != '\0') { ctx->ref = 1; if (!strncmp(strings[0], "raw://", 6)) { ctx->raw = 1; ctx->path = strdup(strings[0] + 6); ctx->fp = fopen(ctx->path, "ab"); } else if (!strncmp(strings[0], "file://", 7)) { ctx->path = strdup(strings[0] + 7); ctx->fp = fopen(ctx->path, "a"); } else { free(ctx); ctx = NULL; } } else { free(ctx); ctx = NULL; } return ctx; } static int -file_match(ctx1, ctx2) - void *ctx1, *ctx2; +file_match(void *ctx1, void *ctx2) { file_opts_t *f1 = ctx1, *f2 = ctx2; if (f1->raw != f2->raw) return 1; if (strcmp(f1->path, f2->path)) return 1; return 0; } static void * -file_dup(ctx) - void *ctx; +file_dup(void *ctx) { file_opts_t *f = ctx; f->ref++; return f; } static void -file_print(ctx) - void *ctx; +file_print(void *ctx) { file_opts_t *file = ctx; if (file->raw) printf("raw://"); else printf("file://"); printf("%s", file->path); } static void -file_destroy(ctx) - void *ctx; +file_destroy(void *ctx) { file_opts_t *file = ctx; file->ref--; if (file->ref > 0) return; if (file->path != NULL) free(file->path); free(file); } static int -file_send(ctx, msg) - void *ctx; - ipmon_msg_t *msg; +file_send(void *ctx, ipmon_msg_t *msg) { file_opts_t *file = ctx; if (file->raw) { fwrite(msg->imm_data, msg->imm_dsize, 1, file->fp); } else { fprintf(file->fp, "%s", msg->imm_msg); } return 0; } diff --git a/sbin/ipf/libipf/save_nothing.c b/sbin/ipf/libipf/save_nothing.c index 39158cf51ddb..6cb8948ab8ac 100644 --- a/sbin/ipf/libipf/save_nothing.c +++ b/sbin/ipf/libipf/save_nothing.c @@ -1,62 +1,59 @@ #include "ipf.h" #include "ipmon.h" static void *nothing_parse(char **); static void nothing_destroy(void *); static int nothing_send(void *, ipmon_msg_t *); typedef struct nothing_opts_s { FILE *fp; int raw; char *path; } nothing_opts_t; ipmon_saver_t nothingsaver = { "nothing", nothing_destroy, NULL, /* dup */ NULL, /* match */ nothing_parse, NULL, /* print */ nothing_send }; static void * nothing_parse(char **strings) { void *ctx; #if 0 strings = strings; /* gcc -Wextra */ #endif ctx = calloc(1, sizeof(void *)); return ctx; } static void -nothing_destroy(ctx) - void *ctx; +nothing_destroy(void *ctx) { free(ctx); } static int -nothing_send(ctx, msg) - void *ctx; - ipmon_msg_t *msg; +nothing_send(void *ctx, ipmon_msg_t *msg) { #if 0 ctx = ctx; /* gcc -Wextra */ msg = msg; /* gcc -Wextra */ #endif /* * Do nothing */ return 0; } diff --git a/sbin/ipf/libipf/save_syslog.c b/sbin/ipf/libipf/save_syslog.c index 37d428bdb4aa..ce75d428d186 100644 --- a/sbin/ipf/libipf/save_syslog.c +++ b/sbin/ipf/libipf/save_syslog.c @@ -1,137 +1,133 @@ #include "ipf.h" #include "ipmon.h" #include static void *syslog_parse(char **); static void syslog_destroy(void *); static int syslog_send(void *, ipmon_msg_t *); static void syslog_print(void *); typedef struct syslog_opts_s { int facpri; int fac; int pri; } syslog_opts_t; ipmon_saver_t syslogsaver = { "syslog", syslog_destroy, NULL, /* dup */ NULL, /* match */ syslog_parse, syslog_print, syslog_send }; static void * syslog_parse(char **strings) { syslog_opts_t *ctx; char *str; char *s; ctx = calloc(1, sizeof(*ctx)); if (ctx == NULL) return NULL; ctx->facpri = -1; if (strings[0] != NULL && strings[0][0] != '\0') { str = strdup(*strings); if (str != NULL && *str != '\0') { int fac = -1, pri = -1; s = strchr(str, '.'); if (s != NULL) *s++ = '\0'; if (*str != '\0') { fac = fac_findname(str); if (fac == -1) { free(str); free(ctx); return NULL; } } if (s != NULL && *s != '\0') { pri = pri_findname(s); if (pri == -1) { free(str); free(ctx); return NULL; } } free(str); ctx->fac = fac; ctx->pri = pri; if (pri == -1) ctx->facpri = fac; else if (fac == -1) ctx->facpri = pri; else ctx->facpri = fac | pri; } else { if (str != NULL) free(str); free(ctx); ctx = NULL; } } return ctx; } static void -syslog_print(ctx) - void *ctx; +syslog_print(void *ctx) { syslog_opts_t *sys = ctx; if (sys->facpri == -1) return; if (sys->fac == -1) { printf(".%s", pri_toname(sys->pri)); } else if (sys->pri == -1) { printf("%s.", fac_toname(sys->fac)); } else { printf("%s.%s", fac_toname(sys->facpri & LOG_FACMASK), pri_toname(sys->facpri & LOG_PRIMASK)); } } static void -syslog_destroy(ctx) - void *ctx; +syslog_destroy(void *ctx) { free(ctx); } static int -syslog_send(ctx, msg) - void *ctx; - ipmon_msg_t *msg; +syslog_send(void *ctx, ipmon_msg_t *msg) { syslog_opts_t *sys = ctx; int facpri; if (sys->facpri == -1) { facpri = msg->imm_loglevel; } else { if (sys->pri == -1) { facpri = sys->fac | (msg->imm_loglevel & LOG_PRIMASK); } else if (sys->fac == -1) { facpri = sys->pri | (msg->imm_loglevel & LOG_FACMASK); } else { facpri = sys->facpri; } } syslog(facpri, "%s", msg->imm_msg); return 0; } diff --git a/sbin/ipf/libipf/save_v1trap.c b/sbin/ipf/libipf/save_v1trap.c index cca61ac600e5..cbd555739462 100644 --- a/sbin/ipf/libipf/save_v1trap.c +++ b/sbin/ipf/libipf/save_v1trap.c @@ -1,463 +1,443 @@ #include "ipf.h" #include "netinet/ipl.h" #include "ipmon.h" #include #define IPF_ENTERPRISE 9932 /* * Enterprise number OID: * 1.3.6.1.4.1.9932 */ static u_char ipf_enterprise[] = { 6, 7, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c }; static u_char ipf_trap0_1[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 1 }; static u_char ipf_trap0_2[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 2 }; static int writeint(u_char *, int); static int writelength(u_char *, u_int); static int maketrap_v1(char *, u_char *, int, u_char *, int, u_32_t, time_t); static void snmpv1_destroy(void *); static void *snmpv1_dup(void *); static int snmpv1_match(void *, void *); static void *snmpv1_parse(char **); static void snmpv1_print(void *); static int snmpv1_send(void *, ipmon_msg_t *); typedef struct snmpv1_opts_s { char *community; int fd; int v6; int ref; #ifdef USE_INET6 struct sockaddr_in6 sin6; #endif struct sockaddr_in sin; } snmpv1_opts_t; ipmon_saver_t snmpv1saver = { "snmpv1", snmpv1_destroy, snmpv1_dup, /* dup */ snmpv1_match, /* match */ snmpv1_parse, snmpv1_print, snmpv1_send }; static int -snmpv1_match(ctx1, ctx2) - void *ctx1, *ctx2; +snmpv1_match(void *ctx1, void *ctx2) { snmpv1_opts_t *s1 = ctx1, *s2 = ctx2; if (s1->v6 != s2->v6) return 1; if (strcmp(s1->community, s2->community)) return 1; #ifdef USE_INET6 if (s1->v6 == 1) { if (memcmp(&s1->sin6, &s2->sin6, sizeof(s1->sin6))) return 1; } else #endif { if (memcmp(&s1->sin, &s2->sin, sizeof(s1->sin))) return 1; } return 0; } static void * -snmpv1_dup(ctx) - void *ctx; +snmpv1_dup(void *ctx) { snmpv1_opts_t *s = ctx; s->ref++; return s; } static void -snmpv1_print(ctx) - void *ctx; +snmpv1_print(void *ctx) { snmpv1_opts_t *snmpv1 = ctx; printf("%s ", snmpv1->community); #ifdef USE_INET6 if (snmpv1->v6 == 1) { char buf[80]; printf("%s", inet_ntop(AF_INET6, &snmpv1->sin6.sin6_addr, buf, sizeof(snmpv1->sin6.sin6_addr))); } else #endif { printf("%s", inet_ntoa(snmpv1->sin.sin_addr)); } } static void * snmpv1_parse(char **strings) { snmpv1_opts_t *ctx; int result; char *str; char *s; if (strings[0] == NULL || strings[0][0] == '\0') return NULL; if (strchr(*strings, ' ') == NULL) return NULL; str = strdup(*strings); ctx = calloc(1, sizeof(*ctx)); if (ctx == NULL) return NULL; ctx->fd = -1; s = strchr(str, ' '); *s++ = '\0'; ctx->community = str; while (ISSPACE(*s)) s++; if (!*s) { free(str); free(ctx); return NULL; } #ifdef USE_INET6 if (strchr(s, ':') == NULL) { result = inet_pton(AF_INET, s, &ctx->sin.sin_addr); if (result == 1) { ctx->fd = socket(AF_INET, SOCK_DGRAM, 0); if (ctx->fd >= 0) { ctx->sin.sin_family = AF_INET; ctx->sin.sin_port = htons(162); if (connect(ctx->fd, (struct sockaddr *)&ctx->sin, sizeof(ctx->sin)) != 0) { snmpv1_destroy(ctx); return NULL; } } } } else { result = inet_pton(AF_INET6, s, &ctx->sin6.sin6_addr); if (result == 1) { ctx->v6 = 1; ctx->fd = socket(AF_INET6, SOCK_DGRAM, 0); if (ctx->fd >= 0) { ctx->sin6.sin6_family = AF_INET6; ctx->sin6.sin6_port = htons(162); if (connect(ctx->fd, (struct sockaddr *)&ctx->sin6, sizeof(ctx->sin6)) != 0) { snmpv1_destroy(ctx); return NULL; } } } } #else result = inet_aton(s, &ctx->sin.sin_addr); if (result == 1) { ctx->fd = socket(AF_INET, SOCK_DGRAM, 0); if (ctx->fd >= 0) { ctx->sin.sin_family = AF_INET; ctx->sin.sin_port = htons(162); if (connect(ctx->fd, (struct sockaddr *)&ctx->sin, sizeof(ctx->sin)) != 0) { snmpv1_destroy(ctx); return NULL; } } } #endif if (result != 1) { free(str); free(ctx); return NULL; } ctx->ref = 1; return ctx; } static void -snmpv1_destroy(ctx) - void *ctx; +snmpv1_destroy(void *ctx) { snmpv1_opts_t *v1 = ctx; v1->ref--; if (v1->ref > 0) return; if (v1->community) free(v1->community); if (v1->fd >= 0) close(v1->fd); free(v1); } static int -snmpv1_send(ctx, msg) - void *ctx; - ipmon_msg_t *msg; +snmpv1_send(void *ctx, ipmon_msg_t *msg) { snmpv1_opts_t *v1 = ctx; return sendtrap_v1_0(v1->fd, v1->community, msg->imm_msg, msg->imm_msglen, msg->imm_when); } static char def_community[] = "public"; /* ublic */ static int -writelength(buffer, value) - u_char *buffer; - u_int value; +writelength(u_char *buffer, u_int value) { u_int n = htonl(value); int len; if (value < 128) { *buffer = value; return 1; } if (value > 0xffffff) len = 4; else if (value > 0xffff) len = 3; else if (value > 0xff) len = 2; else len = 1; *buffer = 0x80 | len; bcopy((u_char *)&n + 4 - len, buffer + 1, len); return len + 1; } static int -writeint(buffer, value) - u_char *buffer; - int value; +writeint(u_char *buffer, int value) { u_char *s = buffer; u_int n = value; if (value == 0) { *buffer = 0; return 1; } if (n > 4194304) { *s++ = 0x80 | (n / 4194304); n -= 4194304 * (n / 4194304); } if (n > 32768) { *s++ = 0x80 | (n / 32768); n -= 32768 * (n / 327678); } if (n > 128) { *s++ = 0x80 | (n / 128); n -= (n / 128) * 128; } *s++ = (u_char)n; return s - buffer; } /* * First style of traps is: * 1.3.6.1.4.1.9932.1.1 */ static int -maketrap_v1(community, buffer, bufsize, msg, msglen, ipaddr, when) - char *community; - u_char *buffer; - int bufsize; - u_char *msg; - int msglen; - u_32_t ipaddr; - time_t when; +maketrap_v1(char *community, u_char *buffer, int bufsize, u_char *msg, + int msglen, u_32_t ipaddr, time_t when) { u_char *s = buffer, *t, *pdulen, *varlen; int basesize = 73; u_short len; int trapmsglen; int pdulensz; int varlensz; int baselensz; int n; if (community == NULL || *community == '\0') community = def_community; basesize += strlen(community) + msglen; if (basesize + 8 > bufsize) return 0; memset(buffer, 0xff, bufsize); *s++ = 0x30; /* Sequence */ if (basesize - 1 >= 128) { baselensz = 2; basesize++; } else { baselensz = 1; } s += baselensz; *s++ = 0x02; /* Integer32 */ *s++ = 0x01; /* length 1 */ *s++ = 0x00; /* version 1 */ *s++ = 0x04; /* octet string */ *s++ = strlen(community); /* length of "public" */ bcopy(community, s, s[-1]); s += s[-1]; *s++ = 0xA4; /* PDU(4) */ pdulen = s++; if (basesize - (s - buffer) >= 128) { pdulensz = 2; basesize++; s++; } else { pdulensz = 1; } /* enterprise */ bcopy(ipf_enterprise, s, sizeof(ipf_enterprise)); s += sizeof(ipf_enterprise); /* Agent address */ *s++ = 0x40; *s++ = 0x4; bcopy(&ipaddr, s, 4); s += 4; /* Generic Trap code */ *s++ = 0x2; n = writeint(s + 1, 6); if (n == 0) return 0; *s = n; s += n + 1; /* Specific Trap code */ *s++ = 0x2; n = writeint(s + 1, 0); if (n == 0) return 0; *s = n; s += n + 1; /* Time stamp */ *s++ = 0x43; /* TimeTicks */ *s++ = 0x04; /* TimeTicks */ s[0] = when >> 24; s[1] = when >> 16; s[2] = when >> 8; s[3] = when & 0xff; s += 4; /* * The trap0 message is "ipfilter_version" followed by the message */ *s++ = 0x30; varlen = s; if (basesize - (s - buffer) >= 128) { varlensz = 2; basesize++; } else { varlensz = 1; } s += varlensz; *s++ = 0x30; t = s + 1; bcopy(ipf_trap0_1, t, sizeof(ipf_trap0_1)); t += sizeof(ipf_trap0_1); *t++ = 0x2; /* Integer */ n = writeint(t + 1, IPFILTER_VERSION); *t = n; t += n + 1; len = t - s - 1; writelength(s, len); s = t; *s++ = 0x30; if (basesize - (s - buffer) >= 128) { trapmsglen = 2; basesize++; } else { trapmsglen = 1; } t = s + trapmsglen; bcopy(ipf_trap0_2, t, sizeof(ipf_trap0_2)); t += sizeof(ipf_trap0_2); *t++ = 0x4; /* Octet string */ n = writelength(t, msglen); t += n; bcopy(msg, t, msglen); t += msglen; len = t - s - trapmsglen; writelength(s, len); len = t - varlen - varlensz; writelength(varlen, len); /* pdu length */ len = t - pdulen - pdulensz; writelength(pdulen, len); /* pdu length */ len = t - buffer - baselensz - 1; writelength(buffer + 1, len); /* length of trap */ return t - buffer; } int -sendtrap_v1_0(fd, community, msg, msglen, when) - int fd; - char *community, *msg; - int msglen; - time_t when; +sendtrap_v1_0(int fd, char *community, char *msg, int msglen, time_t when) { u_char buffer[1500]; int n; n = maketrap_v1(community, buffer, sizeof(buffer), (u_char *)msg, msglen, 0, when); if (n > 0) { return send(fd, buffer, n, 0); } return 0; } diff --git a/sbin/ipf/libipf/save_v2trap.c b/sbin/ipf/libipf/save_v2trap.c index 480f4290851d..4572d5c267ed 100644 --- a/sbin/ipf/libipf/save_v2trap.c +++ b/sbin/ipf/libipf/save_v2trap.c @@ -1,461 +1,444 @@ #include "ipf.h" #include "netinet/ipl.h" #include "ipmon.h" #include static u_char sysuptime[] = { 6, 8, 0x2b, 6, 1, 2, 1, 1, 3, 0 }; /* * Enterprise number OID: * 1.3.6.1.4.1.9932 */ static u_char ipf_trap0_1[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 1 }; static u_char ipf_trap0_2[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 2 }; static int writeint(u_char *, int); static int writelength(u_char *, u_int); static int maketrap_v2(char *, u_char *, int, u_char *, int); static void snmpv2_destroy(void *); static void *snmpv2_dup(void *); static int snmpv2_match(void *, void *); static void *snmpv2_parse(char **); static void snmpv2_print(void *); static int snmpv2_send(void *, ipmon_msg_t *); int sendtrap_v2_0(int, char *, char *, int); static char def_community[] = "public"; /* ublic */ typedef struct snmpv2_opts_s { char *community; char *server; int fd; int v6; int ref; #ifdef USE_INET6 struct sockaddr_in6 sin6; #endif struct sockaddr_in sin; } snmpv2_opts_t; ipmon_saver_t snmpv2saver = { "snmpv2", snmpv2_destroy, snmpv2_dup, /* dup */ snmpv2_match, /* match */ snmpv2_parse, snmpv2_print, snmpv2_send }; static int -snmpv2_match(ctx1, ctx2) - void *ctx1, *ctx2; +snmpv2_match(void *ctx1, void *ctx2) { snmpv2_opts_t *s1 = ctx1, *s2 = ctx2; if (s1->v6 != s2->v6) return 1; if (strcmp(s1->community, s2->community)) return 1; #ifdef USE_INET6 if (s1->v6 == 1) { if (memcmp(&s1->sin6, &s2->sin6, sizeof(s1->sin6))) return 1; } else #endif { if (memcmp(&s1->sin, &s2->sin, sizeof(s1->sin))) return 1; } return 0; } static void * -snmpv2_dup(ctx) - void *ctx; +snmpv2_dup(void *ctx) { snmpv2_opts_t *s = ctx; s->ref++; return s; } static void -snmpv2_print(ctx) - void *ctx; +snmpv2_print(void *ctx) { snmpv2_opts_t *snmpv2 = ctx; printf("%s ", snmpv2->community); #ifdef USE_INET6 if (snmpv2->v6 == 1) { char buf[80]; printf("%s", inet_ntop(AF_INET6, &snmpv2->sin6.sin6_addr, buf, sizeof(snmpv2->sin6.sin6_addr))); } else #endif { printf("%s", inet_ntoa(snmpv2->sin.sin_addr)); } } static void * snmpv2_parse(char **strings) { snmpv2_opts_t *ctx; int result; char *str; char *s; if (strings[0] == NULL || strings[0][0] == '\0') return NULL; if (strchr(*strings, ' ') == NULL) return NULL; str = strdup(*strings); ctx = calloc(1, sizeof(*ctx)); if (ctx == NULL) { free(str); return NULL; } ctx->fd = -1; s = strchr(str, ' '); *s++ = '\0'; ctx->community = str; while (ISSPACE(*s)) s++; if (!*s) { free(str); free(ctx); return NULL; } #ifdef USE_INET6 if (strchr(s, ':') == NULL) { result = inet_pton(AF_INET, s, &ctx->sin.sin_addr); if (result == 1) { ctx->fd = socket(AF_INET, SOCK_DGRAM, 0); if (ctx->fd >= 0) { ctx->sin.sin_family = AF_INET; ctx->sin.sin_port = htons(162); if (connect(ctx->fd, (struct sockaddr *)&ctx->sin, sizeof(ctx->sin)) != 0) { snmpv2_destroy(ctx); return NULL; } } } } else { result = inet_pton(AF_INET6, s, &ctx->sin6.sin6_addr); if (result == 1) { ctx->v6 = 1; ctx->fd = socket(AF_INET6, SOCK_DGRAM, 0); if (ctx->fd >= 0) { ctx->sin6.sin6_family = AF_INET6; ctx->sin6.sin6_port = htons(162); if (connect(ctx->fd, (struct sockaddr *)&ctx->sin6, sizeof(ctx->sin6)) != 0) { snmpv2_destroy(ctx); return NULL; } } } } #else result = inet_aton(s, &ctx->sin.sin_addr); if (result == 1) { ctx->fd = socket(AF_INET, SOCK_DGRAM, 0); if (ctx->fd >= 0) { ctx->sin.sin_family = AF_INET; ctx->sin.sin_port = htons(162); if (connect(ctx->fd, (struct sockaddr *)&ctx->sin, sizeof(ctx->sin)) != 0) { snmpv2_destroy(ctx); return NULL; } } } #endif if (result != 1) { free(str); free(ctx); return NULL; } ctx->ref = 1; return ctx; } static void -snmpv2_destroy(ctx) - void *ctx; +snmpv2_destroy(void *ctx) { snmpv2_opts_t *v2 = ctx; v2->ref--; if (v2->ref > 0) return; if (v2->community) free(v2->community); if (v2->fd >= 0) close(v2->fd); free(v2); } static int -snmpv2_send(ctx, msg) - void *ctx; - ipmon_msg_t *msg; +snmpv2_send(void *ctx, ipmon_msg_t *msg) { snmpv2_opts_t *v2 = ctx; return sendtrap_v2_0(v2->fd, v2->community, msg->imm_msg, msg->imm_msglen); } static int -writelength(buffer, value) - u_char *buffer; - u_int value; +writelength(u_char *buffer, u_int value) { u_int n = htonl(value); int len; if (value < 128) { *buffer = value; return 1; } if (value > 0xffffff) len = 4; else if (value > 0xffff) len = 3; else if (value > 0xff) len = 2; else len = 1; *buffer = 0x80 | len; bcopy((u_char *)&n + 4 - len, buffer + 1, len); return len + 1; } static int -writeint(buffer, value) - u_char *buffer; - int value; +writeint(u_char *buffer, int value) { u_char *s = buffer; u_int n = value; if (value == 0) { *buffer = 0; return 1; } if (n > 4194304) { *s++ = 0x80 | (n / 4194304); n -= 4194304 * (n / 4194304); } if (n > 32768) { *s++ = 0x80 | (n / 32768); n -= 32768 * (n / 327678); } if (n > 128) { *s++ = 0x80 | (n / 128); n -= (n / 128) * 128; } *s++ = (u_char)n; return s - buffer; } /* * First style of traps is: * 1.3.6.1.4.1.9932.1.1 */ static int -maketrap_v2(community, buffer, bufsize, msg, msglen) - char *community; - u_char *buffer; - int bufsize; - u_char *msg; - int msglen; +maketrap_v2(char *community, u_char *buffer, int bufsize, u_char *msg, + int msglen) { u_char *s = buffer, *t, *pdulen; u_char *varlen; int basesize = 77; u_short len; int trapmsglen; int pdulensz; int varlensz; int baselensz; int n; if (community == NULL || *community == '\0') community = def_community; basesize += strlen(community) + msglen; if (basesize + 8 > bufsize) return 0; memset(buffer, 0xff, bufsize); *s++ = 0x30; /* Sequence */ if (basesize - 1 >= 128) { baselensz = 2; basesize++; } else { baselensz = 1; } s += baselensz; *s++ = 0x02; /* Integer32 */ *s++ = 0x01; /* length 1 */ *s++ = 0x01; /* version 2 */ *s++ = 0x04; /* octet string */ *s++ = strlen(community); /* length of "public" */ bcopy(community, s, s[-1]); s += s[-1]; *s++ = 0xA7; /* PDU(7) */ pdulen = s++; if (basesize - (s - buffer) >= 128) { pdulensz = 2; basesize++; s++; } else { pdulensz = 1; } /* request id */ *s++ = 0x2; /* integer */ *s++ = 0x4; /* len 4 */ *s++ = 0x0; /* noError */ *s++ = 0x0; /* noError */ *s++ = 0x0; /* noError */ *s++ = 0x0; /* noError */ /* error status */ *s++ = 0x2; /* integer */ *s++ = 0x1; /* len 1 */ *s++ = 0x0; /* noError */ /* error-index */ *s++ = 0x2; /* integer */ *s++ = 0x1; /* len 1 */ *s++ = 0x0; /* noError */ *s++ = 0x30; /* sequence */ varlen = s++; if (basesize - (s - buffer) >= 128) { varlensz = 2; basesize++; s++; } else { varlensz = 1; } *s++ = 0x30; /* sequence */ *s++ = sizeof(sysuptime) + 6; bcopy(sysuptime, s, sizeof(sysuptime)); s += sizeof(sysuptime); *s++ = 0x43; /* Timestamp */ *s++ = 0x04; /* TimeTicks */ *s++ = 0x0; *s++ = 0x0; *s++ = 0x0; *s++ = 0x0; *s++ = 0x30; t = s + 1; bcopy(ipf_trap0_1, t, sizeof(ipf_trap0_1)); t += sizeof(ipf_trap0_1); *t++ = 0x2; /* Integer */ n = writeint(t + 1, IPFILTER_VERSION); *t = n; t += n + 1; len = t - s - 1; writelength(s, len); s = t; *s++ = 0x30; if (msglen < 128) { if (msglen + 1 + 1 + sizeof(ipf_trap0_2) >= 128) trapmsglen = 2; else trapmsglen = 1; } else { if (msglen + 2 + 1 + sizeof(ipf_trap0_2) >= 128) trapmsglen = 2; else trapmsglen = 1; } t = s + trapmsglen; bcopy(ipf_trap0_2, t, sizeof(ipf_trap0_2)); t += sizeof(ipf_trap0_2); *t++ = 0x4; /* Octet string */ n = writelength(t, msglen); t += n; bcopy(msg, t, msglen); t += msglen; len = t - s - trapmsglen; writelength(s, len); len = t - varlen - varlensz; writelength(varlen, len); /* pdu length */ len = t - pdulen - pdulensz; writelength(pdulen, len); /* pdu length */ len = t - buffer - baselensz - 1; writelength(buffer + 1, len); /* length of trap */ return t - buffer; } int -sendtrap_v2_0(fd, community, msg, msglen) - int fd; - char *community, *msg; - int msglen; +sendtrap_v2_0(int fd, char *community, char *msg, int msglen) { u_char buffer[1500]; int n; n = maketrap_v2(community, buffer, sizeof(buffer), (u_char *)msg, msglen); if (n > 0) { return send(fd, buffer, n, 0); } return 0; } diff --git a/sbin/ipf/libipf/tcp_flags.c b/sbin/ipf/libipf/tcp_flags.c index 0b602e66ab30..9dfe96d17fe8 100644 --- a/sbin/ipf/libipf/tcp_flags.c +++ b/sbin/ipf/libipf/tcp_flags.c @@ -1,50 +1,47 @@ /* $FreeBSD$ */ /* * Copyright (C) 2000-2004 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id: tcp_flags.c,v 1.8.2.1 2006/06/16 17:21:17 darrenr Exp $ */ #include "ipf.h" extern char flagset[]; extern u_char flags[]; -u_char tcp_flags(flgs, mask, linenum) -char *flgs; -u_char *mask; -int linenum; +u_char tcp_flags(char *flgs, u_char *mask, int linenum) { u_char tcpf = 0, tcpfm = 0; char *s; s = strchr(flgs, '/'); if (s) *s++ = '\0'; if (*flgs == '0') { tcpf = strtol(flgs, NULL, 0); } else { tcpf = tcpflags(flgs); } if (s != NULL) { if (*s == '0') tcpfm = strtol(s, NULL, 0); else tcpfm = tcpflags(s); } if (!tcpfm) { if (tcpf == TH_SYN) tcpfm = 0xff & ~(TH_ECN|TH_CWR); else tcpfm = 0xff & ~(TH_ECN); } *mask = tcpfm; return tcpf; } diff --git a/sbin/ipf/libipf/tcpflags.c b/sbin/ipf/libipf/tcpflags.c index feb3e8af04ac..86f7631abf80 100644 --- a/sbin/ipf/libipf/tcpflags.c +++ b/sbin/ipf/libipf/tcpflags.c @@ -1,45 +1,44 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" /* * ECN is a new addition to TCP - RFC 2481 */ #ifndef TH_ECN # define TH_ECN 0x40 #endif #ifndef TH_CWR # define TH_CWR 0x80 #endif extern char flagset[]; extern u_char flags[]; -u_char tcpflags(flgs) - char *flgs; +u_char tcpflags(char *flgs) { u_char tcpf = 0; char *s, *t; for (s = flgs; *s; s++) { if (*s == 'W') tcpf |= TH_CWR; else { if (!(t = strchr(flagset, *s))) { return 0; } tcpf |= flags[t - flagset]; } } return tcpf; } diff --git a/sbin/ipf/libipf/v6optvalue.c b/sbin/ipf/libipf/v6optvalue.c index a6eff9221256..39757bc849b1 100644 --- a/sbin/ipf/libipf/v6optvalue.c +++ b/sbin/ipf/libipf/v6optvalue.c @@ -1,39 +1,37 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include "ipf.h" -u_32_t getv6optbyname(optname) - char *optname; +u_32_t getv6optbyname(char *optname) { #ifdef USE_INET6 struct ipopt_names *io; for (io = v6ionames; io->on_name; io++) if (!strcasecmp(optname, io->on_name)) return io->on_bit; #endif return -1; } -u_32_t getv6optbyvalue(optval) - int optval; +u_32_t getv6optbyvalue(int optval) { #ifdef USE_INET6 struct ipopt_names *io; for (io = v6ionames; io->on_name; io++) if (io->on_value == optval) return io->on_bit; #endif return -1; } diff --git a/sbin/ipf/libipf/var.c b/sbin/ipf/libipf/var.c index 22d5b2ac1b1a..d864117e5df9 100644 --- a/sbin/ipf/libipf/var.c +++ b/sbin/ipf/libipf/var.c @@ -1,179 +1,173 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #include #include "ipf.h" typedef struct variable { struct variable *v_next; char *v_name; char *v_value; } variable_t; static variable_t *vtop = NULL; static variable_t *find_var(char *); static char *expand_string(char *, int); static variable_t *find_var(name) char *name; { variable_t *v; for (v = vtop; v != NULL; v = v->v_next) if (!strcmp(name, v->v_name)) return v; return NULL; } -char *get_variable(string, after, line) - char *string, **after; - int line; +char *get_variable(char *string, char **after, int line) { char c, *s, *t, *value; variable_t *v; s = string; if (*s == '{') { s++; for (t = s; *t != '\0'; t++) if (*t == '}') break; if (*t == '\0') { fprintf(stderr, "%d: { without }\n", line); return NULL; } } else if (ISALPHA(*s)) { for (t = s + 1; *t != '\0'; t++) if (!ISALPHA(*t) && !ISDIGIT(*t) && (*t != '_')) break; } else { fprintf(stderr, "%d: variables cannot start with '%c'\n", line, *s); return NULL; } if (after != NULL) *after = t; c = *t; *t = '\0'; v = find_var(s); *t = c; if (v == NULL) { fprintf(stderr, "%d: unknown variable '%s'\n", line, s); return NULL; } s = strdup(v->v_value); value = expand_string(s, line); if (value != s) free(s); return value; } -static char *expand_string(oldstring, line) - char *oldstring; - int line; +static char *expand_string(char *oldstring, int line) { char c, *s, *p1, *p2, *p3, *newstring, *value; int len; p3 = NULL; newstring = oldstring; for (s = oldstring; *s != '\0'; s++) if (*s == '$') { *s = '\0'; s++; switch (*s) { case '$' : bcopy(s, s - 1, strlen(s)); break; default : c = *s; if (c == '\0') return newstring; value = get_variable(s, &p3, line); if (value == NULL) return NULL; p2 = expand_string(value, line); if (p2 == NULL) return NULL; len = strlen(newstring) + strlen(p2); if (p3 != NULL) { if (c == '{' && *p3 == '}') p3++; len += strlen(p3); } p1 = malloc(len + 1); if (p1 == NULL) return NULL; *(s - 1) = '\0'; strcpy(p1, newstring); strcat(p1, p2); if (p3 != NULL) strcat(p1, p3); s = p1 + len - strlen(p3) - 1; if (newstring != oldstring) free(newstring); newstring = p1; break; } } return newstring; } -void set_variable(name, value) - char *name; - char *value; +void set_variable(char *name, char *value) { variable_t *v; int len; if (name == NULL || value == NULL || *name == '\0') return; v = find_var(name); if (v != NULL) { free(v->v_value); v->v_value = strdup(value); return; } len = strlen(value); if ((*value == '"' && value[len - 1] == '"') || (*value == '\'' && value[len - 1] == '\'')) { value[len - 1] = '\0'; value++; len -=2; } v = (variable_t *)malloc(sizeof(*v)); if (v == NULL) return; v->v_name = strdup(name); v->v_value = strdup(value); v->v_next = vtop; vtop = v; } diff --git a/sbin/ipf/libipf/vtof.c b/sbin/ipf/libipf/vtof.c index fd1a98432aa8..2d624ac64d45 100644 --- a/sbin/ipf/libipf/vtof.c +++ b/sbin/ipf/libipf/vtof.c @@ -1,16 +1,15 @@ #include "ipf.h" int -vtof(version) - int version; +vtof(int version) { #ifdef USE_INET6 if (version == 6) return AF_INET6; #endif if (version == 4) return AF_INET; if (version == 0) return AF_UNSPEC; return -1; } diff --git a/share/examples/ipfilter/l4check/l4check.c b/share/examples/ipfilter/l4check/l4check.c index 014446dc6007..961eeab934fd 100644 --- a/share/examples/ipfilter/l4check/l4check.c +++ b/share/examples/ipfilter/l4check/l4check.c @@ -1,807 +1,801 @@ /* $FreeBSD$ */ /* * (C)Copyright (C) 2012 by Darren Reed. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ip_compat.h" #include "ip_fil.h" #include "ip_nat.h" #include "ipf.h" extern char *optarg; typedef struct l4cfg { struct l4cfg *l4_next; struct ipnat l4_nat; /* NAT rule */ struct sockaddr_in l4_sin; /* remote socket to connect */ time_t l4_last; /* when we last connected */ int l4_alive; /* 1 = remote alive */ int l4_fd; int l4_rw; /* 0 = reading, 1 = writing */ char *l4_rbuf; /* read buffer */ int l4_rsize; /* size of buffer */ int l4_rlen; /* how much used */ char *l4_wptr; /* next byte to write */ int l4_wlen; /* length yet to be written */ } l4cfg_t; l4cfg_t *l4list = NULL; char *response = NULL; char *probe = NULL; l4cfg_t template; int frequency = 20; int ctimeout = 1; int rtimeout = 1; size_t plen = 0; size_t rlen = 0; int natfd = -1; int opts = 0; #if defined(sun) && !defined(__svr4__) && !defined(__SVR4) # define strerror(x) sys_errlist[x] #endif -char *copystr(dst, src) - char *dst, *src; +char * +copystr(char *dst, char *src) { register char *s, *t, c; register int esc = 0; for (s = src, t = dst; s && t && (c = *s++); ) if (esc) { esc = 0; switch (c) { case 'n' : *t++ = '\n'; break; case 'r' : *t++ = '\r'; break; case 't' : *t++ = '\t'; break; } } else if (c != '\\') *t++ = c; else esc = 1; *t = '\0'; return dst; } -void addnat(l4) - l4cfg_t *l4; +void +addnat(l4cfg_t *l4) { ipnat_t *ipn = &l4->l4_nat; printf("Add NAT rule for %s/%#x,%u -> ", inet_ntoa(ipn->in_out[0]), ipn->in_outmsk, ntohs(ipn->in_pmin)); printf("%s,%u\n", inet_ntoa(ipn->in_in[0]), ntohs(ipn->in_pnext)); if (!(opts & OPT_DONOTHING)) { if (ioctl(natfd, SIOCADNAT, &ipn) == -1) perror("ioctl(SIOCADNAT)"); } } -void delnat(l4) - l4cfg_t *l4; +void +delnat(l4cfg_t *l4) { ipnat_t *ipn = &l4->l4_nat; printf("Remove NAT rule for %s/%#x,%u -> ", inet_ntoa(ipn->in_out[0]), ipn->in_outmsk, ipn->in_pmin); printf("%s,%u\n", inet_ntoa(ipn->in_in[0]), ipn->in_pnext); if (!(opts & OPT_DONOTHING)) { if (ioctl(natfd, SIOCRMNAT, &ipn) == -1) perror("ioctl(SIOCRMNAT)"); } } -void connectl4(l4) - l4cfg_t *l4; +void +connectl4(l4cfg_t *l4) { l4->l4_rw = 1; l4->l4_rlen = 0; l4->l4_wlen = plen; if (!l4->l4_wlen) { l4->l4_alive = 1; addnat(l4); } else l4->l4_wptr = probe; } -void closel4(l4, dead) - l4cfg_t *l4; - int dead; +void +closel4(l4cfg_t *l4, int dead) { close(l4->l4_fd); l4->l4_fd = -1; l4->l4_rw = -1; if (dead && l4->l4_alive) { l4->l4_alive = 0; delnat(l4); } } -void connectfd(l4) - l4cfg_t *l4; +void +connectfd(l4cfg_t *l4) { if (connect(l4->l4_fd, (struct sockaddr *)&l4->l4_sin, sizeof(l4->l4_sin)) == -1) { if (errno == EISCONN) { if (opts & OPT_VERBOSE) fprintf(stderr, "Connected fd %d\n", l4->l4_fd); connectl4(l4); return; } if (opts & OPT_VERBOSE) fprintf(stderr, "Connect failed fd %d: %s\n", l4->l4_fd, strerror(errno)); closel4(l4, 1); return; } l4->l4_rw = 1; } -void writefd(l4) - l4cfg_t *l4; +void +writefd(l4cfg_t *l4) { char buf[80], *ptr; int n, i, fd; fd = l4->l4_fd; if (l4->l4_rw == -2) { connectfd(l4); return; } n = l4->l4_wlen; i = send(fd, l4->l4_wptr, n, 0); if (i == 0 || i == -1) { if (opts & OPT_VERBOSE) fprintf(stderr, "Send on fd %d failed: %s\n", fd, strerror(errno)); closel4(l4, 1); } else { l4->l4_wptr += i; l4->l4_wlen -= i; if (l4->l4_wlen == 0) l4->l4_rw = 0; if (opts & OPT_VERBOSE) fprintf(stderr, "Sent %d bytes to fd %d\n", i, fd); } } -void readfd(l4) - l4cfg_t *l4; +void readfd(l4cfg_t *l4) { char buf[80], *ptr; int n, i, fd; fd = l4->l4_fd; if (l4->l4_rw == -2) { connectfd(l4); return; } if (l4->l4_rsize) { n = l4->l4_rsize - l4->l4_rlen; ptr = l4->l4_rbuf + l4->l4_rlen; } else { n = sizeof(buf) - 1; ptr = buf; } if (opts & OPT_VERBOSE) fprintf(stderr, "Read %d bytes on fd %d to %p\n", n, fd, ptr); i = recv(fd, ptr, n, 0); if (i == 0 || i == -1) { if (opts & OPT_VERBOSE) fprintf(stderr, "Read error on fd %d: %s\n", fd, (i == 0) ? "EOF" : strerror(errno)); closel4(l4, 1); } else { if (ptr == buf) ptr[i] = '\0'; if (opts & OPT_VERBOSE) fprintf(stderr, "%d: Read %d bytes [%*.*s]\n", fd, i, i, i, ptr); if (ptr != buf) { l4->l4_rlen += i; if (l4->l4_rlen >= l4->l4_rsize) { if (!strncmp(response, l4->l4_rbuf, l4->l4_rsize)) { printf("%d: Good response\n", fd); if (!l4->l4_alive) { l4->l4_alive = 1; addnat(l4); } closel4(l4, 0); } else { if (opts & OPT_VERBOSE) printf("%d: Bad response\n", fd); closel4(l4, 1); } } } else if (!l4->l4_alive) { l4->l4_alive = 1; addnat(l4); closel4(l4, 0); } } } -int runconfig() +int +runconfig(void) { int fd, opt, res, mfd, i; struct timeval tv; time_t now, now1; fd_set rfd, wfd; l4cfg_t *l4; mfd = 0; opt = 1; now = time(NULL); /* * First, initiate connections that are closed, as required. */ for (l4 = l4list; l4; l4 = l4->l4_next) { if ((l4->l4_last + frequency < now) && (l4->l4_fd == -1)) { l4->l4_last = now; fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) continue; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); #ifdef O_NONBLOCK if ((res = fcntl(fd, F_GETFL, 0)) != -1) fcntl(fd, F_SETFL, res | O_NONBLOCK); #endif if (opts & OPT_VERBOSE) fprintf(stderr, "Connecting to %s,%d (fd %d)...", inet_ntoa(l4->l4_sin.sin_addr), ntohs(l4->l4_sin.sin_port), fd); if (connect(fd, (struct sockaddr *)&l4->l4_sin, sizeof(l4->l4_sin)) == -1) { if (errno != EINPROGRESS) { if (opts & OPT_VERBOSE) fprintf(stderr, "failed\n"); perror("connect"); close(fd); fd = -1; } else { if (opts & OPT_VERBOSE) fprintf(stderr, "waiting\n"); l4->l4_rw = -2; } } else { if (opts & OPT_VERBOSE) fprintf(stderr, "connected\n"); connectl4(l4); } l4->l4_fd = fd; } } /* * Now look for fd's which we're expecting to read/write from. */ FD_ZERO(&rfd); FD_ZERO(&wfd); tv.tv_sec = MIN(rtimeout, ctimeout); tv.tv_usec = 0; for (l4 = l4list; l4; l4 = l4->l4_next) if (l4->l4_rw == 0) { if (now - l4->l4_last > rtimeout) { if (opts & OPT_VERBOSE) fprintf(stderr, "%d: Read timeout\n", l4->l4_fd); closel4(l4, 1); continue; } if (opts & OPT_VERBOSE) fprintf(stderr, "Wait for read on fd %d\n", l4->l4_fd); FD_SET(l4->l4_fd, &rfd); if (l4->l4_fd > mfd) mfd = l4->l4_fd; } else if ((l4->l4_rw == 1 && l4->l4_wlen) || l4->l4_rw == -2) { if ((l4->l4_rw == -2) && (now - l4->l4_last > ctimeout)) { if (opts & OPT_VERBOSE) fprintf(stderr, "%d: connect timeout\n", l4->l4_fd); closel4(l4); continue; } if (opts & OPT_VERBOSE) fprintf(stderr, "Wait for write on fd %d\n", l4->l4_fd); FD_SET(l4->l4_fd, &wfd); if (l4->l4_fd > mfd) mfd = l4->l4_fd; } if (opts & OPT_VERBOSE) fprintf(stderr, "Select: max fd %d wait %d\n", mfd + 1, tv.tv_sec); i = select(mfd + 1, &rfd, &wfd, NULL, &tv); if (i == -1) { perror("select"); return -1; } now1 = time(NULL); for (l4 = l4list; (i > 0) && l4; l4 = l4->l4_next) { if (l4->l4_fd < 0) continue; if (FD_ISSET(l4->l4_fd, &rfd)) { if (opts & OPT_VERBOSE) fprintf(stderr, "Ready to read on fd %d\n", l4->l4_fd); readfd(l4); i--; } if ((l4->l4_fd >= 0) && FD_ISSET(l4->l4_fd, &wfd)) { if (opts & OPT_VERBOSE) fprintf(stderr, "Ready to write on fd %d\n", l4->l4_fd); writefd(l4); i--; } } return 0; } -int gethostport(str, lnum, ipp, portp) - char *str; - int lnum; - u_32_t *ipp; - u_short *portp; +int +gethostport(char *str, int lnum, u_32_t *ipp, u_short *portp) { struct servent *sp; struct hostent *hp; char *host, *port; struct in_addr ip; host = str; port = strchr(host, ','); if (port) *port++ = '\0'; #ifdef HAVE_INET_ATON if (ISDIGIT(*host) && inet_aton(host, &ip)) *ipp = ip.s_addr; #else if (ISDIGIT(*host)) *ipp = inet_addr(host); #endif else { if (!(hp = gethostbyname(host))) { fprintf(stderr, "%d: can't resolve hostname: %s\n", lnum, host); return 0; } *ipp = *(u_32_t *)hp->h_addr; } if (port) { if (ISDIGIT(*port)) *portp = htons(atoi(port)); else { sp = getservbyname(port, "tcp"); if (sp) *portp = sp->s_port; else { fprintf(stderr, "%d: unknown service %s\n", lnum, port); return 0; } } } else *portp = 0; return 1; } -char *mapfile(file, sizep) - char *file; - size_t *sizep; +char * +mapfile(char *file, size_t *sizep) { struct stat sb; caddr_t addr; int fd; fd = open(file, O_RDONLY); if (fd == -1) { perror("open(mapfile)"); return NULL; } if (fstat(fd, &sb) == -1) { perror("fstat(mapfile)"); close(fd); return NULL; } addr = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); if (addr == (caddr_t)-1) { perror("mmap(mapfile)"); close(fd); return NULL; } close(fd); *sizep = sb.st_size; return (char *)addr; } -int readconfig(filename) - char *filename; +int +readconfig(char *filename) { char c, buf[512], *s, *t, *errtxt = NULL, *line; int num, err = 0; ipnat_t *ipn; l4cfg_t *l4; FILE *fp; fp = fopen(filename, "r"); if (!fp) { perror("open(configfile)"); return -1; } bzero((char *)&template, sizeof(template)); template.l4_fd = -1; template.l4_rw = -1; template.l4_sin.sin_family = AF_INET; ipn = &template.l4_nat; ipn->in_flags = IPN_TCP|IPN_ROUNDR; ipn->in_redir = NAT_REDIRECT; for (num = 1; fgets(buf, sizeof(buf), fp); num++) { s = strchr(buf, '\n'); if (!s) { fprintf(stderr, "%d: line too long\n", num); fclose(fp); return -1; } *s = '\0'; /* * lines which are comments */ s = strchr(buf, '#'); if (s) *s = '\0'; /* * Skip leading whitespace */ for (line = buf; (c = *line) && ISSPACE(c); line++) ; if (!*line) continue; if (opts & OPT_VERBOSE) fprintf(stderr, "Parsing: [%s]\n", line); t = strtok(line, " \t"); if (!t) continue; if (!strcasecmp(t, "interface")) { s = strtok(NULL, " \t"); if (s) t = strtok(NULL, "\t"); if (!s || !t) { errtxt = line; err = -1; break; } if (!strchr(t, ',')) { fprintf(stderr, "%d: local address,port missing\n", num); err = -1; break; } strncpy(ipn->in_ifname, s, sizeof(ipn->in_ifname)); if (!gethostport(t, num, &ipn->in_outip, &ipn->in_pmin)) { errtxt = line; err = -1; break; } ipn->in_outmsk = 0xffffffff; ipn->in_pmax = ipn->in_pmin; if (opts & OPT_VERBOSE) fprintf(stderr, "Interface %s %s/%#x port %u\n", ipn->in_ifname, inet_ntoa(ipn->in_out[0]), ipn->in_outmsk, ipn->in_pmin); } else if (!strcasecmp(t, "remote")) { if (!*ipn->in_ifname) { fprintf(stderr, "%d: ifname not set prior to remote\n", num); err = -1; break; } s = strtok(NULL, " \t"); if (s) t = strtok(NULL, ""); if (!s || !t || strcasecmp(s, "server")) { errtxt = line; err = -1; break; } ipn->in_pnext = 0; if (!gethostport(t, num, &ipn->in_inip, &ipn->in_pnext)) { errtxt = line; err = -1; break; } ipn->in_inmsk = 0xffffffff; if (ipn->in_pnext == 0) ipn->in_pnext = ipn->in_pmin; l4 = (l4cfg_t *)malloc(sizeof(*l4)); if (!l4) { fprintf(stderr, "%d: out of memory (%d)\n", num, sizeof(*l4)); err = -1; break; } bcopy((char *)&template, (char *)l4, sizeof(*l4)); l4->l4_sin.sin_addr = ipn->in_in[0]; l4->l4_sin.sin_port = ipn->in_pnext; l4->l4_next = l4list; l4list = l4; } else if (!strcasecmp(t, "connect")) { s = strtok(NULL, " \t"); if (s) t = strtok(NULL, "\t"); if (!s || !t) { errtxt = line; err = -1; break; } else if (!strcasecmp(s, "timeout")) { ctimeout = atoi(t); if (opts & OPT_VERBOSE) fprintf(stderr, "connect timeout %d\n", ctimeout); } else if (!strcasecmp(s, "frequency")) { frequency = atoi(t); if (opts & OPT_VERBOSE) fprintf(stderr, "connect frequency %d\n", frequency); } else { errtxt = line; err = -1; break; } } else if (!strcasecmp(t, "probe")) { s = strtok(NULL, " \t"); if (!s) { errtxt = line; err = -1; break; } else if (!strcasecmp(s, "string")) { if (probe) { fprintf(stderr, "%d: probe already set\n", num); err = -1; break; } t = strtok(NULL, ""); if (!t) { fprintf(stderr, "%d: No probe string\n", num); err = -1; break; } probe = malloc(strlen(t)); copystr(probe, t); plen = strlen(probe); if (opts & OPT_VERBOSE) fprintf(stderr, "Probe string [%s]\n", probe); } else if (!strcasecmp(s, "file")) { t = strtok(NULL, " \t"); if (!t) { errtxt = line; err = -1; break; } if (probe) { fprintf(stderr, "%d: probe already set\n", num); err = -1; break; } probe = mapfile(t, &plen); if (opts & OPT_VERBOSE) fprintf(stderr, "Probe file %s len %u@%p\n", t, plen, probe); } } else if (!strcasecmp(t, "response")) { s = strtok(NULL, " \t"); if (!s) { errtxt = line; err = -1; break; } else if (!strcasecmp(s, "timeout")) { t = strtok(NULL, " \t"); if (!t) { errtxt = line; err = -1; break; } rtimeout = atoi(t); if (opts & OPT_VERBOSE) fprintf(stderr, "response timeout %d\n", rtimeout); } else if (!strcasecmp(s, "string")) { if (response) { fprintf(stderr, "%d: response already set\n", num); err = -1; break; } response = strdup(strtok(NULL, "")); rlen = strlen(response); template.l4_rsize = rlen; template.l4_rbuf = malloc(rlen); if (opts & OPT_VERBOSE) fprintf(stderr, "Response string [%s]\n", response); } else if (!strcasecmp(s, "file")) { t = strtok(NULL, " \t"); if (!t) { errtxt = line; err = -1; break; } if (response) { fprintf(stderr, "%d: response already set\n", num); err = -1; break; } response = mapfile(t, &rlen); template.l4_rsize = rlen; template.l4_rbuf = malloc(rlen); if (opts & OPT_VERBOSE) fprintf(stderr, "Response file %s len %u@%p\n", t, rlen, response); } } else { errtxt = line; err = -1; break; } } if (errtxt) fprintf(stderr, "%d: syntax error at \"%s\"\n", num, errtxt); fclose(fp); return err; } -void usage(prog) - char *prog; +void +usage(char *prog) { fprintf(stderr, "Usage: %s -f \n", prog); exit(1); } -int main(argc, argv) - int argc; - char *argv[]; +int +main(int argc, char *argv[]) { char *config = NULL; int c; while ((c = getopt(argc, argv, "f:nv")) != -1) switch (c) { case 'f' : config = optarg; break; case 'n' : opts |= OPT_DONOTHING; break; case 'v' : opts |= OPT_VERBOSE; break; } if (config == NULL) usage(argv[0]); if (readconfig(config)) exit(1); if (!l4list) { fprintf(stderr, "No remote servers, exiting."); exit(1); } if (!(opts & OPT_DONOTHING)) { natfd = open(IPL_NAT, O_RDWR); if (natfd == -1) { perror("open(IPL_NAT)"); exit(1); } } if (opts & OPT_VERBOSE) fprintf(stderr, "Starting...\n"); while (runconfig() == 0) ; }