diff options
author | ugen <ugen@FreeBSD.org> | 1995-02-24 14:33:54 +0000 |
---|---|---|
committer | ugen <ugen@FreeBSD.org> | 1995-02-24 14:33:54 +0000 |
commit | 7ef3525e292051d370231bb339a622b2fe6eee0b (patch) | |
tree | 2ff826498b35f62a5d2e57739f274fb810473e22 /sys/netinet | |
parent | 378d96702e47d30d34f67b986b2d20bda838e9cd (diff) | |
download | FreeBSD-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.c | 149 | ||||
-rw-r--r-- | sys/netinet/ip_fw.h | 26 |
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. |