summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorugen <ugen@FreeBSD.org>1995-02-24 14:33:54 +0000
committerugen <ugen@FreeBSD.org>1995-02-24 14:33:54 +0000
commit7ef3525e292051d370231bb339a622b2fe6eee0b (patch)
tree2ff826498b35f62a5d2e57739f274fb810473e22 /sys/netinet
parent378d96702e47d30d34f67b986b2d20bda838e9cd (diff)
downloadFreeBSD-src-7ef3525e292051d370231bb339a622b2fe6eee0b.zip
FreeBSD-src-7ef3525e292051d370231bb339a622b2fe6eee0b.tar.gz
Allow "via" to be specified ever as IP adress or
as interface name/unit...
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_fw.c149
-rw-r--r--sys/netinet/ip_fw.h26
2 files changed, 110 insertions, 65 deletions
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index 38e5695..d23262a 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -182,42 +182,41 @@ struct ip_fw *chain;
for (f=chain;f;f=f->fw_next)
- if ((src.s_addr&f->fw_smsk.s_addr)==f->fw_src.s_addr
- && (dst.s_addr&f->fw_dmsk.s_addr)==f->fw_dst.s_addr) {
- if (f->fw_via.s_addr && rif) {
- for (ia_p=ia;ia_p;ia_p=ia_p->ifa_next) {
- if (!ia_p->ifa_addr ||
- ia_p->ifa_addr->sa_family!=AF_INET)
- /*
- * Next interface adress.
- * This is continue for
- * local "for"
- */
- continue;
- ia_i.s_addr=(((struct sockaddr_in *)\
- (ia_p->ifa_addr))->sin_addr.s_addr);
- if (ia_i.s_addr==f->fw_via.s_addr)
- goto via_match;
- }
- /*
- * Next interface adress.
- * This is continue for
- * local "for"
- */
- continue;
- } else {
- /*
- * No special "via" adress set
- * or interface from which packet
- * came unknown so match anyway
- */
- goto via_match;
+ if ((src.s_addr&f->fw_smsk.s_addr)==f->fw_src.s_addr
+ && (dst.s_addr&f->fw_dmsk.s_addr)==f->fw_dst.s_addr) {
+
+ if (!rif)
+ goto via_match;
+
+ if (f->fw_flg&IP_FW_F_IFNAME) {
+
+ if (!f->fw_via_name[0])
+ goto via_match; /* No name/unit set,match any */
+
+ if (rif->if_unit==f->fw_via_unit &&
+ !strncmp(rif->if_name,f->fw_via_name,FW_IFNLEN))
+ goto via_match;
+ } else {
+
+ if (!f->fw_via_ip.s_addr)
+ goto via_match; /* No via ip set,match any */
+
+ for (ia_p=ia;ia_p;ia_p=ia_p->ifa_next) {
+ if (!ia_p->ifa_addr||ia_p->ifa_addr->sa_family!=AF_INET)
+ continue;
+
+ ia_i.s_addr=(((struct sockaddr_in *)\
+ (ia_p->ifa_addr))->sin_addr.s_addr);
+ if (ia_i.s_addr==f->fw_via_ip.s_addr)
+ goto via_match;
}
- /*
- * Skip to next firewall entry - via
- * address did not matched.
- */
- continue;
+
+ }
+ /*
+ * If we got here,no "via"'s matched,so
+ * we should continue to the next firewall entry.
+ */
+ continue;
via_match:
f_prt=f->fw_flg&IP_FW_F_KIND;
if (f_prt==IP_FW_F_ALL) {
@@ -396,34 +395,58 @@ int nh_conv;
}
for (f=chain;f;f=f->fw_next) {
- if ((src.s_addr&f->fw_smsk.s_addr)==f->fw_src.s_addr
- && (dst.s_addr&f->fw_dmsk.s_addr)==f->fw_dst.s_addr) {
- rev=0;
- goto addr_match;
- }
- if ((f->fw_flg&IP_FW_F_BIDIR) &&
- ((src.s_addr&f->fw_smsk.s_addr)==f->fw_dst.s_addr
- && (dst.s_addr&f->fw_dmsk.s_addr)==f->fw_src.s_addr)) {
- rev=1;
- goto addr_match;
- }
- continue;
+ if ((src.s_addr&f->fw_smsk.s_addr)==f->fw_src.s_addr
+ && (dst.s_addr&f->fw_dmsk.s_addr)==f->fw_dst.s_addr) {
+ rev=0;
+ goto addr_match;
+ }
+ if ((f->fw_flg&IP_FW_F_BIDIR) &&
+ ((src.s_addr&f->fw_smsk.s_addr)==f->fw_dst.s_addr
+ && (dst.s_addr&f->fw_dmsk.s_addr)==f->fw_src.s_addr)) {
+ rev=1;
+ goto addr_match;
+ }
+ continue;
addr_match:
- if (f->fw_via.s_addr && rif) {
- for (ia_p=ia;ia_p;ia_p=ia_p->ifa_next) {
- if (!ia_p->ifa_addr ||
- ia_p->ifa_addr->sa_family!=AF_INET)
- continue;
- ia_i.s_addr=(((struct sockaddr_in *)\
- (ia_p->ifa_addr))->sin_addr.s_addr);
- if (ia_i.s_addr==f->fw_via.s_addr)
- goto via_match;
- }
- continue;
- } else {
- goto via_match;
+ /*
+ * We use here same code for "via" matching
+ * as in firewall.This is wrong and does not do
+ * much use,because in most cases instead of interface
+ * passed NULL pointer.Need to be completely
+ * rewritten.
+ */
+ if (!rif)
+ goto via_match;
+
+ if (f->fw_flg&IP_FW_F_IFNAME) {
+
+ if (!f->fw_via_name[0])
+ goto via_match; /* No name/unit set,match any */
+
+ if (rif->if_unit==f->fw_via_unit &&
+ !strncmp(rif->if_name,f->fw_via_name,FW_IFNLEN))
+ goto via_match;
+ } else {
+
+ if (!f->fw_via_ip.s_addr)
+ goto via_match; /* No via ip set,match any */
+
+ for (ia_p=ia;ia_p;ia_p=ia_p->ifa_next) {
+ if (!ia_p->ifa_addr||ia_p->ifa_addr->sa_family!=AF_INET)
+ continue;
+
+ ia_i.s_addr=(((struct sockaddr_in *)\
+ (ia_p->ifa_addr))->sin_addr.s_addr);
+ if (ia_i.s_addr==f->fw_via_ip.s_addr)
+ goto via_match;
}
- continue;
+
+ }
+ /*
+ * If we got here,no "via"'s matched,so
+ * we should continue to the next firewall entry.
+ */
+ continue;
via_match:
f_prt=f->fw_flg&IP_FW_F_KIND;
if (f_prt==IP_FW_F_ALL) {
@@ -708,7 +731,7 @@ struct ip_fw *frwl;
|| ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr
|| ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr
|| ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr
- || ftmp->fw_via.s_addr!=frwl->fw_via.s_addr
+ || ftmp->fw_via_ip.s_addr!=frwl->fw_via_ip.s_addr
|| ftmp->fw_flg!=frwl->fw_flg)
matches=0;
tport1=ftmp->fw_nsp+ftmp->fw_ndp;
@@ -776,7 +799,7 @@ struct ip_fw *frwl;
|| ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr
|| ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr
|| ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr
- || ftmp->fw_via.s_addr!=frwl->fw_via.s_addr
+ || ftmp->fw_via_ip.s_addr!=frwl->fw_via_ip.s_addr
|| ftmp->fw_flg!=frwl->fw_flg)
matches=0;
tport1=ftmp->fw_nsp+ftmp->fw_ndp;
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index 132dc84..87ba0fb 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -26,7 +26,19 @@ struct ip_fw {
struct ip_fw *fw_next; /* Next firewall on chain */
struct in_addr fw_src, fw_dst; /* Source and destination IP addr */
struct in_addr fw_smsk, fw_dmsk; /* Mask for src and dest IP addr */
- struct in_addr fw_via; /* IP addr of interface "via" */
+ /*
+ * This union keeps all "via" information.
+ * If ever fu_via_ip is 0,or IP_FW_F_IFNAME set and
+ * fu_via_name[0] is 0 - match any packet.
+ */
+ union {
+ struct in_addr fu_via_ip;
+ struct {
+#define FW_IFNLEN 6 /* To keep structure on 2^x boundary */
+ char fu_via_name[FW_IFNLEN];
+ short fu_via_unit;
+ } fu_via_if;
+ } fu_via_un;
u_short fw_flg; /* Flags word */
u_short fw_nsp, fw_ndp; /* N'of src ports and # of dst ports */
/* in ports array (dst ports follow */
@@ -37,6 +49,15 @@ struct ip_fw {
u_long fw_pcnt,fw_bcnt; /* Packet and byte counters */
};
+
+/*
+ * Definitions to make expressions
+ * for "via" stuff shorter.
+ */
+#define fw_via_ip fu_via_un.fu_via_ip
+#define fw_via_name fu_via_un.fu_via_if.fu_via_name
+#define fw_via_unit fu_via_un.fu_via_if.fu_via_unit
+
/*
* Values for "flags" field .
*/
@@ -62,7 +83,8 @@ struct ip_fw {
#define IP_FW_F_BIDIR 0x040 /* For accounting-count two way */
#define IP_FW_F_TCPSYN 0x080 /* For tcp packets-check SYN only */
#define IP_FW_F_ICMPRPL 0x100 /* Send back icmp unreachable packet */
-#define IP_FW_F_MASK 0x1FF /* All possible flag bits mask */
+#define IP_FW_F_IFNAME 0x200 /* Use interface name/unit (not IP) */
+#define IP_FW_F_MASK 0x3FF /* All possible flag bits mask */
/*
* New IP firewall options for [gs]etsockopt at the RAW IP level.
OpenPOWER on IntegriCloud