REVIEW request: bin/74450: enable libalias/natd to create skipto
rules when punching ipfw
Joost Bekkers
joost at jodocus.org
Sat Nov 27 08:05:36 PST 2004
Hi
Can somebody knowledgable please review this patch I've submitted to gnats?
All comments are welcome.
Almost forgot to mention: the diff is against 5.3R
thanks
============================
When using ipfw in a stateful firewall with natd it's desirable to have
natd create skipto rules instead of allow rules.
See http://lists.freebsd.org/mailman/htdig/freebsd-ipfw/2004-June/001182.html
for a description of the type of firewall I'm referring to.
--
greetz Joost
joost at jodocus.org
-------------- next part --------------
diff -c src/lib/libalias/dist/alias.h src/lib/libalias/alias.h
*** src/lib/libalias/dist/alias.h Tue Nov 23 21:52:03 2004
--- src/lib/libalias/alias.h Fri Nov 26 19:46:27 2004
***************
*** 126,131 ****
--- 126,132 ----
struct libalias *LibAliasInit(struct libalias *);
void LibAliasSetAddress(struct libalias *, struct in_addr _addr);
void LibAliasSetFWBase(struct libalias *, unsigned int _base, unsigned int _num);
+ void LibAliasSetFWSkipToRule(struct libalias *, unsigned int _rulenr);
void LibAliasSetSkinnyPort(struct libalias *, unsigned int _port);
unsigned int
LibAliasSetMode(struct libalias *, unsigned int _flags, unsigned int _mask);
diff -c src/lib/libalias/dist/alias_db.c src/lib/libalias/alias_db.c
*** src/lib/libalias/dist/alias_db.c Tue Nov 23 21:52:03 2004
--- src/lib/libalias/alias_db.c Fri Nov 26 19:46:27 2004
***************
*** 2531,2537 ****
static int
fill_rule(void *buf, int bufsize, int rulenum,
! enum ipfw_opcodes action, int proto,
struct in_addr sa, u_int16_t sp, struct in_addr da, u_int16_t dp)
{
struct ip_fw *rule = (struct ip_fw *)buf;
--- 2531,2537 ----
static int
fill_rule(void *buf, int bufsize, int rulenum,
! enum ipfw_opcodes action, int arg1, int proto,
struct in_addr sa, u_int16_t sp, struct in_addr da, u_int16_t dp)
{
struct ip_fw *rule = (struct ip_fw *)buf;
***************
*** 2547,2553 ****
cmd = fill_one_port(cmd, O_IP_DSTPORT, dp);
rule->act_ofs = (u_int32_t *) cmd - (u_int32_t *) rule->cmd;
! cmd = fill_cmd(cmd, action, F_INSN_SIZE(ipfw_insn), 0, 0);
rule->cmd_len = (u_int32_t *) cmd - (u_int32_t *) rule->cmd;
--- 2547,2553 ----
cmd = fill_one_port(cmd, O_IP_DSTPORT, dp);
rule->act_ofs = (u_int32_t *) cmd - (u_int32_t *) rule->cmd;
! cmd = fill_cmd(cmd, action, F_INSN_SIZE(ipfw_insn), 0, arg1);
rule->cmd_len = (u_int32_t *) cmd - (u_int32_t *) rule->cmd;
***************
*** 2652,2660 ****
if (GetOriginalPort(lnk) != 0 && GetDestPort(lnk) != 0) {
u_int32_t rulebuf[255];
int i;
i = fill_rule(rulebuf, sizeof(rulebuf), fwhole,
! O_ACCEPT, IPPROTO_TCP,
GetOriginalAddress(lnk), ntohs(GetOriginalPort(lnk)),
GetDestAddress(lnk), ntohs(GetDestPort(lnk)));
r = setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_ADD, rulebuf, i);
--- 2652,2666 ----
if (GetOriginalPort(lnk) != 0 && GetDestPort(lnk) != 0) {
u_int32_t rulebuf[255];
int i;
+ enum ipfw_opcodes action;
+
+ if (la->fireWallSkipTo==0)
+ action=O_ACCEPT;
+ else
+ action=O_SKIPTO;
i = fill_rule(rulebuf, sizeof(rulebuf), fwhole,
! action, la->fireWallSkipTo, IPPROTO_TCP,
GetOriginalAddress(lnk), ntohs(GetOriginalPort(lnk)),
GetDestAddress(lnk), ntohs(GetDestPort(lnk)));
r = setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_ADD, rulebuf, i);
***************
*** 2662,2668 ****
err(1, "alias punch inbound(1) setsockopt(IP_FW_ADD)");
i = fill_rule(rulebuf, sizeof(rulebuf), fwhole,
! O_ACCEPT, IPPROTO_TCP,
GetDestAddress(lnk), ntohs(GetDestPort(lnk)),
GetOriginalAddress(lnk), ntohs(GetOriginalPort(lnk)));
r = setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_ADD, rulebuf, i);
--- 2668,2674 ----
err(1, "alias punch inbound(1) setsockopt(IP_FW_ADD)");
i = fill_rule(rulebuf, sizeof(rulebuf), fwhole,
! action, la->fireWallSkipTo, IPPROTO_TCP,
GetDestAddress(lnk), ntohs(GetDestPort(lnk)),
GetOriginalAddress(lnk), ntohs(GetOriginalPort(lnk)));
r = setsockopt(la->fireWallFD, IPPROTO_IP, IP_FW_ADD, rulebuf, i);
***************
*** 2675,2681 ****
rule.fw_number = fwhole;
IP_FW_SETNSRCP(&rule, 1); /* Number of source ports. */
IP_FW_SETNDSTP(&rule, 1); /* Number of destination ports. */
! rule.fw_flg = IP_FW_F_ACCEPT | IP_FW_F_IN | IP_FW_F_OUT;
rule.fw_prot = IPPROTO_TCP;
rule.fw_smsk.s_addr = INADDR_BROADCAST;
rule.fw_dmsk.s_addr = INADDR_BROADCAST;
--- 2681,2689 ----
rule.fw_number = fwhole;
IP_FW_SETNSRCP(&rule, 1); /* Number of source ports. */
IP_FW_SETNDSTP(&rule, 1); /* Number of destination ports. */
! rule.fw_flg = (la->fireWallSkipTo==0)?IP_FW_F_ACCEPT:IP_FW_F_SKIPTO;
! rule.fw_flg |= IP_FW_F_IN | IP_FW_F_OUT;
! rule.fw_skipto_rule = la->fireWallSkipTo;
rule.fw_prot = IPPROTO_TCP;
rule.fw_smsk.s_addr = INADDR_BROADCAST;
rule.fw_dmsk.s_addr = INADDR_BROADCAST;
***************
*** 2778,2783 ****
--- 2786,2799 ----
#ifndef NO_FW_PUNCH
la->fireWallBaseNum = base;
la->fireWallNumNums = num;
+ #endif
+ }
+
+ void
+ LibAliasSetFWSkipToRule(struct libalias *la, unsigned int rulenr)
+ {
+ #ifndef NO_FW_PUNCH
+ la->fireWallSkipTo = rulenr;
#endif
}
diff -c src/lib/libalias/dist/alias_local.h src/lib/libalias/alias_local.h
*** src/lib/libalias/dist/alias_local.h Tue Nov 23 21:52:03 2004
--- src/lib/libalias/alias_local.h Fri Nov 26 19:46:27 2004
***************
*** 121,126 ****
--- 121,128 ----
* free for our use */
int fireWallNumNums; /* How many entries can we
* use? */
+ int fireWallSkipTo; /* 0 == accept
+ * else rule number to skip to */
int fireWallActiveNum; /* Which entry did we last
* use? */
char *fireWallField; /* bool array for entries */
diff -c src/lib/libalias/dist/libalias.3 src/lib/libalias/libalias.3
*** src/lib/libalias/dist/libalias.3 Tue Nov 23 21:52:03 2004
--- src/lib/libalias/libalias.3 Fri Nov 26 19:46:27 2004
***************
*** 270,275 ****
--- 270,286 ----
.Ed
.Pp
.Ft void
+ .Fn LibAliasSetFWSkipToRule "struct libalias *" "unsigned int rulenr"
+ .Bd -ragged -offset indent
+ Cause
+ .Nm
+ to create skipto rules instead of the default allow rules
+ when making holes in the firewall. Setting
+ .Fa rulenr
+ to 0 will restore the default behavior of creating allow rules.
+ .Ed
+ .Pp
+ .Ft void
.Fn LibAliasSkinnyPort "struct libalias *" "unsigned int port"
.Bd -ragged -offset indent
Set the TCP port used by the Skinny Station protocol.
diff -c src/sbin/natd/dist/natd.8 src/sbin/natd/natd.8
*** src/sbin/natd/dist/natd.8 Fri Nov 26 19:10:27 2004
--- src/sbin/natd/natd.8 Sat Nov 27 16:34:16 2004
***************
*** 31,36 ****
--- 31,37 ----
.Op Fl log_denied
.Op Fl log_facility Ar facility_name
.Op Fl punch_fw Ar firewall_range
+ .Op Fl punch_skipto Ar rule_number
.Op Fl skinny_port Ar port
.Op Fl log_ipfw_denied
.Op Fl pid_file | P Ar pidfile
***************
*** 484,489 ****
--- 485,493 ----
.Ar basenumber
will be used for punching firewall holes.
The range will be cleared for all rules on startup.
+ .It Fl punch_skipto Ar rule_number
+ Instead of the default allow rules, create skipto rules which skip to
+ .Ar rule_number .
.It Fl skinny_port Ar port
This option allows you to specify the TCP port used for
the Skinny Station protocol.
diff -c src/sbin/natd/dist/natd.c src/sbin/natd/natd.c
*** src/sbin/natd/dist/natd.c Fri Nov 26 19:09:06 2004
--- src/sbin/natd/natd.c Fri Nov 26 19:35:50 2004
***************
*** 127,132 ****
--- 127,133 ----
static int StrToAddrAndPortRange (const char* str, struct in_addr* addr, char* proto, port_range *portRange);
static void ParseArgs (int argc, char** argv);
static void SetupPunchFW(const char *strValue);
+ static void SetupPunchSkipTo(const char *strValue);
static void SetupSkinnyPort(const char *strValue);
static void NewInstance(const char *name);
static void DoGlobal (int fd);
***************
*** 1017,1022 ****
--- 1018,1024 ----
LogDenied,
LogFacility,
PunchFW,
+ PunchSkipTo,
SkinnyPort,
LogIpfwDenied,
PidFile
***************
*** 1247,1252 ****
--- 1249,1262 ----
"punch_fw",
NULL },
+ { PunchSkipTo,
+ 0,
+ String,
+ "rulenumber",
+ "use skipto instead of permit action when punching the firewall",
+ "punch_skipto",
+ NULL },
+
{ SkinnyPort,
0,
String,
***************
*** 1465,1470 ****
--- 1475,1484 ----
SetupPunchFW(strValue);
break;
+ case PunchSkipTo:
+ SetupPunchSkipTo(strValue);
+ break;
+
case SkinnyPort:
SetupSkinnyPort(strValue);
break;
***************
*** 1918,1923 ****
--- 1932,1948 ----
LibAliasSetFWBase(mla, base, num);
(void)LibAliasSetMode(mla, PKT_ALIAS_PUNCH_FW, PKT_ALIAS_PUNCH_FW);
+ }
+
+ static void
+ SetupPunchSkipTo(const char *strValue)
+ {
+ unsigned int rule;
+
+ if (sscanf(strValue, "%u", &rule) != 1)
+ errx(1, "punch_skipto: rule number required");
+
+ LibAliasSetFWSkipToRule(mla, rule);
}
static void
More information about the freebsd-ipfw
mailing list