diff options
-rw-r--r-- | sbin/ipfw/ipfw.8 | 14 | ||||
-rw-r--r-- | sbin/ipfw/ipfw.c | 99 | ||||
-rw-r--r-- | sys/netinet/ip_fw.c | 12 | ||||
-rw-r--r-- | sys/netinet/ip_fw.h | 5 |
4 files changed, 89 insertions, 41 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8 index 765fb3d..a64f290 100644 --- a/sbin/ipfw/ipfw.8 +++ b/sbin/ipfw/ipfw.8 @@ -478,9 +478,23 @@ or .Cm all keywords mean any protocol will match. .It Ar src No and Ar dst : +.Cm any +| +.Cm me +| +.Op Cm not .Aq Ar address Ns / Ns Ar mask .Op Ar ports .Pp +Specifying +.Cm any +makes the rule match any IP number. +.Pp +Specifying +.Cm me +makes the rule match any IP number configured on an interface in the system. +This is an computationally semi-expensive check which should be used with care. +.Pp The .Aq Ar address Ns / Ns Ar mask may be specified as: diff --git a/sbin/ipfw/ipfw.c b/sbin/ipfw/ipfw.c index d8f4934..247b7a5 100644 --- a/sbin/ipfw/ipfw.c +++ b/sbin/ipfw/ipfw.c @@ -276,17 +276,20 @@ show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth) else printf(" %u", chain->fw_prot); - printf(" from %s", chain->fw_flg & IP_FW_F_INVSRC ? "not " : ""); - - adrt=ntohl(chain->fw_smsk.s_addr); - if (adrt==ULONG_MAX && do_resolv) { - adrt=(chain->fw_src.s_addr); - he=gethostbyaddr((char *)&adrt,sizeof(u_long),AF_INET); - if (he==NULL) { - printf(inet_ntoa(chain->fw_src)); - } else - printf("%s",he->h_name); - } else { + if (chain->fw_flg & IP_FW_F_SME) { + printf(" from me"); + } else { + printf(" from %s", chain->fw_flg & IP_FW_F_INVSRC ? "not " : ""); + + adrt=ntohl(chain->fw_smsk.s_addr); + if (adrt==ULONG_MAX && do_resolv) { + adrt=(chain->fw_src.s_addr); + he=gethostbyaddr((char *)&adrt,sizeof(u_long),AF_INET); + if (he==NULL) { + printf(inet_ntoa(chain->fw_src)); + } else + printf("%s",he->h_name); + } else { if (adrt!=ULONG_MAX) { mb=mask_bits(chain->fw_smsk); if (mb == 0) { @@ -303,6 +306,7 @@ show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth) } } else printf(inet_ntoa(chain->fw_src)); + } } if (chain->fw_prot == IPPROTO_TCP || chain->fw_prot == IPPROTO_UDP) { @@ -318,33 +322,37 @@ show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth) } } - printf(" to %s", chain->fw_flg & IP_FW_F_INVDST ? "not " : ""); - - adrt=ntohl(chain->fw_dmsk.s_addr); - if (adrt==ULONG_MAX && do_resolv) { - adrt=(chain->fw_dst.s_addr); - he=gethostbyaddr((char *)&adrt,sizeof(u_long),AF_INET); - if (he==NULL) { - printf(inet_ntoa(chain->fw_dst)); - } else - printf("%s",he->h_name); - } else { - if (adrt!=ULONG_MAX) { - mb=mask_bits(chain->fw_dmsk); - if (mb == 0) { - printf("any"); - } else { - if (mb > 0) { - printf(inet_ntoa(chain->fw_dst)); - printf("/%d",mb); + if (chain->fw_flg & IP_FW_F_DME) { + printf(" to me"); + } else { + printf(" to %s", chain->fw_flg & IP_FW_F_INVDST ? "not " : ""); + + adrt=ntohl(chain->fw_dmsk.s_addr); + if (adrt==ULONG_MAX && do_resolv) { + adrt=(chain->fw_dst.s_addr); + he=gethostbyaddr((char *)&adrt,sizeof(u_long),AF_INET); + if (he==NULL) { + printf(inet_ntoa(chain->fw_dst)); + } else + printf("%s",he->h_name); + } else { + if (adrt!=ULONG_MAX) { + mb=mask_bits(chain->fw_dmsk); + if (mb == 0) { + printf("any"); } else { - printf(inet_ntoa(chain->fw_dst)); - printf(":"); - printf(inet_ntoa(chain->fw_dmsk)); + if (mb > 0) { + printf(inet_ntoa(chain->fw_dst)); + printf("/%d",mb); + } else { + printf(inet_ntoa(chain->fw_dst)); + printf(":"); + printf(inet_ntoa(chain->fw_dmsk)); + } } - } - } else - printf(inet_ntoa(chain->fw_dst)); + } else + printf(inet_ntoa(chain->fw_dst)); + } } if (chain->fw_prot == IPPROTO_TCP || chain->fw_prot == IPPROTO_UDP) { @@ -857,8 +865,8 @@ show_usage(const char *fmt, ...) " reset|count|skipto num|divert port|tee port|fwd ip|\n" " pipe num} [log [logamount count]]\n" " proto: {ip|tcp|udp|icmp|<number>}\n" -" src: from [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n" -" dst: to [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n" +" src: from [not] {me|any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n" +" dst: to [not] {me|any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n" " extras:\n" " uid {user id}\n" " gid {group id}\n" @@ -1792,7 +1800,12 @@ add(ac,av) if (!ac) show_usage("missing arguments"); - fill_ip(&rule.fw_src, &rule.fw_smsk, &ac, &av); + if (ac && !strncmp(*av,"me",strlen(*av))) { + rule.fw_flg |= IP_FW_F_SME; + av++; ac--; + } else { + fill_ip(&rule.fw_src, &rule.fw_smsk, &ac, &av); + } if (ac && (isdigit(**av) || lookup_port(*av, rule.fw_prot, 1, 1) >= 0)) { u_short nports = 0; @@ -1819,7 +1832,13 @@ add(ac,av) if (!ac) show_usage("missing arguments"); - fill_ip(&rule.fw_dst, &rule.fw_dmsk, &ac, &av); + + if (ac && !strncmp(*av,"me",strlen(*av))) { + rule.fw_flg |= IP_FW_F_DME; + av++; ac--; + } else { + fill_ip(&rule.fw_dst, &rule.fw_dmsk, &ac, &av); + } if (ac && (isdigit(**av) || lookup_port(*av, rule.fw_prot, 1, 1) >= 0)) { u_short nports = 0; diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c index 66dc6f1..8a53b1f 100644 --- a/sys/netinet/ip_fw.c +++ b/sys/netinet/ip_fw.c @@ -47,6 +47,7 @@ #include <net/route.h> #include <netinet/in.h> #include <netinet/in_systm.h> +#include <netinet/in_var.h> #include <netinet/in_pcb.h> #include <netinet/ip.h> #include <netinet/ip_var.h> @@ -947,6 +948,7 @@ ip_fw_chk(struct ip **pip, int hlen, struct ip_fw *f = NULL, *rule = NULL; struct ip *ip = *pip; struct ifnet *const rif = (*m)->m_pkthdr.rcvif; + struct ifnet *tif; u_short offset = 0 ; u_short src_port = 0, dst_port = 0; struct in_addr src_ip, dst_ip; /* XXX */ @@ -1111,6 +1113,16 @@ again: if ((f->fw_flg & IP_FW_F_FRAG) && offset == 0 ) continue; + if (f->fw_flg & IP_FW_F_SME) { + INADDR_TO_IFP(src_ip, tif); + if (tif == NULL) + continue; + } + if (f->fw_flg & IP_FW_F_DME) { + INADDR_TO_IFP(dst_ip, tif); + if (tif == NULL) + continue; + } /* If src-addr doesn't match, not this rule. */ if (((f->fw_flg & IP_FW_F_INVSRC) != 0) ^ ((src_ip.s_addr & f->fw_smsk.s_addr) != f->fw_src.s_addr)) diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h index 81da17a..7abae15 100644 --- a/sys/netinet/ip_fw.h +++ b/sys/netinet/ip_fw.h @@ -212,7 +212,10 @@ struct ipfw_dyn_rule { #define IP_FW_F_KEEP_S 0x08000000 /* keep state */ #define IP_FW_F_CHECK_S 0x10000000 /* check state */ -#define IP_FW_F_MASK 0x1FFFFFFF /* All possible flag bits mask */ +#define IP_FW_F_SME 0x20000000 /* source = me */ +#define IP_FW_F_DME 0x40000000 /* destination = me */ + +#define IP_FW_F_MASK 0x7FFFFFFF /* All possible flag bits mask */ /* * Flags for the 'fw_ipflg' field, for comparing values of ip and its protocols. |