Date: Sun, 18 Jun 2006 17:35:32 +0200 From: Paolo Pisati <p.pisati@oltrelinux.com> To: FreeBSD_Net <freebsd-net@freebsd.org> Subject: Libalias modules and ipfw nat for HEAD Message-ID: <20060618153532.GA69905@tin.it>
next in thread | raw e-mail | index | archive | help
--wac7ysb48OaltWcw Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, attached is the final patch for HEAD of my soc2005 work about ipfw and libalias. Please take a look at it and reprt any problem you'll find, cause i would like to commit it ASAP. There are no fundamental differences between this patch and the previous one: i just merged all the documentation into ipfw.8 and libalias.3. If you want to know exactly what we get with this patch: http://wikitest.freebsd.org/Libalias bye -- Paolo Piso's first law: nothing works as expected! --wac7ysb48OaltWcw Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="libalias_ipfw_final.patch" diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/etc/Makefile /home/flag/src/freebsd7/src/etc/Makefile *** /home/flag/src/freebsd7_vanilla/src/etc/Makefile Wed May 3 17:14:46 2006 --- /home/flag/src/freebsd7/src/etc/Makefile Sun Jun 11 18:59:46 2006 *************** *** 11,17 **** crontab csh.cshrc csh.login csh.logout devd.conf devfs.conf \ dhclient.conf disktab fbtab ftpusers gettytab group \ hosts hosts.allow hosts.equiv hosts.lpd \ ! inetd.conf login.access login.conf mac.conf motd \ netconfig network.subr networks newsyslog.conf nsswitch.conf \ portsnap.conf pf.conf pf.os phones profile protocols \ rc rc.bsdextended rc.firewall rc.firewall6 rc.initdiskless \ --- 11,17 ---- crontab csh.cshrc csh.login csh.logout devd.conf devfs.conf \ dhclient.conf disktab fbtab ftpusers gettytab group \ hosts hosts.allow hosts.equiv hosts.lpd \ ! inetd.conf libalias.conf login.access login.conf mac.conf motd \ netconfig network.subr networks newsyslog.conf nsswitch.conf \ portsnap.conf pf.conf pf.os phones profile protocols \ rc rc.bsdextended rc.firewall rc.firewall6 rc.initdiskless \ diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/etc/libalias.conf /home/flag/src/freebsd7/src/etc/libalias.conf *** /home/flag/src/freebsd7_vanilla/src/etc/libalias.conf Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/etc/libalias.conf Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,7 ---- + /usr/lib/libalias_cuseeme.so + /usr/lib/libalias_ftp.so + /usr/lib/libalias_irc.so + /usr/lib/libalias_nbt.so + /usr/lib/libalias_pptp.so + /usr/lib/libalias_skinny.so + /usr/lib/libalias_smedia.so diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/lib/libalias/Makefile /home/flag/src/freebsd7/src/lib/libalias/Makefile *** /home/flag/src/freebsd7_vanilla/src/lib/libalias/Makefile Fri Jul 22 19:18:59 2005 --- /home/flag/src/freebsd7/src/lib/libalias/Makefile Sun Jun 11 19:01:50 2006 *************** *** 1,16 **** # $FreeBSD: src/lib/libalias/Makefile,v 1.31 2005/07/22 17:18:59 kensmith Exp $ ! ! .PATH: ${.CURDIR}/../../sys/netinet/libalias ! ! LIB= alias ! SHLIBDIR?= /lib ! SHLIB_MAJOR= 5 ! MAN= libalias.3 ! SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \ ! alias_nbt.c alias_pptp.c alias_proxy.c alias_skinny.c alias_smedia.c \ ! alias_util.c alias_old.c ! INCS= alias.h ! WARNS?= 6 ! NO_WERROR= ! ! .include <bsd.lib.mk> --- 1,12 ---- # $FreeBSD: src/lib/libalias/Makefile,v 1.31 2005/07/22 17:18:59 kensmith Exp $ ! SUBDIR= lib-cuseeme \ ! lib-dummy \ ! lib-ftp \ ! lib-irc \ ! lib-libalias \ ! lib-nbt \ ! lib-pptp \ ! lib-skinny \ ! lib-smedia ! ! .include <bsd.subdir.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-cuseeme/Makefile /home/flag/src/freebsd7/src/lib/libalias/lib-cuseeme/Makefile *** /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-cuseeme/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/lib/libalias/lib-cuseeme/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,11 ---- + .PATH: ${.CURDIR}/../../../sys/netinet/libalias + + LIB= alias_cuseeme + SHLIBDIR?= /lib + SHLIB_MAJOR= 4 + SRCS= alias_cuseeme.c + INCS= alias_mod.h + + CFLAGS+= -Werror + + .include <bsd.lib.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-dummy/Makefile /home/flag/src/freebsd7/src/lib/libalias/lib-dummy/Makefile *** /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-dummy/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/lib/libalias/lib-dummy/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,11 ---- + .PATH: ${.CURDIR}/../../../sys/netinet/libalias + + LIB= alias_dummy + SHLIBDIR?= /lib + SHLIB_MAJOR= 4 + SRCS= alias_dummy.c + INCS= alias_mod.h + + CFLAGS+= -Werror + + .include <bsd.lib.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-ftp/Makefile /home/flag/src/freebsd7/src/lib/libalias/lib-ftp/Makefile *** /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-ftp/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/lib/libalias/lib-ftp/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,11 ---- + .PATH: ${.CURDIR}/../../../sys/netinet/libalias + + LIB= alias_ftp + SHLIBDIR?= /lib + SHLIB_MAJOR= 4 + SRCS= alias_ftp.c + INCS= alias_mod.h + + CFLAGS+= -Werror + + .include <bsd.lib.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-irc/Makefile /home/flag/src/freebsd7/src/lib/libalias/lib-irc/Makefile *** /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-irc/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/lib/libalias/lib-irc/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,11 ---- + .PATH: ${.CURDIR}/../../../sys/netinet/libalias + + LIB= alias_irc + SHLIBDIR?= /lib + SHLIB_MAJOR= 4 + SRCS= alias_irc.c + INCS= alias_mod.h + + CFLAGS+= -Werror + + .include <bsd.lib.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-libalias/Makefile /home/flag/src/freebsd7/src/lib/libalias/lib-libalias/Makefile *** /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-libalias/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/lib/libalias/lib-libalias/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,14 ---- + # $FreeBSD: src/lib/libalias/Makefile,v 1.30.2.1 2005/07/22 17:29:02 kensmith Exp $ + + .PATH: ${.CURDIR}/../../../sys/netinet/libalias + + LIB= alias + SHLIBDIR?= /lib + SHLIB_MAJOR= 5 + MAN= libalias.3 + SRCS= alias.c alias_db.c alias_proxy.c alias_util.c alias_old.c alias_mod.c + INCS= alias.h alias_mod.h + WARNS?= 6 + NO_WERROR= + + .include <bsd.lib.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-nbt/Makefile /home/flag/src/freebsd7/src/lib/libalias/lib-nbt/Makefile *** /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-nbt/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/lib/libalias/lib-nbt/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,11 ---- + .PATH: ${.CURDIR}/../../../sys/netinet/libalias + + LIB= alias_nbt + SHLIBDIR?= /lib + SHLIB_MAJOR= 4 + SRCS= alias_nbt.c + INCS= alias_mod.h + + CFLAGS+= -Werror + + .include <bsd.lib.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-pptp/Makefile /home/flag/src/freebsd7/src/lib/libalias/lib-pptp/Makefile *** /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-pptp/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/lib/libalias/lib-pptp/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,11 ---- + .PATH: ${.CURDIR}/../../../sys/netinet/libalias + + LIB= alias_pptp + SHLIBDIR?= /lib + SHLIB_MAJOR= 4 + SRCS= alias_pptp.c + INCS= alias_mod.h + + CFLAGS+= -Werror + + .include <bsd.lib.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-skinny/Makefile /home/flag/src/freebsd7/src/lib/libalias/lib-skinny/Makefile *** /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-skinny/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/lib/libalias/lib-skinny/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,11 ---- + .PATH: ${.CURDIR}/../../../sys/netinet/libalias + + LIB= alias_skinny + SHLIBDIR?= /lib + SHLIB_MAJOR= 4 + SRCS= alias_skinny.c + INCS= alias_mod.h + + CFLAGS+= -Werror + + .include <bsd.lib.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-smedia/Makefile /home/flag/src/freebsd7/src/lib/libalias/lib-smedia/Makefile *** /home/flag/src/freebsd7_vanilla/src/lib/libalias/lib-smedia/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/lib/libalias/lib-smedia/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,11 ---- + .PATH: ${.CURDIR}/../../../sys/netinet/libalias + + LIB= alias_smedia + SHLIBDIR?= /lib + SHLIB_MAJOR= 4 + SRCS= alias_smedia.c + INCS= alias_mod.h + + CFLAGS+= -Werror + + .include <bsd.lib.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sbin/ipfw/ipfw.8 /home/flag/src/freebsd7/src/sbin/ipfw/ipfw.8 *** /home/flag/src/freebsd7_vanilla/src/sbin/ipfw/ipfw.8 Wed May 24 15:09:55 2006 --- /home/flag/src/freebsd7/src/sbin/ipfw/ipfw.8 Sun Jun 18 16:10:14 2006 *************** *** 2027,2032 **** --- 2027,2124 ---- If no socket is bound to the destination port, or if the divert module is not loaded, or if the kernel was not compiled with divert socket support, the packets are dropped. + .Sh IPFW NAT + To support nat operations inside ipfw, the syntax was extended with a + new action: nat. + Then, to configure/handle nat instances the following syntax was + added (trying to follow closely pipe|queue options): + .Bd -ragged -offset indent + .Bk -words + .Cm nat + .Ar nat_number + .Cm config + .Ar options + .Ek + .Ed + .Pp + where + .Ar options + is one or more mandatory fields that can assume the + following values: + .Bl -tag -width indent + .It Cm ip Ar ip_address + Define an ip address to use for aliasing + .It Cm if Ar nic + Use ip addres of NIC for aliasing, dynamically changing + it if NIC's ip address change + .It Cm log + Enable logging on this nat instance + .It Cm deny_in + Deny any incoming connection from outside world + .It Cm same_ports + Try to leave the alias port numbers unchanged from + the actual local port numbers + .It Cm unreg_only + Traffic on the local network not originating from an + unregistered address spaces will be ignored + .It Cm reset + Reset table of the packet aliasing engine on address change + .It Cm reverse + Reverse the way libalias handles aliasing + .It Cm proxy_only + Obey transparent proxy rules only, packet aliasing is not performed + .El + .Pp + For more information about aliasing modes, take a look + at libalias( + .Xr libalias 3 + ). + .Pp + Other commands to manipulate nats are: + .Bd -ragged -offset indent + .Bk -words + .Cm nat + .Ar nat_number + .Cm show + .Cm config + .Ek + .Ed + .Pp + to see nat configuration of + .Ar nat_number + . + .Pp + .Bd -ragged -offset indent + .Bk -words + .Cm nat + .Ar nat_number + .Cm show + .Ek + .Ed + .Pp + to see the logs of + .Ar nat_number + (if any) + .Pp + In these two previous examples + .Ar nat_number + could be a single number to see the configuration of that + instance (i.e. 123, a range of numbers (i.e 333-555) to see the + configurations all the instances in that range or nothing, to see all + the configured instances. + .Pp + See Section + .Sx EXAMPLES + for some examples on how to use nat. + .Sh REDIRECT AND LSNAT SUPPORT IN IPFW + Redirect and LSNAT support follow closely the syntax used in natd: refer to natd's man page + for syntax details. + The only difference between natd's redirect and ipfw redirect is: + instead of redirect_[addr|port|prot] i chose redir_[addr|port|proto]. + .Pp + See Section + .Sx EXAMPLES + for some examples on how to do redirect and lsnat. .Sh SYSCTL VARIABLES A set of .Xr sysctl 8 *************** *** 2406,2411 **** --- 2498,2552 ---- Otherwise, e.g.\& if you cannot access your box, the ruleset will be disabled after the sleep terminates thus restoring the previous situation. + .Ss NAT, REDIRECT AND LSNAT + First redirect all the traffic to nat instance 123: + .Pp + .Dl "ipfw add nat 123 all from any to any" + .Pp + Then to configure nat instance 123 to alias all the outgoing traffic with ip + 192.168.0.123, blocking all incoming connections, trying to keep + same ports on both sides, clearing aliasing table on address change + and keeping a log of traffic/link statistics: + .Pp + .Dl "ipfw nat 123 config ip 192.168.0.123 log deny_in reset same_ports" + .Pp + Or to change address of instance 123, aliasing table will be cleared (see + reset option): + .Pp + .Dl "ipfw nat 123 config ip 10.0.0.1" + .Pp + To see configuration of nat instance 123: + .Pp + .Dl "ipfw nat 123 show config" + .Pp + To show logs of all the instances in range 111-999: + .Pp + .Dl "ipfw nat 111-999 show" + .Pp + To see configurations of all instances: + .Pp + .Dl "ipfw nat show config" + .Pp + Or a redirect rule with mixed modes could looks like: + .Pp + .Dl "ipfw nat 123 config redir_addr 10.0.0.1 10.0.0.66" + .Dl " redir_port tcp 192.168.0.1:80 500" + .Dl " redir_proto udp 192.168.1.43 192.168.1.1" + .Dl " redir_addr 192.168.0.10,192.168.0.11" + .Dl " 10.0.0.100 # LSNAT" + .Dl " redir_port tcp 192.168.0.1:80,192.168.0.10:22" + .Dl " 500 # LSNAT" + .Pp + or it could be splitted in: + .Pp + .Dl "ipfw nat 1 config redir_addr 10.0.0.1 10.0.0.66" + .Dl "ipfw nat 2 config redir_port tcp 192.168.0.1:80 500" + .Dl "ipfw nat 3 config redir_proto udp 192.168.1.43 192.168.1.1" + .Dl "ipfw nat 4 config redir_addr 192.168.0.10,192.168.0.11,192.168.0.12" + .Dl " 10.0.0.100" + .Dl "ipfw nat 5 config redir_port tcp" + .Dl " 192.168.0.1:80,192.168.0.10:22,192.168.0.20:25 500" + .Pp .Sh SEE ALSO .Xr cpp 1 , .Xr m4 1 , *************** *** 2446,2451 **** --- 2587,2597 ---- API based upon code written by .An Daniel Boulet for BSDI. + .Pp + .An -nosplit + In-kernel NAT support written by + .An Paolo Pisati Aq piso@FreeBSD.org + as part of a Summer of Code 2005 project. .Pp Work on .Xr dummynet 4 diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sbin/ipfw/ipfw2.c /home/flag/src/freebsd7/src/sbin/ipfw/ipfw2.c *** /home/flag/src/freebsd7_vanilla/src/sbin/ipfw/ipfw2.c Fri Jun 2 07:17:17 2006 --- /home/flag/src/freebsd7/src/sbin/ipfw/ipfw2.c Sun Jun 11 18:57:26 2006 *************** *** 48,53 **** --- 48,54 ---- #include <fcntl.h> #include <net/if.h> + #include <net/if_dl.h> #include <net/pfvar.h> #include <net/route.h> /* def. of struct route */ #include <netinet/in.h> *************** *** 59,70 **** --- 60,73 ---- #include <netinet/ip_dummynet.h> #include <netinet/tcp.h> #include <arpa/inet.h> + #include <alias.h> int do_resolv, /* Would try to resolve all */ do_time, /* Show time stamps */ do_quiet, /* Be quiet in add and flush */ do_pipe, /* this cmd refers to a pipe */ + do_nat, /* nat configuration */ do_sort, /* field to sort results (0 = no) */ do_dynamic, /* display dynamic rules */ do_expired, /* display expired dynamic rules */ *************** *** 218,223 **** --- 221,227 ---- TOK_RESET, TOK_UNREACH, TOK_CHECKSTATE, + TOK_NAT, TOK_ALTQ, TOK_LOG, *************** *** 280,285 **** --- 284,301 ---- TOK_DROPTAIL, TOK_PROTO, TOK_WEIGHT, + TOK_IP, + TOK_IF, + TOK_LOG, + TOK_DENY_INC, + TOK_SAME_PORTS, + TOK_UNREG_ONLY, + TOK_RESET_ADDR, + TOK_ALIAS_REV, + TOK_PROXY_ONLY, + TOK_REDIR_ADDR, + TOK_REDIR_PORT, + TOK_REDIR_PROTO, TOK_IPV6, TOK_FLOWID, *************** *** 322,327 **** --- 338,359 ---- { NULL, 0 } /* terminator */ }; + struct _s_x nat_params[] = { + { "ip", TOK_IP }, + { "if", TOK_IF }, + { "log", TOK_LOG }, + { "deny_in", TOK_DENY_INC }, + { "same_ports", TOK_SAME_PORTS }, + { "unreg_only", TOK_UNREG_ONLY }, + { "reset", TOK_RESET_ADDR }, + { "reverse", TOK_ALIAS_REV }, + { "proxy_only", TOK_PROXY_ONLY }, + { "redir_addr", TOK_REDIR_ADDR }, + { "redir_port", TOK_REDIR_PORT }, + { "redir_proto", TOK_REDIR_PROTO }, + { NULL, 0 } /* terminator */ + }; + struct _s_x rule_actions[] = { { "accept", TOK_ACCEPT }, { "pass", TOK_ACCEPT }, *************** *** 346,351 **** --- 378,384 ---- { "unreach", TOK_UNREACH }, { "check-state", TOK_CHECKSTATE }, { "//", TOK_COMMENT }, + { "nat", TOK_NAT}, { NULL, 0 } /* terminator */ }; *************** *** 453,459 **** { static int s = -1; /* the socket */ int i; ! if (test_only) return 0; --- 486,492 ---- { static int s = -1; /* the socket */ int i; ! if (test_only) return 0; *************** *** 464,470 **** if (optname == IP_FW_GET || optname == IP_DUMMYNET_GET || optname == IP_FW_ADD || optname == IP_FW_TABLE_LIST || ! optname == IP_FW_TABLE_GETSIZE) i = getsockopt(s, IPPROTO_IP, optname, optval, (socklen_t *)optlen); else --- 497,504 ---- if (optname == IP_FW_GET || optname == IP_DUMMYNET_GET || optname == IP_FW_ADD || optname == IP_FW_TABLE_LIST || ! optname == IP_FW_TABLE_GETSIZE || optname == IP_FW_NAT_GET_CONFIG || ! optname == IP_FW_NAT_GET_LOG) i = getsockopt(s, IPPROTO_IP, optname, optval, (socklen_t *)optlen); else *************** *** 1520,1525 **** --- 1554,1563 ---- tagptr = cmd; break; + case O_NAT: + printf("nat %u", cmd->arg1); + break; + default: printf("** unrecognized action %d len %d ", cmd->opcode, cmd->len); *************** *** 2583,2595 **** "add [num] [set N] [prob x] RULE-BODY\n" "{pipe|queue} N config PIPE-BODY\n" "[pipe|queue] {zero|delete|show} [N{,N}]\n" "set [disable N... enable N...] | move [rule] X to Y | swap X Y | show\n" "table N {add ip[/bits] [value] | delete ip[/bits] | flush | list}\n" "\n" "RULE-BODY: check-state [PARAMS] | ACTION [PARAMS] ADDR [OPTION_LIST]\n" "ACTION: check-state | allow | count | deny | unreach{,6} CODE |\n" " skipto N | {divert|tee} PORT | forward ADDR |\n" ! " pipe N | queue N\n" "PARAMS: [log [logamount LOGLIMIT]] [altq QUEUE_NAME]\n" "ADDR: [ MAC dst src ether_type ] \n" " [ ip from IPADDR [ PORT ] to IPADDR [ PORTLIST ] ]\n" --- 2621,2636 ---- "add [num] [set N] [prob x] RULE-BODY\n" "{pipe|queue} N config PIPE-BODY\n" "[pipe|queue] {zero|delete|show} [N{,N}]\n" + "nat N config {ip IPADDR|if IFNAME|log|deny_in|same_ports|unreg_only|reset|\n" + " reverse|proxy_only|redir_addr linkspec| redir_port linkspec|\n" + " redir_proto linkspec}\n" "set [disable N... enable N...] | move [rule] X to Y | swap X Y | show\n" "table N {add ip[/bits] [value] | delete ip[/bits] | flush | list}\n" "\n" "RULE-BODY: check-state [PARAMS] | ACTION [PARAMS] ADDR [OPTION_LIST]\n" "ACTION: check-state | allow | count | deny | unreach{,6} CODE |\n" " skipto N | {divert|tee} PORT | forward ADDR |\n" ! " pipe N | queue N | nat N\n" "PARAMS: [log [logamount LOGLIMIT]] [altq QUEUE_NAME]\n" "ADDR: [ MAC dst src ether_type ] \n" " [ ip from IPADDR [ PORT ] to IPADDR [ PORTLIST ] ]\n" *************** *** 3098,3104 **** /* Rule number */ while (ac && isdigit(**av)) { i = atoi(*av); av++; ac--; ! if (do_pipe) { if (do_pipe == 1) p.pipe_nr = i; else --- 3139,3152 ---- /* Rule number */ while (ac && isdigit(**av)) { i = atoi(*av); av++; ac--; ! if (do_nat) { ! exitval = do_cmd(IP_FW_NAT_DEL, &i, sizeof i); ! if (exitval) { ! exitval = EX_UNAVAILABLE; ! warn("rule %u not available", ! i); ! } ! } else if (do_pipe) { if (do_pipe == 1) p.pipe_nr = i; else *************** *** 3123,3129 **** exit(exitval); } - /* * fill the interface structure. We do not check the name as we can * create interfaces dynamically, so checking them at insert time --- 3171,3176 ---- *************** *** 3147,3152 **** --- 3194,3946 ---- errx(EX_DATAERR, "bad ip address ``%s''", arg); } + /* + * Search for interface with name "ifn", and fill n accordingly: + * + * n->ip ip address of interface "ifn" + * n->if_name copy of interface name "ifn" + */ + static void + set_addr_dynamic(const char *ifn, struct cfg_nat *n) + { + size_t needed; + int mib[6]; + char *buf, *lim, *next; + struct if_msghdr *ifm; + struct ifa_msghdr *ifam; + struct sockaddr_dl *sdl; + struct sockaddr_in *sin; + int ifIndex, ifMTU; + + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = AF_INET; /* Only IP addresses please */ + mib[4] = NET_RT_IFLIST; + mib[5] = 0; /* ifIndex??? */ + /* + * Get interface data. + */ + if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) + err(1, "iflist-sysctl-estimate"); + if ((buf = malloc(needed)) == NULL) + errx(1, "malloc failed"); + if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) + err(1, "iflist-sysctl-get"); + lim = buf + needed; + /* + * Loop through interfaces until one with + * given name is found. This is done to + * find correct interface index for routing + * message processing. + */ + ifIndex = 0; + next = buf; + while (next < lim) { + ifm = (struct if_msghdr *)next; + next += ifm->ifm_msglen; + if (ifm->ifm_version != RTM_VERSION) { + if (verbose) + warnx("routing message version %d " + "not understood", ifm->ifm_version); + continue; + } + if (ifm->ifm_type == RTM_IFINFO) { + sdl = (struct sockaddr_dl *)(ifm + 1); + if (strlen(ifn) == sdl->sdl_nlen && + strncmp(ifn, sdl->sdl_data, sdl->sdl_nlen) == 0) { + ifIndex = ifm->ifm_index; + ifMTU = ifm->ifm_data.ifi_mtu; + break; + } + } + } + if (!ifIndex) + errx(1, "unknown interface name %s", ifn); + /* + * Get interface address. + */ + sin = NULL; + while (next < lim) { + ifam = (struct ifa_msghdr *)next; + next += ifam->ifam_msglen; + if (ifam->ifam_version != RTM_VERSION) { + if (verbose) + warnx("routing message version %d " + "not understood", ifam->ifam_version); + continue; + } + if (ifam->ifam_type != RTM_NEWADDR) + break; + if (ifam->ifam_addrs & RTA_IFA) { + int i; + char *cp = (char *)(ifam + 1); + + for (i = 1; i < RTA_IFA; i <<= 1) + if (ifam->ifam_addrs & i) + cp += SA_SIZE((struct sockaddr *)cp); + if (((struct sockaddr *)cp)->sa_family == AF_INET) { + sin = (struct sockaddr_in *)cp; + break; + } + } + } + if (sin == NULL) + errx(1, "%s: cannot get interface address", ifn); + + n->ip = sin->sin_addr; + strncpy(n->if_name, ifn, IF_NAMESIZE); + + free(buf); + } + + /* + * XXX: the following functions, macros and definitions come from natd.c: + * it would be better to move them outside of natd.c, in a file + * (redirect_support.[ch]?) shared by ipfw and natd, but for now i can live + * with it... + */ + + /* + * Definition of a port range, and macros to deal with values. + * FORMAT: HI 16-bits == first port in range, 0 == all ports. + * LO 16-bits == number of ports in range + * NOTES: - Port values are not stored in network byte order. + */ + + #define port_range u_long + + #define GETLOPORT(x) ((x) >> 0x10) + #define GETNUMPORTS(x) ((x) & 0x0000ffff) + #define GETHIPORT(x) (GETLOPORT((x)) + GETNUMPORTS((x))) + + /* Set y to be the low-port value in port_range variable x. */ + #define SETLOPORT(x,y) ((x) = ((x) & 0x0000ffff) | ((y) << 0x10)) + + /* Set y to be the number of ports in port_range variable x. */ + #define SETNUMPORTS(x,y) ((x) = ((x) & 0xffff0000) | (y)) + + static void + StrToAddr (const char* str, struct in_addr* addr) + { + struct hostent* hp; + + if (inet_aton (str, addr)) + return; + + hp = gethostbyname (str); + if (!hp) + errx (1, "unknown host %s", str); + + memcpy (addr, hp->h_addr, sizeof (struct in_addr)); + } + + static int + StrToPortRange (const char* str, const char* proto, port_range *portRange) + { + char* sep; + struct servent* sp; + char* end; + u_short loPort; + u_short hiPort; + + /* First see if this is a service, return corresponding port if so. */ + sp = getservbyname (str,proto); + if (sp) { + SETLOPORT(*portRange, ntohs(sp->s_port)); + SETNUMPORTS(*portRange, 1); + return 0; + } + + /* Not a service, see if it's a single port or port range. */ + sep = strchr (str, '-'); + if (sep == NULL) { + SETLOPORT(*portRange, strtol(str, &end, 10)); + if (end != str) { + /* Single port. */ + SETNUMPORTS(*portRange, 1); + return 0; + } + + /* Error in port range field. */ + errx (EX_DATAERR, "%s/%s: unknown service", str, proto); + } + + /* Port range, get the values and sanity check. */ + sscanf (str, "%hu-%hu", &loPort, &hiPort); + SETLOPORT(*portRange, loPort); + SETNUMPORTS(*portRange, 0); /* Error by default */ + if (loPort <= hiPort) + SETNUMPORTS(*portRange, hiPort - loPort + 1); + + if (GETNUMPORTS(*portRange) == 0) + errx (EX_DATAERR, "invalid port range %s", str); + + return 0; + } + + static int + StrToProto (const char* str) + { + if (!strcmp (str, "tcp")) + return IPPROTO_TCP; + + if (!strcmp (str, "udp")) + return IPPROTO_UDP; + + errx (EX_DATAERR, "unknown protocol %s. Expected tcp or udp", str); + } + + static int + StrToAddrAndPortRange (const char* str, struct in_addr* addr, char* proto, port_range *portRange) + { + char* ptr; + + ptr = strchr (str, ':'); + if (!ptr) + errx (EX_DATAERR, "%s is missing port number", str); + + *ptr = '\0'; + ++ptr; + + StrToAddr (str, addr); + return StrToPortRange (ptr, proto, portRange); + } + + /* end of stuff taken from natd.c */ + + #define INC_ARGCV() do { \ + (*_av)++; \ + (*_ac)--; \ + av = *_av; \ + ac = *_ac; \ + } while(0) + + /* + * The next 3 functions add support for the addr, port and proto redirect and + * their logic is loosely based on SetupAddressRedirect(), SetupPortRedirect() + * and SetupProtoRedirect() from natd.c. + * + * Every setup_* function fills at least one redirect entry + * (struct cfg_redir) and zero or more server pool entry (struct cfg_spool) + * in buf. + * + * The format of data in buf is: + * + * + * cfg_nat cfg_redir cfg_spool ...... cfg_spool + * + * ------------------------------------- ------------ + * | | .....X ... | | | | ..... + * ------------------------------------- ...... ------------ + * ^ + * spool_cnt n=0 ...... n=(X-1) + * + * len points to the amount of available space in buf + * space counts the memory consumed by every function + * + * XXX - Every function get all the argv params so it + * has to check, in optional parameters, that the next + * args is a valid option for the redir entry and not + * another token. Only redir_port and redir_proto are + * affected by this. + */ + + static int + setup_redir_addr(char *spool_buf, int len, + int *_ac, char ***_av) + { + char **av = *_av, *sep; /* token separator */ + /* temporary buffer used to hold server pool ip's */ + char tmp_spool_buf[NAT_BUF_LEN]; + int ac = *_ac, i, space = 0, lsnat = 0; + int sof_redir = sizeof(struct cfg_redir); + struct cfg_redir *r; + + if (len >= sof_redir) { + r = (struct cfg_redir *)spool_buf; + /* skip cfg_redir at beginning of buf */ + spool_buf = &spool_buf[sof_redir]; + space = sof_redir; + len -= sof_redir; + } else + goto nospace; + r->mode = REDIR_ADDR; + /* extract local address */ + if (ac == 0) + errx(EX_DATAERR, "redir_addr: missing local address"); + sep = strchr(*av, ','); + if (sep) { /* LSNAT redirection syntax. */ + r->laddr.s_addr = INADDR_NONE; + /* preserve av, copy spool servers to tmp_spool_buf */ + strncpy(tmp_spool_buf, *av, strlen(*av)+1); + lsnat = 1; + } else + StrToAddr(*av, &r->laddr); + INC_ARGCV(); + + /* extract public address */ + if (ac == 0) + errx(EX_DATAERR, "redir_addr: missing public address"); + StrToAddr(*av, &r->paddr); + INC_ARGCV(); + + /* setup LSNAT server pool */ + if (sep) { + int sof_spool = sizeof(struct cfg_spool); + struct cfg_spool *tmp; + + sep = strtok(tmp_spool_buf, ","); + while (sep != NULL) { + tmp = (struct cfg_spool *)spool_buf; + if (len < sof_spool) + goto nospace; + len -= sof_spool; + space += sof_spool; + StrToAddr(sep, &tmp->addr); + tmp->port = ~0; + r->spool_cnt++; + /* point to the next possible cfg_spool */ + spool_buf = &spool_buf[sof_spool]; + sep = strtok(NULL, ","); + } + } + return(space); + nospace: + errx(EX_DATAERR, "redir_addr: buf is too small\n"); + } + + static int + setup_redir_port(char *spool_buf, int len, + int *_ac, char ***_av) + { + char **av = *_av, *sep, *protoName; + char tmp_spool_buf[NAT_BUF_LEN]; + int ac = *_ac, space = 0, lsnat = 0; + int sof_redir = sizeof(struct cfg_redir); + struct cfg_redir *r; + u_short numLocalPorts = 0; + port_range portRange; + + if (len >= sof_redir) { + r = (struct cfg_redir *)spool_buf; + /* skip cfg_redir at beginning of buf */ + spool_buf = &spool_buf[sof_redir]; + space = sof_redir; + len -= sof_redir; + } else + goto nospace; + r->mode = REDIR_PORT; + /* + * Extract protocol. + */ + if (ac == 0) + errx (EX_DATAERR, "redirect_port: missing protocol"); + r->proto = StrToProto(*av); + protoName = *av; + INC_ARGCV(); + + /* + * Extract local address. + */ + if (ac == 0) + errx (EX_DATAERR, "redirect_port: missing local address"); + + sep = strchr(*av, ','); + if (sep) { /* LSNAT redirection syntax. */ + r->laddr.s_addr = INADDR_NONE; + r->lport = ~0; + numLocalPorts = 1; + /* preserve av, copy spool servers to tmp_spool_buf */ + strncpy(tmp_spool_buf, *av, strlen(*av)+1); + lsnat = 1; + } else { + if ( StrToAddrAndPortRange (*av, &r->laddr, protoName, &portRange) != 0 ) + errx (EX_DATAERR, "redirect_port: invalid local port range"); + + r->lport = GETLOPORT(portRange); + numLocalPorts = GETNUMPORTS(portRange); + } + INC_ARGCV(); + + /* + * Extract public port and optionally address. + */ + if (ac == 0) + errx (EX_DATAERR, "redirect_port: missing public port"); + + sep = strchr (*av, ':'); + if (sep) { + if (StrToAddrAndPortRange (*av, &r->paddr, protoName, &portRange) != 0 ) + errx (EX_DATAERR, "redirect_port: invalid public port range"); + } else { + r->paddr.s_addr = INADDR_ANY; + if (StrToPortRange (*av, protoName, &portRange) != 0) + errx (EX_DATAERR, "redirect_port: invalid public port range"); + } + + r->pport = GETLOPORT(portRange); + r->pport_cnt = GETNUMPORTS(portRange); + INC_ARGCV(); + + /* + * Extract remote address and optionally port. + */ + /* + * isalpha(**av) => we've to check that next parameter is really an + * option for this redirect entry, else stop here processing arg[cv] + */ + if (ac != 0 && !isalpha(**av)) { + sep = strchr (*av, ':'); + if (sep) { + if (StrToAddrAndPortRange (*av, &r->raddr, protoName, &portRange) != 0) + errx (EX_DATAERR, "redirect_port: invalid remote port range"); + } else { + SETLOPORT(portRange, 0); + SETNUMPORTS(portRange, 1); + StrToAddr (*av, &r->raddr); + } + INC_ARGCV(); + } else { + SETLOPORT(portRange, 0); + SETNUMPORTS(portRange, 1); + r->raddr.s_addr = INADDR_ANY; + } + r->rport = GETLOPORT(portRange); + r->rport_cnt = GETNUMPORTS(portRange); + + /* + * Make sure port ranges match up, then add the redirect ports. + */ + if (numLocalPorts != r->pport_cnt) + errx(EX_DATAERR, "redirect_port: port ranges must be equal in size"); + + /* Remote port range is allowed to be '0' which means all ports. */ + if (r->rport_cnt != numLocalPorts && (r->rport_cnt != 1 || r->rport != 0)) + errx(EX_DATAERR, "redirect_port: remote port must be 0 or equal to local port range in size"); + + /* + * Setup LSNAT server pool. + */ + if (lsnat) { + int sof_spool = sizeof(struct cfg_spool); + struct cfg_spool *tmp; + + sep = strtok(tmp_spool_buf, ","); + while (sep != NULL) { + tmp = (struct cfg_spool *)spool_buf; + if (len < sof_spool) + goto nospace; + len -= sof_spool; + space += sof_spool; + if (StrToAddrAndPortRange(sep, &tmp->addr, protoName, &portRange) != 0) + errx(EX_DATAERR, "redirect_port: invalid local port range"); + if (GETNUMPORTS(portRange) != 1) + errx(EX_DATAERR, "redirect_port: local port must be single in this context"); + tmp->port = GETLOPORT(portRange); + r->spool_cnt++; + /* point to the next possible cfg_spool */ + spool_buf = &spool_buf[sof_spool]; + sep = strtok(NULL, ","); + } + } + return(space); + nospace: + errx(EX_DATAERR, "redir_port: buf is too small\n"); + } + + static int + setup_redir_proto(char *spool_buf, int len, + int *_ac, char ***_av) + { + char **av = *_av; + int ac = *_ac, i, space; + struct protoent *protoent; + int sof_redir = sizeof(struct cfg_redir); + struct cfg_redir *r; + + if (len >= sof_redir) { + r = (struct cfg_redir *)spool_buf; + /* skip cfg_redir at beginning of buf */ + spool_buf = &spool_buf[sof_redir]; + space = sof_redir; + len -= sof_redir; + } else + goto nospace; + r->mode = REDIR_PROTO; + /* + * Extract protocol. + */ + if (ac == 0) + errx(EX_DATAERR, "redirect_proto: missing protocol"); + + protoent = getprotobyname(*av); + if (protoent == NULL) + errx(EX_DATAERR, "redirect_proto: unknown protocol %s", *av); + else + r->proto = protoent->p_proto; + + INC_ARGCV(); + + /* + * Extract local address. + */ + if (ac == 0) + errx(EX_DATAERR, "redirect_proto: missing local address"); + else + StrToAddr(*av, &r->laddr); + + INC_ARGCV(); + + /* + * Extract optional public address. + */ + if (ac == 0) { + r->paddr.s_addr = INADDR_ANY; + r->raddr.s_addr = INADDR_ANY; + } else { + /* see above in setup_redir_port() */ + if (!isalpha(**av)) { + StrToAddr(*av, &r->paddr); + INC_ARGCV(); + + /* + * Extract optional remote address. + */ + /* see above in setup_redir_port() */ + if (ac!=0 && !isalpha(**av)) { + StrToAddr(*av, &r->raddr); + INC_ARGCV(); + } + } + } + return(space); + nospace: + errx(EX_DATAERR, "redir_proto: buf is too small\n"); + } + + static void + show_nat(int ac, char **av); + + static void + print_nat_config(char *buf) { + struct cfg_nat *n = (struct cfg_nat *)buf; + int i, cnt, flag = 1, off = sizeof(*n); + int sof_redir = sizeof(struct cfg_redir); + int sof_spool = sizeof(struct cfg_spool); + struct cfg_redir *t; + struct cfg_spool *s; + struct protoent *p; + + printf("ipfw nat %u config", n->id); + if (strlen(n->if_name) != 0) + printf(" if %s", n->if_name); + else if (n->ip.s_addr != 0) + printf(" ip %s", inet_ntoa(n->ip)); + while (n->mode != 0) { + if (n->mode & PKT_ALIAS_LOG) { + printf(" log"); + n->mode &= ~PKT_ALIAS_LOG; + } else if (n->mode & PKT_ALIAS_DENY_INCOMING) { + printf(" deny_in"); + n->mode &= ~PKT_ALIAS_DENY_INCOMING; + } else if (n->mode & PKT_ALIAS_SAME_PORTS) { + printf(" same_ports"); + n->mode &= ~PKT_ALIAS_SAME_PORTS; + } else if (n->mode & PKT_ALIAS_UNREGISTERED_ONLY) { + printf(" unreg_only"); + n->mode &= ~PKT_ALIAS_UNREGISTERED_ONLY; + } else if (n->mode & PKT_ALIAS_RESET_ON_ADDR_CHANGE) { + printf(" reset"); + n->mode &= ~PKT_ALIAS_RESET_ON_ADDR_CHANGE; + } else if (n->mode & PKT_ALIAS_REVERSE) { + printf(" reverse"); + n->mode &= ~PKT_ALIAS_REVERSE; + } else if (n->mode & PKT_ALIAS_PROXY_ONLY) { + printf(" proxy_only"); + n->mode &= ~PKT_ALIAS_PROXY_ONLY; + } + } + /* print all the redirect's data configuration */ + for (cnt=0; cnt < n->redir_cnt; cnt++) { + t = (struct cfg_redir *)&buf[off]; + off += sof_redir; + switch(t->mode) { + case REDIR_ADDR: + printf(" redir_addr"); + if (t->spool_cnt == 0) + printf(" %s", inet_ntoa(t->laddr)); + else + for (i=0; i<t->spool_cnt; i++) { + s = (struct cfg_spool *)&buf[off]; + if (i) + printf(","); + else + printf(" "); + printf("%s", inet_ntoa(s->addr)); + off += sof_spool; + } + printf(" %s", inet_ntoa(t->paddr)); + break; + case REDIR_PORT: + p = getprotobynumber(t->proto); + printf(" redir_port %s ", p->p_name); + if (!t->spool_cnt) { + printf("%s:%u", inet_ntoa(t->laddr), t->lport); + if (t->pport_cnt > 1) + printf("-%u", t->lport+t->pport_cnt-1); + } else + for (i=0; i<t->spool_cnt; i++) { + s = (struct cfg_spool *)&buf[off]; + if (i) + printf(","); + printf("%s:%u", inet_ntoa(s->addr), s->port); + off += sof_spool; + } + + printf(" "); + if (t->paddr.s_addr) + printf("%s:", inet_ntoa(t->paddr)); + printf("%u", t->pport); + if (!t->spool_cnt && t->pport_cnt>1) + printf("-%u", t->pport+t->pport_cnt-1); + + if (t->raddr.s_addr) { + printf(" %s", inet_ntoa(t->raddr)); + if (t->rport) { + printf(":%u", t->rport); + if (!t->spool_cnt && t->rport_cnt>1) + printf("-%u", t->rport+t->rport_cnt-1); + } + } + break; + case REDIR_PROTO: + p = getprotobynumber(t->proto); + printf(" redir_proto %s %s", p->p_name, + inet_ntoa(t->laddr)); + if (t->paddr.s_addr != 0) { + printf(" %s", inet_ntoa(t->paddr)); + if (t->raddr.s_addr) + printf(" %s", inet_ntoa(t->raddr)); + } + break; + default: + errx(EX_DATAERR, "unknown redir mode"); + break; + } + } + printf("\n"); + } + + static void + config_nat(int ac, char **av) + { + struct cfg_nat *n; /* nat instance configuration */ + struct in_addr ip; + int i, len = NAT_BUF_LEN; + /* offset in buf: save space for a n at the beginning */ + int off=sizeof(*n); + char *id, buf[NAT_BUF_LEN]; /* buffer for serialized data */ + + memset(buf, 0, sizeof(buf)); + n = (struct cfg_nat *)buf; + + av++; ac--; + /* Nat id */ + if (ac && isdigit(**av)) { + id = *av; + i = atoi(*av); av++; ac--; + n->id = i; + } else errx(EX_DATAERR, "missing nat id"); + if (ac == 0) errx(EX_DATAERR, "missing option"); + + while (ac > 0) { + int tok = match_token(nat_params, *av); + int sof_redir = sizeof(struct cfg_redir); + + ac--; av++; + + switch(tok) { + case TOK_IP: + if (ac == 0) errx(EX_DATAERR, "missing option"); + if (!inet_aton(av[0], &(n->ip))) + errx(EX_DATAERR, "bad ip address ``%s''", av[0]); + ac--; av++; + break; + + case TOK_IF: + set_addr_dynamic(av[0], n); + ac--; av++; + break; + + case TOK_LOG: + n->mode |= PKT_ALIAS_LOG; + break; + + case TOK_DENY_INC: + n->mode |= PKT_ALIAS_DENY_INCOMING; + break; + + case TOK_SAME_PORTS: + n->mode |= PKT_ALIAS_SAME_PORTS; + break; + + case TOK_UNREG_ONLY: + n->mode |= PKT_ALIAS_UNREGISTERED_ONLY; + break; + + case TOK_RESET_ADDR: + n->mode |= PKT_ALIAS_RESET_ON_ADDR_CHANGE; + break; + + case TOK_ALIAS_REV: + n->mode |= PKT_ALIAS_REVERSE; + break; + + case TOK_PROXY_ONLY: + n->mode |= PKT_ALIAS_PROXY_ONLY; + break; + + /* + * all the setup_redir_* functions work directly in the final + * buffer, see above for details + */ + case TOK_REDIR_ADDR: + case TOK_REDIR_PORT: + case TOK_REDIR_PROTO: + switch(tok) { + case TOK_REDIR_ADDR: + i = setup_redir_addr(&buf[off], len, &ac, &av); + break; + + case TOK_REDIR_PORT: + i = setup_redir_port(&buf[off], len, &ac, &av); + break; + + case TOK_REDIR_PROTO: + i = setup_redir_proto(&buf[off], len, &ac, &av); + break; + } + n->redir_cnt++; + off += i; + len -= i; + break; + + default: + errx(EX_DATAERR, "unrecognised option ``%s''", av[-1]); + } + } + + i = do_cmd(IP_FW_NAT_CFG, buf, off); + if (i) + err(1, "setsockopt(%s)", "IP_FW_NAT_CFG"); + + /* after every rule modification, we show the resultant rule */ + int _ac = 3; + char *_av[] = {"show", "config", id}; + show_nat(_ac, _av); + } + static void config_pipe(int ac, char **av) { *************** *** 3999,4004 **** --- 4793,4806 ---- ac++; av--; /* go back... */ break; + case TOK_NAT: + action->opcode = O_NAT; + action->len = F_INSN_SIZE(ipfw_insn_nat); + NEED1("missing nat number"); + action->arg1 = strtoul(*av, NULL, 10); + ac--; av++; + break; + default: errx(EX_DATAERR, "invalid action %s\n", av[-1]); } *************** *** 4942,4947 **** --- 5744,5811 ---- errx(EX_USAGE, "invalid table command %s", *av); } + static void + show_nat(int ac, char **av) { + struct cfg_nat *n; + struct cfg_redir *e; + int cmd, i, nbytes, do_cfg, do_rule = 0, frule, lrule, nalloc = 1024, + size = 0, loop, r; + u_int8_t *data = NULL, *p; + char **lav, *endptr; + + av++; ac--; + + /* parse parameters */ + for (cmd = IP_FW_NAT_GET_LOG, do_cfg = 0; ac != 0; ac--, av++) { + if (!strncmp(av[0], "config", strlen(av[0]))) { + cmd = IP_FW_NAT_GET_CONFIG, do_cfg = 1; continue; + } + /* convert command line rule # */ + frule = lrule = strtoul(av[0], &endptr, 10); + if (*endptr == '-') + lrule = strtoul(endptr+1, &endptr, 10); + if (lrule == 0) + err(EX_USAGE, "invalid rule number: %s", av[0]); + do_rule = 1; + } + + nbytes = nalloc; + while (nbytes >= nalloc) { + nalloc = nalloc * 2; + nbytes = nalloc; + if ((data = realloc(data, nbytes)) == NULL) + err(EX_OSERR, "realloc"); + if (do_cmd(cmd, data, (uintptr_t)&nbytes) < 0) + err(EX_OSERR, "getsockopt(IP_FW_GET_%s)", + (cmd == IP_FW_NAT_GET_LOG) ? "LOG" : "CONFIG"); + } + if (nbytes == 0) exit(0); + if (do_cfg) { + for (i = 0, loop = 1; loop; ) { + n = (struct cfg_nat *)&data[i]; + if (n->next == NULL) loop = 0; + if (do_rule) + if (!(frule <= n->id && lrule >= n->id)) continue; + print_nat_config(&data[i]); + i += sizeof(struct cfg_nat); + e = (struct cfg_redir *)&data[i]; + if (e->mode == REDIR_ADDR || e->mode == REDIR_PORT || + e->mode == REDIR_PROTO) + i += sizeof(struct cfg_redir) + e->spool_cnt * + sizeof(struct cfg_spool); + } + } else { + for (i = 0; 1; i += LIBALIAS_BUF_SIZE + sizeof(int)) { + p = &data[i]; + if (p == data + nbytes) break; + bcopy(p, &r, sizeof(int)); + if (do_rule) + if (!(frule <= r && lrule >= r)) continue; + printf("nat %u: %s\n", r, p+sizeof(int)); + } + } + } + /* * Called with the arguments (excluding program name). * Returns 0 if successful, 1 if empty command, errx() in case of errors. *************** *** 5130,5154 **** } /* ! * optional: pipe or queue */ do_pipe = 0; ! if (_substrcmp(*av, "pipe") == 0) do_pipe = 1; else if (_substrcmp(*av, "queue") == 0) do_pipe = 2; ! if (do_pipe) { ac--; av++; } NEED1("missing command"); /* ! * For pipes and queues we normally say 'pipe NN config' ! * but the code is easier to parse as 'pipe config NN' * so we swap the two arguments. */ ! if (do_pipe > 0 && ac > 1 && isdigit(*av[0])) { char *p = av[0]; av[0] = av[1]; --- 5994,6021 ---- } /* ! * optional: pipe, queue or nat */ + do_nat = 0; do_pipe = 0; ! if (!strncmp(*av, "nat", strlen(*av))) ! do_nat = 1; ! else if (!strncmp(*av, "pipe", strlen(*av))) do_pipe = 1; else if (_substrcmp(*av, "queue") == 0) do_pipe = 2; ! if (do_pipe || do_nat) { ac--; av++; } NEED1("missing command"); /* ! * For pipes, queues and nats we normally say 'nat|pipe NN config' ! * but the code is easier to parse as 'nat|pipe config NN' * so we swap the two arguments. */ ! if ((do_pipe || do_nat) && ac > 1 && isdigit(*av[0])) { char *p = av[0]; av[0] = av[1]; *************** *** 5157,5164 **** --- 6024,6035 ---- if (_substrcmp(*av, "add") == 0) add(ac, av); + else if (do_nat && _substrcmp(*av, "show") == 0) + show_nat(ac, av); else if (do_pipe && _substrcmp(*av, "config") == 0) config_pipe(ac, av); + else if (do_nat && _substrcmp(*av, "config") == 0) + config_nat(ac, av); else if (_substrcmp(*av, "delete") == 0) delete(ac, av); else if (_substrcmp(*av, "flush") == 0) diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sbin/natd/natd.c /home/flag/src/freebsd7/src/sbin/natd/natd.c *** /home/flag/src/freebsd7_vanilla/src/sbin/natd/natd.c Mon May 2 12:13:38 2005 --- /home/flag/src/freebsd7/src/sbin/natd/natd.c Sun Jun 11 18:57:26 2006 *************** *** 349,354 **** --- 349,358 ---- siginterrupt(SIGHUP, 1); signal (SIGTERM, InitiateShutdown); signal (SIGHUP, RefreshAddr); + + /* Load all libalias modules */ + LibAliasRefreshModules(); + /* * Set alias address if it has been given. */ *************** *** 970,976 **** static void RefreshAddr (int sig __unused) { ! if (mip->ifName) mip->assignAliasAddr = 1; } --- 974,981 ---- static void RefreshAddr (int sig __unused) { ! LibAliasRefreshModules(); ! if (mip && mip->ifName) mip->assignAliasAddr = 1; } diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/conf/files /home/flag/src/freebsd7/src/sys/conf/files *** /home/flag/src/freebsd7_vanilla/src/sys/conf/files Fri Jun 9 08:13:45 2006 --- /home/flag/src/freebsd7/src/sys/conf/files Sun Jun 11 18:57:26 2006 *************** *** 1702,1717 **** netinet/tcp_usrreq.c optional inet netinet/udp_usrreq.c optional inet netinet/libalias/alias.c optional libalias - netinet/libalias/alias_cuseeme.c optional libalias netinet/libalias/alias_db.c optional libalias - netinet/libalias/alias_ftp.c optional libalias - netinet/libalias/alias_irc.c optional libalias - netinet/libalias/alias_nbt.c optional libalias - netinet/libalias/alias_pptp.c optional libalias netinet/libalias/alias_proxy.c optional libalias - netinet/libalias/alias_skinny.c optional libalias - netinet/libalias/alias_smedia.c optional libalias netinet/libalias/alias_util.c optional libalias netinet6/ah_aesxcbcmac.c optional ipsec netinet6/ah_core.c optional ipsec netinet6/ah_input.c optional ipsec --- 1702,1712 ---- netinet/tcp_usrreq.c optional inet netinet/udp_usrreq.c optional inet netinet/libalias/alias.c optional libalias netinet/libalias/alias_db.c optional libalias netinet/libalias/alias_proxy.c optional libalias netinet/libalias/alias_util.c optional libalias + netinet/libalias/alias_old.c optional libalias + netinet/libalias/alias_mod.c optional libalias netinet6/ah_aesxcbcmac.c optional ipsec netinet6/ah_core.c optional ipsec netinet6/ah_input.c optional ipsec diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/Makefile /home/flag/src/freebsd7/src/sys/modules/libalias/Makefile *** /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/Makefile Mon Jun 20 10:33:29 2005 --- /home/flag/src/freebsd7/src/sys/modules/libalias/Makefile Sun Jun 11 18:57:26 2006 *************** *** 1,33 **** ! # $FreeBSD: src/sys/modules/libalias/Makefile,v 1.2 2005/06/20 08:33:29 glebius Exp $ ! .PATH: ${.CURDIR}/../../netinet/libalias ! ! KMOD= libalias ! SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \ ! alias_nbt.c alias_pptp.c alias_proxy.c alias_skinny.c alias_smedia.c \ ! alias_util.c ! INCS= alias.h ! ! EXPORT_SYMS= LibAliasInit \ ! LibAliasUninit \ ! LibAliasSetAddress \ ! LibAliasSetMode \ ! LibAliasSkinnyPort \ ! LibAliasIn \ ! LibAliasOut \ ! LibAliasRedirectPort \ ! LibAliasRedirectAddr \ ! LibAliasAddServer \ ! LibAliasRedirectDynamic \ ! LibAliasRedirectDelete \ ! LibAliasProxyRule \ ! LibAliasRedirectProto \ ! LibAliasSaveFragment \ ! LibAliasGetFragment \ ! LibAliasFragmentIn \ ! LibAliasSetTarget \ ! LibAliasCheckNewLink \ ! LibAliasInternetChecksum \ ! LibAliasUnaliasOut ! ! .include <bsd.kmod.mk> --- 1,11 ---- ! SUBDIR= kld-cuseeme \ ! kld-dummy \ ! kld-ftp \ ! kld-irc \ ! kld-libalias \ ! kld-nbt \ ! kld-pptp \ ! kld-skinny \ ! kld-smedia ! .include <bsd.subdir.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-cuseeme/Makefile /home/flag/src/freebsd7/src/sys/modules/libalias/kld-cuseeme/Makefile *** /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-cuseeme/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/sys/modules/libalias/kld-cuseeme/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,9 ---- + .PATH: ${.CURDIR}/../../../netinet/libalias + + KMOD= alias_cuseeme + SRCS= alias_cuseeme.c + INCS= alias.h + + CFLAGS+= -Werror + + .include <bsd.kmod.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-dummy/Makefile /home/flag/src/freebsd7/src/sys/modules/libalias/kld-dummy/Makefile *** /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-dummy/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/sys/modules/libalias/kld-dummy/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,9 ---- + .PATH: ${.CURDIR}/../../../netinet/libalias + + KMOD= alias_dummy + SRCS= alias_dummy.c + INCS= alias.h + + CFLAGS+= -Werror + + .include <bsd.kmod.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-ftp/Makefile /home/flag/src/freebsd7/src/sys/modules/libalias/kld-ftp/Makefile *** /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-ftp/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/sys/modules/libalias/kld-ftp/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,9 ---- + .PATH: ${.CURDIR}/../../../netinet/libalias + + KMOD= alias_ftp + SRCS= alias_ftp.c + INCS= alias.h + + CFLAGS+= -Werror + + .include <bsd.kmod.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-irc/Makefile /home/flag/src/freebsd7/src/sys/modules/libalias/kld-irc/Makefile *** /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-irc/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/sys/modules/libalias/kld-irc/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,9 ---- + .PATH: ${.CURDIR}/../../../netinet/libalias + + KMOD= alias_irc + SRCS= alias_irc.c + INCS= alias.h + + CFLAGS+= -Werror + + .include <bsd.kmod.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-libalias/Makefile /home/flag/src/freebsd7/src/sys/modules/libalias/kld-libalias/Makefile *** /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-libalias/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/sys/modules/libalias/kld-libalias/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,33 ---- + .PATH: ${.CURDIR}/../../../netinet/libalias + + KMOD= libalias + SRCS= alias.c alias_db.c alias_proxy.c alias_util.c alias_old.c alias_mod.c + INCS= alias.h + + EXPORT_SYMS= LibAliasInit \ + LibAliasUninit \ + LibAliasSetAddress \ + LibAliasSetMode \ + LibAliasSkinnyPort \ + LibAliasIn \ + LibAliasOut \ + LibAliasRedirectPort \ + LibAliasRedirectAddr \ + LibAliasAddServer \ + LibAliasRedirectDynamic \ + LibAliasRedirectDelete \ + LibAliasProxyRule \ + LibAliasRedirectProto \ + LibAliasSaveFragment \ + LibAliasGetFragment \ + LibAliasFragmentIn \ + LibAliasSetTarget \ + LibAliasCheckNewLink \ + LibAliasInternetChecksum \ + LibAliasUnaliasOut \ + attach_handler \ + detach_handler + + CFLAGS+= -Werror + + .include <bsd.kmod.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-nbt/Makefile /home/flag/src/freebsd7/src/sys/modules/libalias/kld-nbt/Makefile *** /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-nbt/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/sys/modules/libalias/kld-nbt/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,9 ---- + .PATH: ${.CURDIR}/../../../netinet/libalias + + KMOD= alias_nbt + SRCS= alias_nbt.c + INCS= alias.h + + CFLAGS+= -Werror + + .include <bsd.kmod.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-pptp/Makefile /home/flag/src/freebsd7/src/sys/modules/libalias/kld-pptp/Makefile *** /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-pptp/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/sys/modules/libalias/kld-pptp/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,9 ---- + .PATH: ${.CURDIR}/../../../netinet/libalias + + KMOD= alias_pptp + SRCS= alias_pptp.c + INCS= alias.h + + CFLAGS+= -Werror + + .include <bsd.kmod.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-skinny/Makefile /home/flag/src/freebsd7/src/sys/modules/libalias/kld-skinny/Makefile *** /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-skinny/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/sys/modules/libalias/kld-skinny/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,9 ---- + .PATH: ${.CURDIR}/../../../netinet/libalias + + KMOD= alias_skinny + SRCS= alias_skinny.c + INCS= alias.h + + CFLAGS+= -Werror + + .include <bsd.kmod.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-smedia/Makefile /home/flag/src/freebsd7/src/sys/modules/libalias/kld-smedia/Makefile *** /home/flag/src/freebsd7_vanilla/src/sys/modules/libalias/kld-smedia/Makefile Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/sys/modules/libalias/kld-smedia/Makefile Sun Jun 11 18:57:26 2006 *************** *** 0 **** --- 1,9 ---- + .PATH: ${.CURDIR}/../../../netinet/libalias + + KMOD= alias_smedia + SRCS= alias_smedia.c + INCS= alias.h + + CFLAGS+= -Werror + + .include <bsd.kmod.mk> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/in.h /home/flag/src/freebsd7/src/sys/netinet/in.h *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/in.h Sun May 14 16:22:49 2006 --- /home/flag/src/freebsd7/src/sys/netinet/in.h Sun Jun 11 18:57:26 2006 *************** *** 410,415 **** --- 410,420 ---- #define IP_FW_GET 54 /* get entire firewall rule chain */ #define IP_FW_RESETLOG 55 /* reset logging counters */ + #define IP_FW_NAT_CFG 56 /* add/config a nat rule */ + #define IP_FW_NAT_DEL 57 /* delete a nat rule */ + #define IP_FW_NAT_GET_CONFIG 58 /* get configuration of a nat rule */ + #define IP_FW_NAT_GET_LOG 59 /* get log of a nat rule */ + #define IP_DUMMYNET_CONFIGURE 60 /* add/configure a dummynet pipe */ #define IP_DUMMYNET_DEL 61 /* delete a dummynet pipe from chain */ #define IP_DUMMYNET_FLUSH 62 /* flush dummynet */ diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/ip_fw.h /home/flag/src/freebsd7/src/sys/netinet/ip_fw.h *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/ip_fw.h Wed May 24 15:09:55 2006 --- /home/flag/src/freebsd7/src/sys/netinet/ip_fw.h Sun Jun 11 18:57:26 2006 *************** *** 124,129 **** --- 124,130 ---- O_TEE, /* arg1=port number */ O_FORWARD_IP, /* fwd sockaddr */ O_FORWARD_MAC, /* fwd mac */ + O_NAT, /* nope */ /* * More opcodes. *************** *** 307,312 **** --- 308,372 ---- u_int32_t log_left; /* how many left to log */ } ipfw_insn_log; + /* + * "syntactic sugar for compiler": used in HOOK_REDIR|SPOOL in ip_fw2.c. + * + * WARNING: don't move the field "next" in the subsequent cfg_* structs, + * it has to be the first. + */ + struct _chain { + struct _chain *next; + }; + + /* Server pool support (LSNAT) */ + struct cfg_spool { + struct cfg_spool *next; /* chain of spool instances */ + struct in_addr addr; + u_short port; + }; + + /* Redirect modes id */ + #define REDIR_ADDR 0x01 + #define REDIR_PORT 0x02 + #define REDIR_PROTO 0x04 + + /* Nat redirect configuration */ + struct cfg_redir { + struct cfg_redir *next; /* chain of redir instances */ + u_int16_t mode; /* type of redirect mode */ + struct in_addr laddr; /* local ip address */ + struct in_addr paddr; /* public ip address */ + struct in_addr raddr; /* remote ip address */ + u_short lport; /* local port */ + u_short pport; /* public port */ + u_short rport; /* remote port */ + u_short pport_cnt; /* number of public ports */ + u_short rport_cnt; /* number of remote ports */ + int proto; /* protocol: tcp/udp */ + struct alias_link **alink; + u_int16_t spool_cnt; /* number of entry in spool chain */ + struct cfg_spool *spool_chain; /* chain of spool instances */ + }; + + #define NAT_BUF_LEN 1024 + /* Nat configuration data struct */ + struct cfg_nat { + struct cfg_nat *next; /* chain of nat instances */ + int id; /* nat id */ + struct in_addr ip; /* nat ip address */ + char if_name[IF_NAMESIZE]; /* interface name */ + int mode; /* aliasing mode */ + struct libalias *lib; /* libalias instance */ + int redir_cnt; /* number of entry in spool chain */ + struct cfg_redir *redir_chain; /* chain of redir instances */ + }; + + /* Nat command */ + typedef struct _ipfw_insn_nat { + ipfw_insn o; + struct cfg_nat *nat; + } ipfw_insn_nat; + /* Apply ipv6 mask on ipv6 addr */ #define APPLY_MASK(addr,mask) \ (addr)->__u6_addr.__u6_addr32[0] &= (mask)->__u6_addr.__u6_addr32[0]; \ *************** *** 483,488 **** --- 543,549 ---- IP_FW_DUMMYNET, IP_FW_NETGRAPH, IP_FW_NGTEE, + IP_FW_NAT, }; /* flags for divert mtag */ diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/ip_fw2.c /home/flag/src/freebsd7/src/sys/netinet/ip_fw2.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/ip_fw2.c Thu Jun 8 13:27:45 2006 --- /home/flag/src/freebsd7/src/sys/netinet/ip_fw2.c Sun Jun 11 18:57:26 2006 *************** *** 46,51 **** --- 46,52 ---- #include <sys/param.h> #include <sys/systm.h> #include <sys/condvar.h> + #include <sys/eventhandler.h> #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/kernel.h> *************** *** 55,60 **** --- 56,62 ---- #include <sys/proc.h> #include <sys/rwlock.h> #include <sys/socket.h> + #include <sys/types.h> #include <sys/socketvar.h> #include <sys/sysctl.h> #include <sys/syslog.h> *************** *** 78,84 **** #include <netinet/tcpip.h> #include <netinet/udp.h> #include <netinet/udp_var.h> ! #include <netgraph/ng_ipfw.h> #include <altq/if_altq.h> --- 80,87 ---- #include <netinet/tcpip.h> #include <netinet/udp.h> #include <netinet/udp_var.h> ! #include <netinet/libalias/alias.h> ! #include <netinet/libalias/alias_local.h> #include <netgraph/ng_ipfw.h> #include <altq/if_altq.h> *************** *** 296,301 **** --- 299,360 ---- #endif /* INET6 */ #endif /* SYSCTL_NODE */ + MODULE_DEPEND(ipfw, libalias, 1, 1, 1); + + struct _nat_chain { + struct cfg_nat *chain; + struct mtx mtx; /* lock guarding rule list */ + int busy_count; /* busy count for rw locks */ + int want_write; + struct cv cv; + } nat_chain; + + #define NAT_LOCK_INIT(_chain) \ + mtx_init(&(_chain)->mtx, "NAT instances", NULL, \ + MTX_DEF | MTX_RECURSE) + #define NAT_LOCK_DESTROY(_chain) mtx_destroy(&(_chain)->mtx) + #define NAT_WLOCK_ASSERT(_chain) do { \ + mtx_assert(&(_chain)->mtx, MA_OWNED); \ + NET_ASSERT_GIANT(); \ + } while (0) + + static __inline void + NAT_RLOCK(struct _nat_chain *chain) + { + mtx_lock(&chain->mtx); + chain->busy_count++; + mtx_unlock(&chain->mtx); + } + + static __inline void + NAT_RUNLOCK(struct _nat_chain *chain) + { + mtx_lock(&chain->mtx); + chain->busy_count--; + if (chain->busy_count == 0 && chain->want_write) + cv_signal(&chain->cv); + mtx_unlock(&chain->mtx); + } + + static __inline void + NAT_WLOCK(struct _nat_chain *chain) + { + mtx_lock(&chain->mtx); + chain->want_write++; + while (chain->busy_count > 0) + cv_wait(&chain->cv, &chain->mtx); + } + + static __inline void + NAT_WUNLOCK(struct _nat_chain *chain) + { + chain->want_write--; + cv_signal(&chain->cv); + mtx_unlock(&chain->mtx); + } + + static eventhandler_tag ifaddr_event_tag; + static int fw_deny_unknown_exthdrs = 1; *************** *** 853,858 **** --- 912,920 ---- snprintf(SNPARGS(action2, 0), "Ngtee %d", cmd->arg1); break; + case O_NAT: + action = "Nat"; + break; default: action = "UNKNOWN"; break; *************** *** 1964,1969 **** --- 2026,2294 ---- return match; } + /* FIX for 5.x and 4.x branch: m_move_pkthdr is not mbuf_cluster safe there */ + #if __FreeBSD_version > 600000 + static void + mym_move_pkthdr(struct mbuf *to, struct mbuf *from) { + m_move_pkthdr(to, from); + } + #else + /* + * "Move" mbuf pkthdr from "from" to "to". + * "from" must have M_PKTHDR set, and "to" must be empty. + */ + static void + mym_move_pkthdr(struct mbuf *to, struct mbuf *from) + { + + #ifdef MAC + /* + * XXXMAC: It could be this should also occur for non-MAC? + */ + if (to->m_flags & M_PKTHDR) + m_tag_delete_chain(to, NULL); + #endif + to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT); + if ((to->m_flags & M_EXT) == 0) + to->m_data = to->m_pktdat; + to->m_pkthdr = from->m_pkthdr; /* especially tags */ + SLIST_INIT(&from->m_pkthdr.tags); /* purge tags from src */ + from->m_flags &= ~M_PKTHDR; + } + #endif + + /* + * m_megapullup() function is a big hack. (from ng_nat.c) + * + * It allocates an mbuf with cluster and copies the whole + * chain into cluster, so that it is all contigous and the + * whole packet can be accessed via char pointer. + * This is required, because libalias doesn't have idea + * about mbufs. + * + * On success, m_megapullup returns an mbuf with cluster + * containing the input packet, on failure NULL. + * In both cases, the input packet is consumed. + */ + static struct mbuf * + m_megapullup(struct mbuf *m, int len) { + struct mbuf *mcl; + caddr_t cp; + + if (len > MCLBYTES) + goto bad; + + if ((mcl = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR)) == NULL) + goto bad; + + cp = mtod(mcl, caddr_t); + m_copydata(m, 0, len, cp); + mym_move_pkthdr(mcl, m); + mcl->m_len = mcl->m_pkthdr.len; + m_freem(m); + + return (mcl); + bad: + m_freem(m); + return (NULL); + } + + static void + flush_nat_ptrs(const int i) { + struct ip_fw *rule; + + IPFW_WLOCK(&layer3_chain); + for (rule = layer3_chain.rules; rule; rule = rule->next) { + ipfw_insn_nat *cmd = (ipfw_insn_nat *)ACTION_PTR(rule); + + if (cmd->o.opcode != O_NAT) + continue; + if (cmd->nat != NULL && cmd->nat->id == i) + cmd->nat = NULL; + } + IPFW_WUNLOCK(&layer3_chain); + } + + static struct cfg_nat * + lookup_nat(const int i) { + struct cfg_nat *ptr; + + for (ptr = nat_chain.chain; ptr != NULL; ptr = ptr->next) + if (ptr->id == i) return(ptr); + return(NULL); + } + + /* attach p to b chain */ + static void + hook_entry(struct _chain **b, struct _chain *p) { + + /* XXX better to make an in-order addition... */ + for(; *b != NULL; b = &((*b)->next)) + ; + *b = p; + } + + /* remove p from b chain */ + static void + unhook_entry(struct _chain **b, struct _chain *p) { + + NAT_WLOCK_ASSERT(&nat_chain); + for(; *b != p; b = &((*b)->next)) + ; + *b = p->next; + } + + #define HOOK_NAT(b, p) do { \ + NAT_WLOCK_ASSERT(&nat_chain); \ + hook_entry((struct _chain **)b, (struct _chain *)p); \ + } while (0) + + #define UNHOOK_NAT(b, p) do { \ + NAT_WLOCK_ASSERT(&nat_chain); \ + unhook_entry((struct _chain **)b, (struct _chain *)p); \ + } while (0) + + #define HOOK_REDIR(b, p) do { \ + hook_entry((struct _chain **)b, (struct _chain *)p); \ + } while (0) + + #define HOOK_SPOOL(b, p) do { \ + hook_entry((struct _chain **)b, (struct _chain *)p); \ + } while (0) + + static void + del_redir_spool_cfg(struct cfg_nat *n, struct cfg_redir *r) { + struct cfg_redir *tmp_r; + struct cfg_spool *tmp_s; + int i, num; + + while(r) { + num = 1; /* number of alias_link to delete */ + switch(r->mode) { + case REDIR_PORT: + num = r->pport_cnt; + case REDIR_ADDR: + case REDIR_PROTO: + /* delete all libalias redirect entry */ + for (i = 0; i < num; i++) + LibAliasRedirectDelete(n->lib, + r->alink[i]); + /* del spool cfg if any */ + while(r->spool_chain) { + tmp_s = r->spool_chain->next; + free(r->spool_chain, M_IPFW); + r->spool_chain = tmp_s; + } + tmp_r = r->next; + free(r->alink, M_IPFW); + free(r, M_IPFW); + r = tmp_r; + break; + default: + printf("unknown redirect mode: %u\n", r->mode); + /* XXX - panic?!?!? */ + break; + } + } + n->redir_chain = NULL; + } + + static int + add_redir_spool_cfg(char *buf, struct cfg_nat *ptr) { + int sof_alinkp = sizeof(struct alias_link *); + int sof_redir = sizeof(struct cfg_redir); + int sof_spool = sizeof(struct cfg_spool); + struct cfg_redir *r, *ser_r; + struct cfg_spool *s, *ser_s; + int cnt, off, i; + + for(cnt=0, off = 0; cnt<ptr->redir_cnt; cnt++) { + ser_r = (struct cfg_redir *)&buf[off]; + r = malloc(sof_redir, M_IPFW, M_NOWAIT | M_ZERO); + if (r == NULL) { + /* try to recover: + * set the actual number of redir entries + * that were hooked succesfully + */ + ptr->redir_cnt = cnt; + del_redir_spool_cfg(ptr, ptr->redir_chain); + // XXX - NAT_WUNLOCK... + return (ENOSPC); + } + memcpy(r, ser_r, sof_redir); + off += sof_redir; + r->alink = malloc(sof_alinkp*r->pport_cnt, + M_IPFW, M_NOWAIT | M_ZERO); + if (r->alink == NULL) { + r->pport_cnt = 0; + del_redir_spool_cfg(ptr, ptr->redir_chain); + // XXX - NAT_WUNLOCK... + return (ENOSPC); + } + switch(r->mode) { + case REDIR_ADDR: + { + r->alink[0] = LibAliasRedirectAddr(ptr->lib, + r->laddr, + r->paddr); + } + break; + case REDIR_PORT: + for (i = 0 ; i < r->pport_cnt; i++) { + /* If remotePort is all ports, set it to 0. */ + u_short remotePortCopy = r->rport + i; + if (r->rport_cnt == 1 && r->rport == 0) + remotePortCopy = 0; + r->alink[i] = LibAliasRedirectPort (ptr->lib, r->laddr, + htons(r->lport + i), + r->raddr, + htons(remotePortCopy), + r->paddr, + htons(r->pport + i), + r->proto); + if (r->alink[i] == NULL) { + r->alink[0] = NULL; + break; + } + } + break; + case REDIR_PROTO: + r->alink[0] = LibAliasRedirectProto(ptr->lib, + r->laddr, + r->raddr, + r->paddr, + r->proto); + break; + default: + printf("unknown redirect mode: %u\n", r->mode); + break; + } + if (r->alink[0] == NULL) { /* panic?!?!? */ + free(r->alink, M_IPFW); + printf("previous LibAliasRedirect* returned NULL!!!\n"); + } else /* handles LSNAT */ + for (i=0; i<r->spool_cnt; i++) { + ser_s = (struct cfg_spool *)&buf[off]; + s = malloc(sof_redir, M_IPFW, M_NOWAIT | M_ZERO); + if (s == NULL) { + r->spool_cnt = i; + del_redir_spool_cfg(ptr, r); + return (ENOSPC); + } + memcpy(s, ser_s, sof_spool); + LibAliasAddServer(ptr->lib, r->alink[0], // XXX - what about RedirectPort with many alink? + s->addr, + htons(s->port)); + off += sof_spool; + /* hook spool entry */ + HOOK_SPOOL(&r->spool_chain, s); + } + /* and finally hook this redir entry */ + HOOK_REDIR(&ptr->redir_chain, r); + } + return(1); + } + /* * The main check routine for the firewall. * *************** *** 3138,3143 **** --- 3463,3625 ---- IP_FW_NETGRAPH : IP_FW_NGTEE; goto done; + case O_NAT: { + struct cfg_nat *t; + struct mbuf *mcl; + /* XXX - libalias duct tape */ + int ldt = 0; + char *c; + + args->rule = f; /* report matching rule */ + retval = 0; + t = ((ipfw_insn_nat *)cmd)->nat; + if (t == NULL) { + NAT_RLOCK(&nat_chain); + t = lookup_nat(cmd->arg1); + if (t == NULL) { + retval = IP_FW_DENY; + goto done; + } else ((ipfw_insn_nat *)cmd)->nat = t; + } + if ((mcl = m_megapullup(m, m->m_pkthdr.len)) == NULL) + goto badnat; + ip = mtod(mcl, struct ip *); + /* + * XXX - workaround for host-byte-order 4.x BSD well_known_bug: + * due to 4.x BSD legacy, some fields in layer-3 packet COULD be + * in host byte order instead of network byte order, so we have + * to manually swap it before passing mbuf to libalias... + */ + if (args->eh == NULL) { /* host byte order */ + ip->ip_len = htons(ip->ip_len); + ip->ip_off = htons(ip->ip_off); + } + + /* + * XXX - libalias checksum offload 'duct tape': + * + * locally generated packets have only pseudo-header + * checksum calculated and libalias will screw it[1], + * so mark them for later fix. + * Moreover there are cases when libalias modify tcp + * packet data[2], mark it for later fix too. + * + * [1] libalias was never meant to run in kernel, so + * it doesn't have any knowledge about checksum + * offloading, and it expects a packet with a full + * internet checksum. Unfortunately, packets + * generated locally will have just the pseudo + * header calculated, and when libalias tries to + * adjust the checksum it will actually screw it. + * + * [2] when libalias modify tcp's data content, + * full TCP checksum has to be recomputed: + * the problem is that libalias doesn't have any + * idea about checksum offloading + * To workaround this, we do not do checksumming + * in LibAlias, but only mark the packets in th_x2 + * field. If we receive a marked packet, we + * calculate correct checksum for it aware of + * offloading. + * Why such a terrible hack instead of + * recalculating checksum for each packet? + * Because the previous checksum was not checked! + * Recalculating checksums for EVERY packet will + * hide ALL transmission errors. Yes, marked packets + * still suffer from this problem. But, sigh, natd(8) + * has this problem, too. + * + * TODO: + * -make libalias mbuf aware (so it can handle + * delayed checksum) + * -maybe shrink the api? do we really need 23 + * functions? + */ + + if (mcl->m_pkthdr.rcvif == NULL && + mcl->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + ldt = 1; + } + + c = mtod(mcl, char *); + if (oif == NULL) + retval = LibAliasIn(t->lib, c, MCLBYTES); + else + retval = LibAliasOut(t->lib, c, MCLBYTES); + if (retval != PKT_ALIAS_OK) { + /* XXX - should i add some logging ? */ + m_free(mcl); + badnat: + args->m = NULL; + retval = IP_FW_DENY; + goto done; + } + mcl->m_pkthdr.len = mcl->m_len = ntohs(ip->ip_len); + + /* + * XXX - libalias checksum offload + * 'duct tape' (see above) + */ + + if ((ip->ip_off & htons(IP_OFFMASK)) == 0 && + ip->ip_p == IPPROTO_TCP) { + struct tcphdr *th = (struct tcphdr *)(ip + 1); + + if (th->th_x2) + ldt = 1; + } + + if (ldt) { + struct tcphdr *th; + struct udphdr *uh; + u_short cksum; + + ip->ip_len = ntohs(ip->ip_len); + cksum = in_pseudo( + ip->ip_src.s_addr, + ip->ip_dst.s_addr, + htons(ip->ip_p + ip->ip_len - (ip->ip_hl << 2)) + ); + + switch(ip->ip_p) { + case IPPROTO_TCP: + th = (struct tcphdr *)(ip + 1); + /* maybe it was set in libalias... */ + th->th_x2 = 0; + th->th_sum = cksum; + mcl->m_pkthdr.csum_data = + offsetof(struct tcphdr, + th_sum); + break; + case IPPROTO_UDP: + uh = (struct udphdr *)(ip + 1); + uh->uh_sum = cksum; + mcl->m_pkthdr.csum_data = + offsetof(struct udphdr, + uh_sum); + break; + + } + /* no hw checksum offloading: do it by ourself */ + if ((mcl->m_pkthdr.csum_flags & CSUM_DELAY_DATA) == 0) { + in_delayed_cksum(mcl); + mcl->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; + } + ip->ip_len = htons(ip->ip_len); + } + + /* XXX - swap again some fields... see above */ + if (args->eh == NULL) { /* host byte order */ + ip->ip_len = ntohs(ip->ip_len); + ip->ip_off = ntohs(ip->ip_off); + } + + args->m = mcl; + retval = IP_FW_NAT; + NAT_RUNLOCK(&nat_chain); + goto done; + } + default: panic("-- unknown opcode %d\n", cmd->opcode); } /* end of switch() on opcodes */ *************** *** 3707,3712 **** --- 4189,4198 ---- return EINVAL; else goto check_size; + case O_NAT: + if (cmdlen != F_INSN_SIZE(ipfw_insn_nat)) + goto bad_size; + goto check_action; case O_FORWARD_MAC: /* XXX not implemented yet */ case O_CHECK_STATE: case O_COUNT: *************** *** 3860,3865 **** --- 4346,4377 ---- } + static void + ifaddr_change(void *arg __unused, struct ifnet *ifp) { + struct cfg_nat *ptr; + struct ifaddr *ifa; + + NAT_WLOCK(&nat_chain); + /* find every nat entry...*/ + for (ptr = nat_chain.chain; ptr; ptr = ptr->next) { + /* ...using nic 'ifp->if_xname' as dynamic alias address */ + if (strncmp(ptr->if_name, ifp->if_xname, IF_NAMESIZE) == 0) { + mtx_lock(&ifp->if_addr_mtx); + TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { + if (ifa->ifa_addr == NULL) + continue; + if (ifa->ifa_addr->sa_family != AF_INET) + continue; + ptr->ip = ((struct sockaddr_in *) + (ifa->ifa_addr))->sin_addr; + LibAliasSetAddress(ptr->lib, ptr->ip); + } + mtx_unlock(&ifp->if_addr_mtx); + } + } + NAT_WUNLOCK(&nat_chain); + } + /** * {set|get}sockopt parser. */ *************** *** 4085,4090 **** --- 4597,4750 ---- } break; + case IP_FW_NAT_CFG: + { + struct cfg_nat *ptr, *ser_n; + char *buf; + int err=0; + + buf = malloc(NAT_BUF_LEN, M_IPFW, M_NOWAIT | M_ZERO); + if (buf == NULL) + return (ENOSPC); + + error = sooptcopyin(sopt, buf, NAT_BUF_LEN, sizeof(struct cfg_nat)); + ser_n = (struct cfg_nat *)buf; + + /* FIND/CREATE NAT RULE */ + NAT_WLOCK(&nat_chain); + ptr = lookup_nat(ser_n->id); + if (ptr == NULL) { /* new rule: allocate and init new instance */ + ptr = malloc(sizeof(struct cfg_nat), M_IPFW, M_NOWAIT | M_ZERO); + if (ptr == NULL) { + free(buf, M_IPFW); + NAT_WUNLOCK(&nat_chain); + return (ENOSPC); + } + ptr->lib = LibAliasInit(NULL); + if (ptr->lib == NULL) { + free(ptr, M_IPFW); + free(buf, M_IPFW); + NAT_WUNLOCK(&nat_chain); + return(EINVAL); + } + } else { /* entry already present: temporarly unhook it */ + UNHOOK_NAT(&nat_chain.chain, ptr); + flush_nat_ptrs(ser_n->id); + } + NAT_WUNLOCK(&nat_chain); + + /* BASIC NAT CONFIGURATION */ + ptr->id = ser_n->id; + /* + * XXX - what if this rule doesn't nat any ip and just redirect? + * do we set aliasaddress to 0.0.0.0? is it correct? + */ + ptr->ip = ser_n->ip; + ptr->redir_cnt = ser_n->redir_cnt; + ptr->mode = ser_n->mode; + LibAliasSetMode(ptr->lib, ser_n->mode, ser_n->mode); + LibAliasSetAddress(ptr->lib, ptr->ip); + memcpy(ptr->if_name, ser_n->if_name, IF_NAMESIZE); + + /* REDIR AND LSNAT CONFIGURATION */ + del_redir_spool_cfg(ptr, ptr->redir_chain); /* delete old cfgs */ + err = add_redir_spool_cfg(&buf[(sizeof(struct cfg_nat))], + ptr); /* add new entries */ + free(buf, M_IPFW); + if (err == 1) { + NAT_WLOCK(&nat_chain); + HOOK_NAT(&nat_chain.chain, ptr); + NAT_WUNLOCK(&nat_chain); + } else /* something bad happened, redir cfg not added */ + return(EINVAL); + } + break; + + case IP_FW_NAT_DEL: + { + struct cfg_nat *ptr; + int i; + + error = sooptcopyin(sopt, &i, sizeof i, sizeof i); + NAT_WLOCK(&nat_chain); + ptr = lookup_nat(i); + if (ptr == NULL) { + error = EINVAL; + NAT_WUNLOCK(&nat_chain); + break; + } + UNHOOK_NAT(&nat_chain.chain, ptr); + NAT_WUNLOCK(&nat_chain); + flush_nat_ptrs(i); + del_redir_spool_cfg(ptr, ptr->redir_chain); + LibAliasUninit(ptr->lib); + free(ptr, M_IPFW); + } + break; + + case IP_FW_NAT_GET_CONFIG: + { + u_int8_t *data; + struct cfg_nat *n; + struct cfg_redir *r; + struct cfg_spool *s; + int sof_nat = sizeof(struct cfg_nat); + int sof_redir = sizeof(struct cfg_redir); + int sof_spool = sizeof(struct cfg_spool); + int off = 0; + + data = malloc(NAT_BUF_LEN, M_IPFW, M_NOWAIT | M_ZERO); + if (data == NULL) + return (ENOSPC); + NAT_RLOCK(&nat_chain); + /* serialize all the data */ + for (n = nat_chain.chain; (n && (off + sof_nat < NAT_BUF_LEN)); + n = n->next) { + bcopy(n, &data[off], sof_nat); + off += sof_nat; + for (r = n->redir_chain; (r && (off + sof_redir < NAT_BUF_LEN)); + r = r->next) { + bcopy(r, &data[off], sof_redir); + off += sof_redir; + for (s = r->spool_chain; (s && (off + sof_spool < NAT_BUF_LEN)); + s = s->next) { + bcopy(s, &data[off], sof_spool); + off += sof_spool; + } + } + } + NAT_RUNLOCK(&nat_chain); + + error = sooptcopyout(sopt, data, NAT_BUF_LEN); + free(data, M_IPFW); + } + break; + + case IP_FW_NAT_GET_LOG: + { + u_int8_t *data = NULL; + struct cfg_nat *ptr; + int sof = LIBALIAS_BUF_SIZE; + int i, size, cnt = 0; + + NAT_RLOCK(&nat_chain); + for (ptr = nat_chain.chain, size = i = 0; ptr; ptr = ptr->next) { + if (ptr->lib->logDesc == NULL) continue; + cnt++; + size = cnt * (sof + sizeof(int)); + data = realloc(data, size, M_IPFW, M_NOWAIT | M_ZERO); + if (data == NULL) return (ENOSPC); + bcopy(&ptr->id, &data[i], sizeof(int)); + i += sizeof(int); + bcopy(ptr->lib->logDesc, &data[i], sof); + i += sof; + } + NAT_RUNLOCK(&nat_chain); + error = sooptcopyout(sopt, data, size); + free(data, M_IPFW); + } + break; + default: printf("ipfw: ipfw_ctl invalid option %d\n", sopt->sopt_name); error = EINVAL; *************** *** 4256,4263 **** } ip_fw_ctl_ptr = ipfw_ctl; ip_fw_chk_ptr = ipfw_chk; ! callout_reset(&ipfw_timeout, hz, ipfw_tick, NULL); ! return (0); } --- 4916,4928 ---- } ip_fw_ctl_ptr = ipfw_ctl; ip_fw_chk_ptr = ipfw_chk; ! callout_reset(&ipfw_timeout, hz, ipfw_tick, NULL); ! nat_chain.chain = NULL; ! nat_chain.busy_count = 0; ! nat_chain.want_write = 0; ! NAT_LOCK_INIT(&nat_chain); ! ifaddr_event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_change, ! NULL, EVENTHANDLER_PRI_ANY); return (0); } *************** *** 4265,4276 **** --- 4930,4952 ---- ipfw_destroy(void) { struct ip_fw *reap; + struct cfg_nat *ptr, *ptr_temp; ip_fw_chk_ptr = NULL; ip_fw_ctl_ptr = NULL; callout_drain(&ipfw_timeout); IPFW_WLOCK(&layer3_chain); flush_tables(&layer3_chain); + NAT_WLOCK(&nat_chain); + for (ptr = nat_chain.chain; ptr; ptr = ptr_temp) { + ptr_temp = ptr->next; + del_redir_spool_cfg(ptr, ptr->redir_chain); + LibAliasUninit(ptr->lib); + free(ptr, M_IPFW); + } + NAT_WUNLOCK(&nat_chain); + EVENTHANDLER_DEREGISTER(ifaddr_event, ifaddr_event_tag); + NAT_LOCK_DESTROY(&nat_chain); layer3_chain.reap = NULL; free_chain(&layer3_chain, 1 /* kill default rule */); reap = layer3_chain.reap, layer3_chain.reap = NULL; diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/ip_fw_pfil.c /home/flag/src/freebsd7/src/sys/netinet/ip_fw_pfil.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/ip_fw_pfil.c Fri May 12 06:41:27 2006 --- /home/flag/src/freebsd7/src/sys/netinet/ip_fw_pfil.c Sun Jun 11 18:57:26 2006 *************** *** 189,194 **** --- 189,197 ---- if (!NG_IPFW_LOADED) goto drop; return ng_ipfw_input_p(m0, NG_IPFW_IN, &args, 0); + + case IP_FW_NAT: + goto again; /* continue with packet */ default: KASSERT(0, ("%s: unknown retval", __func__)); *************** *** 315,320 **** --- 318,326 ---- goto drop; return ng_ipfw_input_p(m0, NG_IPFW_OUT, &args, 0); + case IP_FW_NAT: + goto again; /* continue with packet */ + default: KASSERT(0, ("%s: unknown retval", __func__)); } diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias.c Tue Jun 28 00:21:42 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias.c Sun Jun 11 18:57:26 2006 *************** *** 113,121 **** --- 113,128 ---- #ifdef _KERNEL #include <sys/param.h> + #include <sys/proc.h> + #include <sys/types.h> + #include <sys/systm.h> #else #include <sys/types.h> + #include <stdlib.h> #include <stdio.h> + #include <dlfcn.h> + #include <errno.h> + #include <string.h> #endif #include <netinet/in_systm.h> *************** *** 128,149 **** #ifdef _KERNEL #include <netinet/libalias/alias.h> #include <netinet/libalias/alias_local.h> #else #include "alias.h" #include "alias_local.h" #endif - #define NETBIOS_NS_PORT_NUMBER 137 - #define NETBIOS_DGM_PORT_NUMBER 138 - #define FTP_CONTROL_PORT_NUMBER 21 - #define IRC_CONTROL_PORT_NUMBER_1 6667 - #define IRC_CONTROL_PORT_NUMBER_2 6668 - #define CUSEEME_PORT_NUMBER 7648 - #define RTSP_CONTROL_PORT_NUMBER_1 554 - #define RTSP_CONTROL_PORT_NUMBER_2 7070 - #define TFTP_PORT_NUMBER 69 - #define PPTP_CONTROL_PORT_NUMBER 1723 - static __inline int twowords(void *p) { --- 135,147 ---- #ifdef _KERNEL #include <netinet/libalias/alias.h> #include <netinet/libalias/alias_local.h> + #include <netinet/libalias/alias_mod.h> #else #include "alias.h" #include "alias_local.h" + #include "alias_mod.h" #endif static __inline int twowords(void *p) { *************** *** 725,748 **** struct in_addr original_address; u_short alias_port; int accumulate; ! int r = 0; alias_address = GetAliasAddress(lnk); original_address = GetOriginalAddress(lnk); alias_port = ud->uh_dport; ud->uh_dport = GetOriginalPort(lnk); ! /* Special processing for IP encoding protocols */ ! if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER) ! AliasHandleCUSeeMeIn(la, pip, original_address); ! /* If NETBIOS Datagram, It should be alias address in UDP Data, too */ ! else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER ! || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER) ! r = AliasHandleUdpNbt(la, pip, lnk, &original_address, ud->uh_dport); ! else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER ! || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER) ! r = AliasHandleUdpNbtNS(la, pip, lnk, &alias_address, &alias_port, ! &original_address, &ud->uh_dport); /* If UDP checksum is not zero, then adjust since destination port */ /* is being unaliased and destination address is being altered. */ --- 723,748 ---- struct in_addr original_address; u_short alias_port; int accumulate; ! int r = 0, err; ! struct alias_data ad = { ! lnk, ! &original_address, ! &alias_address, ! &alias_port, ! &ud->uh_sport, ! &ud->uh_dport, ! 0 /* maxpacketsize */ ! }; alias_address = GetAliasAddress(lnk); original_address = GetOriginalAddress(lnk); alias_port = ud->uh_dport; ud->uh_dport = GetOriginalPort(lnk); ! /* walk out chain */ ! err = find_handler(IN, UDP, la, pip, &ad); ! if (err == EHDNOF) ! ; /* If UDP checksum is not zero, then adjust since destination port */ /* is being unaliased and destination address is being altered. */ *************** *** 774,779 **** --- 774,780 ---- { struct udphdr *ud; struct alias_link *lnk; + int err; /* Return if proxy-only mode is enabled */ if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) *************** *** 787,815 **** if (lnk != NULL) { u_short alias_port; struct in_addr alias_address; alias_address = GetAliasAddress(lnk); alias_port = GetAliasPort(lnk); ! /* Special processing for IP encoding protocols */ ! if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER) ! AliasHandleCUSeeMeOut(la, pip, lnk); ! /* If NETBIOS Datagram, It should be alias address in UDP Data, too */ ! else if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER ! || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER) ! AliasHandleUdpNbt(la, pip, lnk, &alias_address, alias_port); ! else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER ! || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER) ! AliasHandleUdpNbtNS(la, pip, lnk, &pip->ip_src, &ud->uh_sport, ! &alias_address, &alias_port); ! /* ! * We don't know in advance what TID the TFTP server will choose, ! * so we create a wilcard link (destination port is unspecified) ! * that will match any TID from a given destination. ! */ ! else if (ntohs(ud->uh_dport) == TFTP_PORT_NUMBER) ! FindRtspOut(la, pip->ip_src, pip->ip_dst, ! ud->uh_sport, alias_port, IPPROTO_UDP); /* If UDP checksum is not zero, adjust since source port is */ /* being aliased and source address is being altered */ --- 788,810 ---- if (lnk != NULL) { u_short alias_port; struct in_addr alias_address; + struct alias_data ad = { + lnk, + NULL, /* original address */ + &alias_address, + &alias_port, + &ud->uh_sport, + &ud->uh_dport, + 0 /* maxpacketsize */ + }; alias_address = GetAliasAddress(lnk); alias_port = GetAliasPort(lnk); ! /* walk out chain */ ! err = find_handler(OUT, UDP, la, pip, &ad); ! if (err == EHDNOF) ! ; /* If UDP checksum is not zero, adjust since source port is */ /* being aliased and source address is being altered */ *************** *** 855,869 **** struct in_addr proxy_address; u_short alias_port; u_short proxy_port; ! int accumulate; ! /* Special processing for IP encoding protocols */ ! if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER ! || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER) ! AliasHandlePptpIn(la, pip, lnk); ! else if (la->skinnyPort != 0 && (ntohs(tc->th_dport) == la->skinnyPort ! || ntohs(tc->th_sport) == la->skinnyPort)) ! AliasHandleSkinny(la, pip, lnk); alias_address = GetAliasAddress(lnk); original_address = GetOriginalAddress(lnk); --- 850,878 ---- struct in_addr proxy_address; u_short alias_port; u_short proxy_port; ! int accumulate, err; ! /* ! * XXX - the init of MANY vars is a bit below, but ! * aliashandlepptpin seems to need the destination port ! * that came within the packet and not the original one ! * looks below [*] ! */ ! ! struct alias_data ad = { ! lnk, ! NULL, /* original address */ ! NULL, /* alias address */ ! NULL, /* alias port */ ! &tc->th_sport, ! &tc->th_dport, ! 0 /* maxpacketsize */ ! }; ! ! /* walk out chain */ ! err = find_handler(IN, TCP, la, pip, &ad); ! if (err == EHDNOF) ! ; alias_address = GetAliasAddress(lnk); original_address = GetOriginalAddress(lnk); *************** *** 872,877 **** --- 881,908 ---- tc->th_dport = GetOriginalPort(lnk); proxy_port = GetProxyPort(lnk); + /* + * XXX - [*] looks above, if anyone is going to add + * find_handler AFTER this aliashandlepptpin/point, please redo + * alias_data too. + * Uncommenting the piece here below should be enough. + */ + + /* struct alias_data ad = { */ + /* lnk, */ + /* &original_address, */ + /* &alias_address, */ + /* &alias_port, */ + /* &ud->uh_sport, */ + /* &ud->uh_dport, */ + /* 0 /\* maxpacketsize *\/ */ + /* }; */ + + /* /\* walk out chain *\/ */ + /* err = find_handler(la, pip, &ad); */ + /* if (err == EHDNOF) */ + /* printf("Protocol handler not found\n"); */ + /* Adjust TCP checksum since destination port is being unaliased */ /* and destination port is being altered. */ accumulate = alias_port; *************** *** 926,932 **** static int TcpAliasOut(struct libalias *la, struct ip *pip, int maxpacketsize, int create) { ! int proxy_type; u_short dest_port; u_short proxy_server_port; struct in_addr dest_address; --- 957,963 ---- static int TcpAliasOut(struct libalias *la, struct ip *pip, int maxpacketsize, int create) { ! int proxy_type, err; u_short dest_port; u_short proxy_server_port; struct in_addr dest_address; *************** *** 973,978 **** --- 1004,1018 ---- u_short alias_port; struct in_addr alias_address; int accumulate; + struct alias_data ad = { + lnk, + NULL, /* original address */ + &alias_address, + &alias_port, + &tc->th_sport, + &tc->th_dport, + maxpacketsize + }; /* Save original destination address, if this is a proxy packet. Also modify packet to include destination encoding. This may *************** *** 989,1013 **** /* Monitor TCP connection state */ TcpMonitorOut(pip, lnk); ! ! /* Special processing for IP encoding protocols */ ! if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER ! || ntohs(tc->th_sport) == FTP_CONTROL_PORT_NUMBER) ! AliasHandleFtpOut(la, pip, lnk, maxpacketsize); ! else if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1 ! || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2) ! AliasHandleIrcOut(la, pip, lnk, maxpacketsize); ! else if (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1 ! || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_1 ! || ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2 ! || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_2) ! AliasHandleRtspOut(la, pip, lnk, maxpacketsize); ! else if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER ! || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER) ! AliasHandlePptpOut(la, pip, lnk); ! else if (la->skinnyPort != 0 && (ntohs(tc->th_sport) == la->skinnyPort ! || ntohs(tc->th_dport) == la->skinnyPort)) ! AliasHandleSkinny(la, pip, lnk); /* Adjust TCP checksum since source port is being aliased */ /* and source address is being altered */ --- 1029,1039 ---- /* Monitor TCP connection state */ TcpMonitorOut(pip, lnk); ! ! /* walk out chain */ ! err = find_handler(OUT, TCP, la, pip, &ad); ! if (err == EHDNOF) ! ; /* Adjust TCP checksum since source port is being aliased */ /* and source address is being altered */ *************** *** 1208,1220 **** case IPPROTO_TCP: iresult = TcpAliasIn(la, pip); break; ! case IPPROTO_GRE: ! if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY || ! AliasHandlePptpGreIn(la, pip) == 0) iresult = PKT_ALIAS_OK; else iresult = ProtoAliasIn(la, pip); ! break; default: iresult = ProtoAliasIn(la, pip); break; --- 1234,1261 ---- case IPPROTO_TCP: iresult = TcpAliasIn(la, pip); break; ! case IPPROTO_GRE: { ! int err; ! struct alias_data ad = { ! NULL, ! NULL, ! NULL, ! NULL, ! NULL, ! NULL, ! 0 ! }; ! ! /* walk out chain */ ! err = find_handler(IN, IP, la, pip, &ad); ! if (err == EHDNOF) ! ; ! if (err == OK) iresult = PKT_ALIAS_OK; else iresult = ProtoAliasIn(la, pip); ! } ! break; default: iresult = ProtoAliasIn(la, pip); break; *************** *** 1321,1332 **** case IPPROTO_TCP: iresult = TcpAliasOut(la, pip, maxpacketsize, create); break; ! case IPPROTO_GRE: ! if (AliasHandlePptpGreOut(la, pip) == 0) ! iresult = PKT_ALIAS_OK; ! else ! iresult = ProtoAliasOut(la, pip, create); ! break; default: iresult = ProtoAliasOut(la, pip, create); break; --- 1362,1388 ---- case IPPROTO_TCP: iresult = TcpAliasOut(la, pip, maxpacketsize, create); break; ! case IPPROTO_GRE: { ! int err; ! struct alias_data ad = { ! NULL, ! NULL, ! NULL, ! NULL, ! NULL, ! NULL, ! 0 ! }; ! /* walk out chain */ ! err = find_handler(OUT, IP, la, pip, &ad); ! if (err == EHDNOF) ! ; ! if (err == OK) ! iresult = PKT_ALIAS_OK; ! else ! iresult = ProtoAliasOut(la, pip, create); ! } ! break; default: iresult = ProtoAliasOut(la, pip, create); break; *************** *** 1443,1445 **** --- 1499,1592 ---- return (iresult); } + + #ifndef _KERNEL + + int + LibAliasRefreshModules(void) { + char buf[256], conf[] = "/etc/libalias.conf"; + FILE *fd; + struct dll *t; + struct proto_handler *p; + int len; + + fd = fopen(conf, "r"); + if (fd == NULL) { + strcpy(buf, "cannot open config file "); + strcat(buf, conf); + perror(buf); + exit(-1); + } + + LibAliasUnLoadAllModule(); + + while (1) { + fgets(buf, 256, fd); + if feof(fd) break; + len = strlen(buf); + if (len > 1) { + buf[len - 1] = '\0'; + printf("Loading %s\n", buf); + LibAliasLoadModule(buf); + } + } + return (OK); + } + + int + LibAliasLoadModule(char *path) { + struct dll *t; + void *handle; + struct proto_handler *m; + const char *error; + moduledata_t *p; + + handle = dlopen (path, RTLD_LAZY); + if (!handle) { + fputs (dlerror(), stderr); + return (NOK); + } + + p = dlsym(handle, "alias_mod"); + if ((error = dlerror()) != NULL) { + fputs(error, stderr); + return (NOK); + } + + t = malloc(sizeof(struct dll)); + if (t == NULL) + return (ENOMEM); + strncpy(t->name, p->name, DLL_LEN); + t->handle = handle; + if (attach_dll(t) == EHDCON) { + free(t); + fputs("dll conflict", stderr); + return (NOK); + } + + m = dlsym(t->handle, "handlers"); + if ((error = dlerror()) != NULL) { + fputs(error, stderr); + return (NOK); + } + + attach_handlers(m); + return (OK); + } + + int + LibAliasUnLoadAllModule(void) { + struct dll *t; + struct proto_handler *p; + + /* unload all modules then reload everything */ + while ((p = first_handler()) != NULL) { + detach_handler(p); + } + while ((t = walk_dll_chain()) != NULL) { + dlclose(t->handle); + free(t); + } + } + + #endif diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias.h /home/flag/src/freebsd7/src/sys/netinet/libalias/alias.h *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias.h Thu May 5 23:53:17 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias.h Sun Jun 11 18:57:26 2006 *************** *** 39,51 **** #ifndef _ALIAS_H_ #define _ALIAS_H_ #ifdef _KERNEL /* ! * The kernel version of libalias does not support these features. */ #define NO_FW_PUNCH - #define NO_LOGGING #define NO_USE_SOCKETS #endif /* --- 39,56 ---- #ifndef _ALIAS_H_ #define _ALIAS_H_ + #include <netinet/in_systm.h> + #include <netinet/in.h> + #include <netinet/ip.h> + + #define LIBALIAS_BUF_SIZE 128 #ifdef _KERNEL /* ! * The kernel version of libalias does not support these features... */ #define NO_FW_PUNCH #define NO_USE_SOCKETS + #endif /* *************** *** 180,200 **** /* Transparent proxying routines. */ int LibAliasProxyRule(struct libalias *, const char *_cmd); /* * Mode flags and other constants. */ - /* Mode flags, set using PacketAliasSetMode() */ /* * If PKT_ALIAS_LOG is set, a message will be printed to /var/log/alias.log * every time a link is created or deleted. This is useful for debugging. */ - #ifndef NO_LOGGING #define PKT_ALIAS_LOG 0x01 - #endif /* * If PKT_ALIAS_DENY_INCOMING is set, then incoming connections (e.g. to ftp, --- 185,206 ---- /* Transparent proxying routines. */ int LibAliasProxyRule(struct libalias *, const char *_cmd); + /* Module handling API */ + int LibAliasLoadModule(char *); + int LibAliasUnLoadAllModule(void); + int LibAliasRefreshModules(void); /* * Mode flags and other constants. */ /* Mode flags, set using PacketAliasSetMode() */ /* * If PKT_ALIAS_LOG is set, a message will be printed to /var/log/alias.log * every time a link is created or deleted. This is useful for debugging. */ #define PKT_ALIAS_LOG 0x01 /* * If PKT_ALIAS_DENY_INCOMING is set, then incoming connections (e.g. to ftp, diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_cuseeme.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_cuseeme.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_cuseeme.c Thu May 5 23:55:17 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_cuseeme.c Sun Jun 11 18:57:26 2006 *************** *** 31,37 **** --- 31,47 ---- #ifdef _KERNEL #include <sys/param.h> + #include <sys/proc.h> + #include <sys/ctype.h> + #include <sys/libkern.h> + #include <sys/systm.h> + #include <sys/kernel.h> + #include <sys/types.h> + #include <sys/malloc.h> + #include <sys/module.h> + #include <sys/syslog.h> #else + #include <errno.h> #include <sys/types.h> #include <stdio.h> #endif *************** *** 44,51 **** --- 54,142 ---- #ifdef _KERNEL #include <netinet/libalias/alias.h> #include <netinet/libalias/alias_local.h> + #include <netinet/libalias/alias_mod.h> #else #include "alias_local.h" + #include "alias_mod.h" + #endif + + #define CUSEEME_PORT_NUMBER 7648 + + static void + AliasHandleCUSeeMeOut(struct libalias *la, struct ip *pip, + struct alias_link *lnk); + + static void + AliasHandleCUSeeMeIn(struct libalias *la, struct ip *pip, + struct in_addr original_addr); + #ifdef _KERNEL + static + #endif + int + fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + if (ah->dport == NULL || ah->original_address == NULL) + return (NOK); + if (ntohs(*ah->dport) == CUSEEME_PORT_NUMBER) + return (OK); + return (NOK); + } + + #ifdef _KERNEL + static + #endif + int + protohandlerin(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + AliasHandleCUSeeMeIn(la, pip, *ah->original_address); + return (OK); + } + + #ifdef _KERNEL + static + #endif + int + protohandlerout(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + AliasHandleCUSeeMeOut(la, pip, ah->lnk); + return (OK); + } + + /* Kernel module definition. */ + struct proto_handler handlers[] = {{120, OUT, UDP, &fingerprint, &protohandlerout}, + {120, IN, UDP, &fingerprint, &protohandlerin}, {EOH}}; + + static int + mod_handler(module_t mod, int type, void *data) + { + int error; + + switch (type) { + case MOD_LOAD: + error = 0; + attach_handlers(handlers); + break; + case MOD_UNLOAD: + error = 0; + detach_handlers(handlers); + break; + default: + error = EINVAL; + } + return (error); + } + + #ifdef _KERNEL + static + #endif + moduledata_t alias_mod = { + "alias_cuseeme", mod_handler, NULL + }; + + #ifdef _KERNEL + DECLARE_MODULE(alias_cuseeme, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND); + MODULE_VERSION(alias_cuseeme, 1); + MODULE_DEPEND(alias_cuseeme, libalias, 1, 1, 1); #endif /* CU-SeeMe Data Header */ *************** *** 77,82 **** --- 168,176 ---- * counts etc */ }; + #ifdef _KERNEL + static + #endif void AliasHandleCUSeeMeOut(struct libalias *la, struct ip *pip, struct alias_link *lnk) { *************** *** 100,105 **** --- 194,202 ---- } } + #ifdef _KERNEL + static + #endif void AliasHandleCUSeeMeIn(struct libalias *la, struct ip *pip, struct in_addr original_addr) { diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_db.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_db.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_db.c Tue Sep 20 00:31:45 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_db.c Sun Jun 11 18:57:27 2006 *************** *** 143,150 **** --- 143,152 ---- */ #ifdef _KERNEL + #include <machine/stdarg.h> #include <sys/param.h> #else + #include <stdarg.h> #include <sys/types.h> #endif *************** *** 156,168 **** #ifdef _KERNEL #include <sys/systm.h> #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/module.h> #else #include <stdlib.h> #include <stdio.h> #include <unistd.h> - #include <arpa/inet.h> #endif /* BSD network include files */ --- 158,171 ---- #ifdef _KERNEL #include <sys/systm.h> #include <sys/kernel.h> + #include <sys/types.h> #include <sys/malloc.h> #include <sys/module.h> + #include <sys/syslog.h> #else #include <stdlib.h> #include <stdio.h> #include <unistd.h> #endif /* BSD network include files */ *************** *** 171,187 **** #include <netinet/ip.h> #include <netinet/tcp.h> ! #ifdef _KERNEL #include <netinet/libalias/alias.h> #include <netinet/libalias/alias_local.h> #else #include "alias.h" #include "alias_local.h" #endif static LIST_HEAD(, libalias) instancehead = LIST_HEAD_INITIALIZER(instancehead); - /* Constants (note: constants are also defined near relevant functions or structs) --- 174,193 ---- #include <netinet/ip.h> #include <netinet/tcp.h> ! #ifdef _KERNEL #include <netinet/libalias/alias.h> #include <netinet/libalias/alias_local.h> + #include <netinet/libalias/alias_mod.h> + #include <net/if.h> + #include <netinet/in_var.h> #else #include "alias.h" #include "alias_local.h" + #include "alias_mod.h" #endif static LIST_HEAD(, libalias) instancehead = LIST_HEAD_INITIALIZER(instancehead); /* Constants (note: constants are also defined near relevant functions or structs) *************** *** 350,355 **** --- 356,368 ---- MODULE_VERSION(libalias, 1); + /* Use kernel allocator. */ + #if defined(_SYS_MALLOC_H_) + #define malloc(x) malloc(x, M_ALIAS, M_NOWAIT|M_ZERO) + #define calloc(x, n) malloc(x*n) + #define free(x) free(x, M_ALIAS) + #endif + static int alias_mod_handler(module_t mod, int type, void *data) { *************** *** 358,373 **** switch (type) { case MOD_LOAD: error = 0; break; case MOD_QUIESCE: case MOD_UNLOAD: ! finishoff(); error = 0; break; default: error = EINVAL; } - return (error); } --- 371,389 ---- switch (type) { case MOD_LOAD: error = 0; + handler_chain_init(); break; + #if __FreeBSD_version >= 500000 case MOD_QUIESCE: + #endif case MOD_UNLOAD: ! handler_chain_destroy(); ! finishoff(); error = 0; break; default: error = EINVAL; } return (error); } *************** *** 409,420 **** #endif - #ifndef NO_LOGGING /* Log file control */ static void ShowAliasStats(struct libalias *); ! static void InitPacketAliasLog(struct libalias *); static void UninitPacketAliasLog(struct libalias *); - #endif static u_int StartPointIn(struct in_addr alias_addr, --- 425,434 ---- #endif /* Log file control */ static void ShowAliasStats(struct libalias *); ! static int InitPacketAliasLog(struct libalias *); static void UninitPacketAliasLog(struct libalias *); static u_int StartPointIn(struct in_addr alias_addr, *************** *** 462,498 **** return (ntohl(y) - ntohl(x)); } - #ifndef NO_LOGGING static void ! ShowAliasStats(struct libalias *la) ! { ! /* Used for debugging */ ! if (la->monitorFile) { ! fprintf(la->monitorFile, ! "icmp=%d, udp=%d, tcp=%d, pptp=%d, proto=%d, frag_id=%d frag_ptr=%d", ! la->icmpLinkCount, ! la->udpLinkCount, ! la->tcpLinkCount, ! la->pptpLinkCount, ! la->protoLinkCount, ! la->fragmentIdLinkCount, ! la->fragmentPtrLinkCount); ! ! fprintf(la->monitorFile, " / tot=%d (sock=%d)\n", ! la->icmpLinkCount + la->udpLinkCount ! + la->tcpLinkCount ! + la->pptpLinkCount ! + la->protoLinkCount ! + la->fragmentIdLinkCount ! + la->fragmentPtrLinkCount, ! la->sockCount); ! fflush(la->monitorFile); } } - #endif /* Internal routines for finding, deleting and adding links --- 476,528 ---- return (ntohl(y) - ntohl(x)); } + #ifdef _KERNEL static void ! AliasLog(char * str, const char * format, ...) { ! va_list ap; ! ! va_start(ap, format); ! vsnprintf(str, LIBALIAS_BUF_SIZE, format, ap); ! log(LOG_SECURITY | LOG_INFO, "%s\n", str); ! va_end(ap); ! } ! #else ! static void ! AliasLog(FILE * stream, const char * format, ...) { ! va_list ap; ! ! va_start(ap, format); ! vfprintf(stream, format, ap); ! va_end(ap); ! fflush(stream); ! } ! #endif ! static void ! ShowAliasStats(struct libalias *la) { ! /* Used for debugging */ ! if (la->logDesc) { ! int tot = la->icmpLinkCount + la->udpLinkCount + ! la->tcpLinkCount + la->pptpLinkCount + ! la->protoLinkCount + la->fragmentIdLinkCount + ! la->fragmentPtrLinkCount; ! ! AliasLog(la->logDesc, ! "icmp=%u, udp=%u, tcp=%u, pptp=%u, proto=%u, frag_id=%u frag_ptr=%u / tot=%u", ! la->icmpLinkCount, ! la->udpLinkCount, ! la->tcpLinkCount, ! la->pptpLinkCount, ! la->protoLinkCount, ! la->fragmentIdLinkCount, ! la->fragmentPtrLinkCount, tot); ! #ifndef _KERNEL ! AliasLog(la->logDesc, " (sock=%u)\n", la->sockCount); ! #endif } } /* Internal routines for finding, deleting and adding links *************** *** 929,940 **** /* Free memory */ free(lnk); - #ifndef NO_LOGGING /* Write statistics, if logging enabled */ if (la->packetAliasMode & PKT_ALIAS_LOG) { ShowAliasStats(la); } - #endif } --- 959,968 ---- *************** *** 1013,1019 **** switch (link_type) { struct tcp_dat *aux_tcp; ! case LINK_ICMP: la->icmpLinkCount++; break; case LINK_UDP: --- 1041,1047 ---- switch (link_type) { struct tcp_dat *aux_tcp; ! case LINK_ICMP: la->icmpLinkCount++; break; case LINK_UDP: *************** *** 1072,1082 **** fprintf(stderr, "malloc() call failed.\n"); #endif } - #ifndef NO_LOGGING if (la->packetAliasMode & PKT_ALIAS_LOG) { ShowAliasStats(la); } - #endif return (lnk); } --- 1100,1108 ---- *************** *** 2203,2232 **** } } - #ifndef NO_LOGGING /* Init the log file and enable logging */ ! static void InitPacketAliasLog(struct libalias *la) { ! if ((~la->packetAliasMode & PKT_ALIAS_LOG) ! && (la->monitorFile = fopen("/var/log/alias.log", "w"))) { la->packetAliasMode |= PKT_ALIAS_LOG; - fprintf(la->monitorFile, - "PacketAlias/InitPacketAliasLog: Packet alias logging enabled.\n"); } } /* Close the log-file and disable logging. */ static void UninitPacketAliasLog(struct libalias *la) { ! if (la->monitorFile) { ! fclose(la->monitorFile); ! la->monitorFile = NULL; ! } la->packetAliasMode &= ~PKT_ALIAS_LOG; } - #endif /* Outside world interfaces --- 2229,2267 ---- } } /* Init the log file and enable logging */ ! static int InitPacketAliasLog(struct libalias *la) { ! if (~la->packetAliasMode & PKT_ALIAS_LOG) { ! #ifdef _KERNEL ! if ((la->logDesc = malloc(LIBALIAS_BUF_SIZE))) ! ; ! #else ! if ((la->logDesc = fopen("/var/log/alias.log", "w"))) ! fprintf(la->logDesc, "PacketAlias/InitPacketAliasLog: Packet alias logging enabled.\n"); ! #endif ! else ! return(ENOMEM); /* log initialization failed */ la->packetAliasMode |= PKT_ALIAS_LOG; } + return(1); } /* Close the log-file and disable logging. */ static void UninitPacketAliasLog(struct libalias *la) { ! if (la->logDesc) { ! #ifdef _KERNEL ! free(la->logDesc); ! #else ! fclose(la->logDesc); ! #endif ! la->logDesc = NULL; ! } la->packetAliasMode &= ~PKT_ALIAS_LOG; } /* Outside world interfaces *************** *** 2498,2510 **** la->deleteAllLinks = 1; CleanupAliasData(la); la->deleteAllLinks = 0; - #ifndef NO_LOGGING UninitPacketAliasLog(la); - #endif #ifndef NO_FW_PUNCH UninitPunchFW(la); #endif ! LIST_REMOVE(la, instancelist); free(la); } --- 2533,2543 ---- la->deleteAllLinks = 1; CleanupAliasData(la); la->deleteAllLinks = 0; UninitPacketAliasLog(la); #ifndef NO_FW_PUNCH UninitPunchFW(la); #endif ! LIST_REMOVE(la, instancelist); free(la); } *************** *** 2517,2532 **** * do a probe for flag values) */ ) { - #ifndef NO_LOGGING /* Enable logging? */ if (flags & mask & PKT_ALIAS_LOG) { ! InitPacketAliasLog(la); /* Do the enable */ } else /* _Disable_ logging? */ if (~flags & mask & PKT_ALIAS_LOG) { UninitPacketAliasLog(la); } - #endif #ifndef NO_FW_PUNCH /* Start punching holes in the firewall? */ if (flags & mask & PKT_ALIAS_PUNCH_FW) { --- 2550,2565 ---- * do a probe for flag values) */ ) { /* Enable logging? */ if (flags & mask & PKT_ALIAS_LOG) { ! /* Do the enable */ ! if (InitPacketAliasLog(la) == ENOMEM) ! return(-1); } else /* _Disable_ logging? */ if (~flags & mask & PKT_ALIAS_LOG) { UninitPacketAliasLog(la); } #ifndef NO_FW_PUNCH /* Start punching holes in the firewall? */ if (flags & mask & PKT_ALIAS_PUNCH_FW) { *************** *** 2560,2566 **** --- 2593,2604 ---- /* Firewall include files */ #include <net/if.h> + + #if __FreeBSD__ < 5 + #include <netinet/ip_fw2.h> + #else #include <netinet/ip_fw.h> + #endif #include <string.h> #include <err.h> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_dummy.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_dummy.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_dummy.c Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_dummy.c Sun Jun 11 18:57:27 2006 *************** *** 0 **** --- 1,160 ---- + /*- + * Copyright (c) 2005 Paolo Pisati <piso@FreeBSD.org> + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + + #include <sys/cdefs.h> + + /* + * Alias_dummy is just an empty skeleton used to demostrate how to write + * a module for libalias, that will run unalterated in userland or in + * kernel land + */ + + /* Includes */ + #ifdef _KERNEL + #include <sys/param.h> + #include <sys/ctype.h> + #include <sys/libkern.h> + #include <sys/systm.h> + #include <sys/kernel.h> + #include <sys/types.h> + #include <sys/malloc.h> + #include <sys/module.h> + #include <sys/syslog.h> + #else + #include <errno.h> + #include <sys/types.h> + #include <ctype.h> + #include <stdio.h> + #include <string.h> + #endif + + #include <netinet/in_systm.h> + #include <netinet/in.h> + #include <netinet/ip.h> + #include <netinet/tcp.h> + + #ifdef _KERNEL + #include <netinet/libalias/alias.h> + #include <netinet/libalias/alias_local.h> + #include <netinet/libalias/alias_mod.h> + #else + #include "alias_local.h" + #include "alias_mod.h" + #endif + + static void + AliasHandleDummy(struct libalias *la, struct ip *ip, struct alias_data *ah); + + #ifdef _KERNEL + static + #endif + int + fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + /* + * check here all the data that will be used later, if any field + * is empy/NULL, return a NOK value + */ + if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL || + ah->maxpacketsize == 0) + return (NOK); + /* + * fingerprint the incoming packet, if it matches any conditions + * return an OK value + */ + if (ntohs(*ah->dport) == 123 + || ntohs(*ah->sport) == 456) + return (OK); /* i know how to handle it... */ + return (NOK); /* i don't know this packet... */ + } + + /* + * Wrap in this general purpose function, the real function used to alias the + * packets + */ + + #ifdef _KERNEL + static + #endif + int + protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + AliasHandleDummy(la, pip, ah); + return (OK); + } + + /* + * NOTA BENE: these 2 variables MUST NOT be renamed in any case if you want + * your module to work in userland, cause they are used to find and use all + * the protocol handlers present in every module. + * So WATCH OUT, your module needs these 2 variables, and it needs them with + * THEIR EXACT NAMES: handlers and entries. + */ + + struct proto_handler handlers [] = {{666, IN|OUT, UDP|TCP, &fingerprint, + &protohandler}, {EOH}}; + + static int + mod_handler(module_t mod, int type, void *data) + { + int error; + + switch (type) { + case MOD_LOAD: + error = 0; + attach_handlers(handlers); + break; + case MOD_UNLOAD: + error = 0; + detach_handlers(handlers); + break; + default: + error = EINVAL; + } + return (error); + } + + #ifdef _KERNEL + static + #endif + moduledata_t alias_mod = { + "alias_dummy", mod_handler, NULL + }; + + #ifdef _KERNEL + DECLARE_MODULE(alias_dummy, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND); + MODULE_VERSION(alias_dummy, 1); + MODULE_DEPEND(alias_dummy, libalias, 1, 1, 1); + #endif + + #ifdef _KERNEL + static + #endif + void + AliasHandleDummy(struct libalias *la, struct ip *ip, struct alias_data *ah) { + ; /* dummy */ + } + diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_ftp.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_ftp.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_ftp.c Mon Jun 27 09:36:02 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_ftp.c Sun Jun 11 18:57:27 2006 *************** *** 73,79 **** --- 73,86 ---- #include <sys/param.h> #include <sys/ctype.h> #include <sys/libkern.h> + #include <sys/systm.h> + #include <sys/kernel.h> + #include <sys/types.h> + #include <sys/malloc.h> + #include <sys/module.h> + #include <sys/syslog.h> #else + #include <errno.h> #include <sys/types.h> #include <ctype.h> #include <stdio.h> *************** *** 88,95 **** --- 95,171 ---- #ifdef _KERNEL #include <netinet/libalias/alias.h> #include <netinet/libalias/alias_local.h> + #include <netinet/libalias/alias_mod.h> #else #include "alias_local.h" + #include "alias_mod.h" + #endif + + #define FTP_CONTROL_PORT_NUMBER 21 + + static void + AliasHandleFtpOut(struct libalias *, struct ip *, struct alias_link *, + int maxpacketsize); + + #ifdef _KERNEL + static + #endif + int + fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL || + ah->maxpacketsize == 0) + return (NOK); + if (ntohs(*ah->dport) == FTP_CONTROL_PORT_NUMBER + || ntohs(*ah->sport) == FTP_CONTROL_PORT_NUMBER) + return (OK); + return (NOK); + } + + #ifdef _KERNEL + static + #endif + int + protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + AliasHandleFtpOut(la, pip, ah->lnk, ah->maxpacketsize); + return (OK); + } + + struct proto_handler handlers[] = {{80, OUT, TCP, &fingerprint, + &protohandler}, {EOH}}; + + static int + mod_handler(module_t mod, int type, void *data) + { + int error; + + switch (type) { + case MOD_LOAD: + error = 0; + attach_handlers(handlers); + break; + case MOD_UNLOAD: + error = 0; + detach_handlers(handlers); + break; + default: + error = EINVAL; + } + return (error); + } + + #ifdef _KERNEL + static + #endif + moduledata_t alias_mod = { + "alias_ftp", mod_handler, NULL + }; + + #ifdef _KERNEL + DECLARE_MODULE(alias_ftp, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND); + MODULE_VERSION(alias_ftp, 1); + MODULE_DEPEND(alias_ftp, libalias, 1, 1, 1); #endif #define FTP_CONTROL_PORT_NUMBER 21 *************** *** 112,117 **** --- 188,196 ---- static int ParseFtp229Reply(struct libalias *la, char *, int); static void NewFtpMessage(struct libalias *la, struct ip *, struct alias_link *, int, int); + #ifdef _KERNEL + static + #endif void AliasHandleFtpOut( struct libalias *la, diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_irc.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_irc.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_irc.c Mon Jun 27 09:36:02 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_irc.c Sun Jun 11 18:57:27 2006 *************** *** 52,59 **** --- 52,70 ---- #include <sys/param.h> #include <sys/libkern.h> #include <sys/ctype.h> + #include <sys/systm.h> + #include <sys/kernel.h> + #include <sys/types.h> + #include <sys/malloc.h> + #include <sys/module.h> + #include <sys/syslog.h> + #if __FreeBSD_version < 500000 + #include <machine/limits.h> + #else #include <sys/limits.h> + #endif #else + #include <errno.h> #include <sys/types.h> #include <ctype.h> #include <stdio.h> *************** *** 69,82 **** --- 80,165 ---- #ifdef _KERNEL #include <netinet/libalias/alias.h> #include <netinet/libalias/alias_local.h> + #include <netinet/libalias/alias_mod.h> #else #include "alias_local.h" + #include "alias_mod.h" #endif + #define IRC_CONTROL_PORT_NUMBER_1 6667 + #define IRC_CONTROL_PORT_NUMBER_2 6668 + /* Local defines */ #define DBprintf(a) + static void + AliasHandleIrcOut(struct libalias *, struct ip *, struct alias_link *, + int maxpacketsize); + + #ifdef _KERNEL + static + #endif + int + fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + if (ah->dport == NULL || ah->dport == NULL || ah->lnk == NULL || + ah->maxpacketsize == 0) + return (NOK); + if (ntohs(*ah->dport) == IRC_CONTROL_PORT_NUMBER_1 + || ntohs(*ah->dport) == IRC_CONTROL_PORT_NUMBER_2) + return (OK); + return (NOK); + } + + #ifdef _KERNEL + static + #endif + int + protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + AliasHandleIrcOut(la, pip, ah->lnk, ah->maxpacketsize); + return (OK); + } + struct proto_handler handlers[] = {{90, OUT, TCP, &fingerprint, + &protohandler}, {EOH}}; + + static int + mod_handler(module_t mod, int type, void *data) { + int error; + + switch (type) { + case MOD_LOAD: + error = 0; + attach_handlers(handlers); + break; + case MOD_UNLOAD: + error = 0; + detach_handlers(handlers); + break; + default: + error = EINVAL; + } + return (error); + } + + #ifdef _KERNEL + static + #endif + moduledata_t alias_mod = { + "alias_irc", mod_handler, NULL + }; + + /* Kernel module definition. */ + #ifdef _KERNEL + DECLARE_MODULE(alias_irc, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND); + MODULE_VERSION(alias_irc, 1); + MODULE_DEPEND(alias_irc, libalias, 1, 1, 1); + #endif + + #ifdef _KERNEL + static + #endif void AliasHandleIrcOut(struct libalias *la, struct ip *pip, /* IP packet to examine */ diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_local.h /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_local.h *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_local.h Mon Jun 27 09:36:02 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_local.h Sun Jun 11 18:57:27 2006 *************** *** 47,59 **** #define _ALIAS_LOCAL_H_ #include <sys/queue.h> ! /* Use kernel allocator. */ ! #if defined(_KERNEL) && defined(_SYS_MALLOC_H_) ! MALLOC_DECLARE(M_ALIAS); ! #define malloc(x) malloc(x, M_ALIAS, M_NOWAIT|M_ZERO) ! #define calloc(x, n) malloc(x*n) ! #define free(x) free(x, M_ALIAS) #endif /* XXX: LibAliasSetTarget() uses this constant. */ --- 47,66 ---- #define _ALIAS_LOCAL_H_ #include <sys/queue.h> + #include <sys/types.h> + #include <sys/sysctl.h> ! #ifdef _KERNEL ! #if __FreeBSD_version >= 500000 ! #include <sys/param.h> ! #include <sys/lock.h> ! #include <sys/mutex.h> ! #include <sys/proc.h> ! #include <sys/condvar.h> ! #else ! #include <sys/types.h> ! #include <sys/systm.h> ! #endif #endif /* XXX: LibAliasSetTarget() uses this constant. */ *************** *** 116,125 **** int deleteAllLinks; /* If equal to zero, DeleteLink() */ /* will not remove permanent links */ ! #ifndef NO_LOGGING ! FILE *monitorFile; /* File descriptor for link */ #endif ! /* statistics monitoring file */ int newDefaultLink; /* Indicates if a new aliasing */ /* link has been created after a */ --- 123,136 ---- int deleteAllLinks; /* If equal to zero, DeleteLink() */ /* will not remove permanent links */ ! ! /* log descriptor */ ! #ifdef _KERNEL ! char *logDesc; ! #else ! FILE *logDesc; #endif ! /* statistics monitoring */ int newDefaultLink; /* Indicates if a new aliasing */ /* link has been created after a */ *************** *** 296,338 **** /* Tcp specfic routines */ /* lint -save -library Suppress flexelint warnings */ - /* FTP routines */ - void - AliasHandleFtpOut(struct libalias *la, struct ip *_pip, struct alias_link *_lnk, - int _maxpacketsize); - - /* IRC routines */ - void - AliasHandleIrcOut(struct libalias *la, struct ip *_pip, struct alias_link *_lnk, - int _maxsize); - - /* RTSP routines */ - void - AliasHandleRtspOut(struct libalias *la, struct ip *_pip, struct alias_link *_lnk, - int _maxpacketsize); - - /* PPTP routines */ - void AliasHandlePptpOut(struct libalias *la, struct ip *_pip, struct alias_link *_lnk); - void AliasHandlePptpIn(struct libalias *la, struct ip *_pip, struct alias_link *_lnk); - int AliasHandlePptpGreOut(struct libalias *la, struct ip *_pip); - int AliasHandlePptpGreIn(struct libalias *la, struct ip *_pip); - - /* NetBIOS routines */ - int - AliasHandleUdpNbt(struct libalias *la, struct ip *_pip, struct alias_link *_lnk, - struct in_addr *_alias_address, u_short _alias_port); - int - AliasHandleUdpNbtNS(struct libalias *la, struct ip *_pip, struct alias_link *_lnk, - struct in_addr *_alias_address, u_short * _alias_port, - struct in_addr *_original_address, u_short * _original_port); - - /* CUSeeMe routines */ - void AliasHandleCUSeeMeOut(struct libalias *la, struct ip *_pip, struct alias_link *_lnk); - void AliasHandleCUSeeMeIn(struct libalias *la, struct ip *_pip, struct in_addr _original_addr); - - /* Skinny routines */ - void AliasHandleSkinny(struct libalias *la, struct ip *_pip, struct alias_link *_lnk); - /* Transparent proxy routines */ int ProxyCheck(struct libalias *la, struct ip *_pip, struct in_addr *_proxy_server_addr, --- 307,312 ---- *************** *** 372,378 **** return ((void *)(udphdr + 1)); } #endif - - /*lint -restore */ #endif /* !_ALIAS_LOCAL_H_ */ --- 346,350 ---- diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_mod.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_mod.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_mod.c Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_mod.c Sun Jun 11 18:57:27 2006 *************** *** 0 **** --- 1,388 ---- + /*- + * Copyright (c) 2005 Paolo Pisati <piso@FreeBSD.org> + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + */ + + #ifdef _KERNEL + #include <sys/param.h> + #include <sys/proc.h> + #else + #include <stdio.h> + #include <string.h> + #include <sys/types.h> + #endif + + #include <netinet/in_systm.h> + #include <netinet/in.h> + #include <netinet/ip.h> + #include <netinet/ip_icmp.h> + #include <netinet/tcp.h> + #include <netinet/udp.h> + + #include <sys/queue.h> + #include <sys/types.h> + #include <sys/sysctl.h> + + #ifdef _KERNEL + #include <netinet/libalias/alias_local.h> + #include <netinet/libalias/alias_mod.h> + #else + #include "alias.h" + #include "alias_local.h" + #include "alias_mod.h" + #endif + + #include <sys/types.h> + + #if __FreeBSD_version >= 500000 + /* XXX - make the compiler happy... */ + int strncmp(const char *s1, const char *s2, size_t len); + #endif + + /* protocol and userland module handlers chains */ + struct chain handler_chain, dll_chain; + + #ifdef _KERNEL + + #if __FreeBSD_version >= 500000 + + /* Fine grained locking for 5.x, 6.x and 7.x */ + + #define LIBALIAS_LOCK_INIT(_chain) \ + mtx_init(&(_chain)->mtx, "libalias list of proto-handlers", NULL, \ + MTX_DEF | MTX_RECURSE) + #define LIBALIAS_LOCK_DESTROY(_chain) mtx_destroy(&(_chain)->mtx) + #define LIBALIAS_WLOCK_ASSERT(_chain) do { \ + mtx_assert(&(_chain)->mtx, MA_OWNED); \ + NET_ASSERT_GIANT(); \ + } while (0) + + static __inline void + LIBALIAS_RLOCK(struct chain *chain) + { + mtx_lock(&chain->mtx); + chain->busy_count++; + mtx_unlock(&chain->mtx); + } + + static __inline void + LIBALIAS_RUNLOCK(struct chain *chain) + { + mtx_lock(&chain->mtx); + chain->busy_count--; + if (chain->busy_count == 0 && chain->want_write) + cv_signal(&chain->cv); + mtx_unlock(&chain->mtx); + } + + static __inline void + LIBALIAS_WLOCK(struct chain *chain) + { + mtx_lock(&chain->mtx); + chain->want_write++; + while (chain->busy_count > 0) + cv_wait(&chain->cv, &chain->mtx); + } + + static __inline void + LIBALIAS_WUNLOCK(struct chain *chain) + { + chain->want_write--; + cv_signal(&chain->cv); + mtx_unlock(&chain->mtx); + } + + static void + _handler_chain_init(struct chain *c) { + + if (!mtx_initialized(&c->mtx)) + LIBALIAS_LOCK_INIT(c); + } + + static void + _handler_chain_destroy(struct chain *c) { + + if (mtx_initialized(&c->mtx)) + LIBALIAS_LOCK_DESTROY(c); + } + #else + + /* Good old spl*() locking for 4.x */ + /* + * XXX - i'm not sure about mutex & conditional var + * conversion that i did using spl*()... + */ + + #define LIBALIAS_LOCK_INIT(_chain) (_chain)->spl = 0 + #define LIBALIAS_LOCK_DESTROY(_chain) + #define LIBALIAS_WLOCK_ASSERT(_chain) do { \ + KASSERT(_chain->spl != 0, ("chain not locked")); \ + } while (0) + + static __inline void + LIBALIAS_RLOCK(struct chain *chain) + { + chain->spl = splimp(); + } + + static __inline void + LIBALIAS_RUNLOCK(struct chain *chain) + { + splx(chain->spl); + } + + static __inline void + LIBALIAS_WLOCK(struct chain *chain) + { + LIBALIAS_RLOCK(chain); + } + + static __inline void + LIBALIAS_WUNLOCK(struct chain *chain) + { + LIBALIAS_RUNLOCK(chain); + } + + static void + _handler_chain_init(struct chain *c) { + + c->spl = 0; + } + + static void + _handler_chain_destroy(struct chain *c) { + + ; + } + + #endif + #else + + #define LIBALIAS_LOCK_INIT(_chain) ; + #define LIBALIAS_LOCK_DESTROY(_chain) ; + #define LIBALIAS_WLOCK_ASSERT(_chain) ; + + static __inline void + LIBALIAS_RLOCK(struct chain *chain __unused) + { + ; + } + + static __inline void + LIBALIAS_RUNLOCK(struct chain *chain __unused) + { + ; + } + + static __inline void + LIBALIAS_WLOCK(struct chain *chain __unused) + { + ; + } + + static __inline void + LIBALIAS_WUNLOCK(struct chain *chain __unused) + { + ; + } + + static void + _handler_chain_init(struct chain *c __unused) { + ; + } + + static void + _handler_chain_destroy(struct chain *c __unused) { + ; + } + + #endif + + void + handler_chain_init(void) { + _handler_chain_init(&handler_chain); + } + + void + handler_chain_destroy(void) { + _handler_chain_destroy(&handler_chain); + } + + static int + _attach_handler(struct chain *c, struct proto_handler *p) { + struct proto_handler **b; + int i = 0; + + LIBALIAS_WLOCK_ASSERT(c); + b = (struct proto_handler **)&c->chain; + p->next = NULL; /* i'm paranoid... */ + for(; *b != NULL; b = &((*b)->next), i++) { + if (((*b)->pri == p->pri) && ((*b)->dir == p->dir) && + ((*b)->proto == p->proto)) + return (EHDCON); /* priority conflict */ + if ((*b)->pri > p->pri) { + p->next = *b; break; + } + } + /* end of list or got right position, insert here */ + *b = p; + return (OK); + } + + static int + _detach_handler(struct chain *c, struct proto_handler *p) { + struct proto_handler **b; + + LIBALIAS_WLOCK_ASSERT(c); + b = (struct proto_handler **)&c->chain; + for(; (*b != NULL) && (*b != p); b = &((*b)->next)) + ; + if (*b == p) *b = p->next; + else return (EHDNOF); /* handler not found */ + return (OK); + } + + int + attach_handlers(struct proto_handler *_p) { + int i, res = NOK; + + LIBALIAS_WLOCK(&handler_chain); + for (i=0; 1; i++) { + if (*((int *)&_p[i]) == EOH) break; + res = _attach_handler(&handler_chain, &_p[i]); + if (res != OK) break; + } + LIBALIAS_WUNLOCK(&handler_chain); + return (res); + } + + int + detach_handlers(struct proto_handler *_p) { + int i, res = NOK; + + LIBALIAS_WLOCK(&handler_chain); + for (i=0; 1; i++) { + if (*((int *)&_p[i]) == EOH) break; + res = _detach_handler(&handler_chain, &_p[i]); + if (res != OK) break; + } + LIBALIAS_WUNLOCK(&handler_chain); + return (res); + } + + int + detach_handler(struct proto_handler *_p) { + int res = NOK; + + LIBALIAS_WLOCK(&handler_chain); + res = _detach_handler(&handler_chain, _p); + LIBALIAS_WUNLOCK(&handler_chain); + return (res); + } + + int + find_handler(int8_t dir, int8_t proto, struct libalias *la, struct ip *pip, struct alias_data *ad) { + struct proto_handler *p; + int err; + + LIBALIAS_RLOCK(&handler_chain); + for (p = handler_chain.chain, err = EHDNOF; p != NULL; p = p->next) + if ((p->dir & dir) && (p->proto & proto)) + if (p->fingerprint(la, pip, ad) == OK) { + err = p->protohandler(la, pip, ad); + break; + } + LIBALIAS_RUNLOCK(&handler_chain); + return (err); + } + + struct proto_handler * + first_handler(void) { + + return (handler_chain.chain); + } + + static int + _attach_dll(struct chain *c, struct dll *p) { + struct dll **b; + int i = 0; + + LIBALIAS_WLOCK_ASSERT(c); + b = (struct dll **)&c->chain; + p->next = NULL; /* i'm paranoid... */ + for(; *b != NULL; b = &((*b)->next), i++) + if (!strncmp((*b)->name, p->name, DLL_LEN)) + return (EHDCON); /* dll name conflict */ + /* end of list, insert here */ + *b = p; + return (OK); + } + + static void * + _detach_dll(struct chain *c, char *p) { + struct dll **b; + void *err = NULL; + + LIBALIAS_WLOCK_ASSERT(c); + b = (struct dll **)&c->chain; + for(; *b != NULL; b = &((*b)->next)) + if (!strncmp((*b)->name, p, DLL_LEN)) { + err = *b; + *b = (*b)->next; + break; + } + return (err); + } + + int + attach_dll(struct dll *p) { + int i; + + LIBALIAS_WLOCK(&dll_chain); + i = _attach_dll(&dll_chain, p); + LIBALIAS_WUNLOCK(&dll_chain); + return (i); + } + + void * + detach_dll(char *p) { + void *i; + + LIBALIAS_WLOCK(&dll_chain); + i = _detach_dll(&dll_chain, p); + LIBALIAS_WUNLOCK(&dll_chain); + return (i); + } + + struct dll * + walk_dll_chain(void) { + struct dll *t, **b = (struct dll **)&dll_chain.chain; + + for(t = *b; *b != NULL;) { + *b = (*b)->next; + break; + } + return (t); + } diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_mod.h /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_mod.h *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_mod.h Thu Jan 1 01:00:00 1970 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_mod.h Sun Jun 11 18:57:27 2006 *************** *** 0 **** --- 1,183 ---- + /*- + * Copyright (c) 2005 Paolo Pisati <piso@FreeBSD.org> + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + + /*- + * Alias_mod.h defines the outside world interfaces for the packet aliasing + * modular framework + */ + + #ifndef _ALIAS_MOD_H_ + #define _ALIAS_MOD_H_ + + /* protocol handlers struct & function*/ + + /* packet flow direction */ + #define IN 1 + #define OUT 2 + + /* working protocol */ + #define IP 1 + #define TCP 2 + #define UDP 4 + #define ICMP 8 + + /* + * Data passed to protocol handler module, it must be filled + * right before calling find_handler() to determine which + * module is elegible to be called + */ + + struct alias_data { + + struct alias_link *lnk; + struct in_addr *original_address; + struct in_addr *alias_address; + u_short *alias_port; + u_int16_t *sport, *dport; + int maxpacketsize; + }; + + /* + * This structure contains all the information necessary to make + * a protocol handler correctly work. + */ + + struct proto_handler { + + u_int pri; /* handler priority */ + int16_t dir; /* flow direction */ + int16_t proto; /* working protocol */ + int (*fingerprint)(struct libalias *la, /* fingerprint * function */ + struct ip *pip, struct alias_data *ah); + int (*protohandler)(struct libalias *la, /* aliasing * function */ + struct ip *pip, struct alias_data *ah); + struct proto_handler *next; + }; + + #if __FreeBSD_version >= 500000 + struct chain { + + void *chain; + struct mtx mtx; /* lock guarding list */ + int busy_count; /* busy count for rw locks */ + int want_write; + struct cv cv; + }; + #else + struct chain { + + void *chain; + int spl; + }; + #endif + + /* + * Used only in userland when libalias needs to keep track of all + * module loaded. In kernel land (kld mode) we don't need to care + * care about libalias modules cause it's kld to do it for us + */ + + #define DLL_LEN 32 + struct dll { + + char name[DLL_LEN]; /* name of module */ + void *handle; /* + * ptr to shared obj obtained through + * dlopen() - use this ptr to get access + * to any symbols from a loaded module + * via dlsym() + */ + struct dll *next; + }; + + /* functions used with protocol handlers */ + + void handler_chain_init(void); + void handler_chain_destroy(void); + int attach_handlers(struct proto_handler *); + int detach_handlers(struct proto_handler *); + int detach_handler(struct proto_handler *); + int find_handler(int8_t, int8_t, struct libalias *, + struct ip *, struct alias_data *); + struct proto_handler *first_handler(void); + + /* functions used with dll module */ + + void dll_chain_init(void); + void dll_chain_destroy(void); + int attach_dll(struct dll *); + void *detach_dll(char *); + struct dll *walk_dll_chain(void); + + /* general condition of success & failure */ + #define OK 1 + #define NOK -1 + + /* end of handlers */ + #define EOH -1 + + /* + * handler/dll conflict - tried to attach a protocol handleror a dll, + * but found another one with same priority, direction and working + * protocol(proto handler) or name (dll) already in chain + */ + + #define EHDCON 2 + + /* + * handler/dll not found - tried to detach/search a protocol module + * handler or a dll not present in chain + */ + + #define EHDNOF 3 + + /* + * Some defines borrowed from sys/module.h used to compile a kld + * in userland as a shared lib + */ + + #ifndef _KERNEL + typedef enum modeventtype { + MOD_LOAD, + MOD_UNLOAD, + MOD_SHUTDOWN, + MOD_QUIESCE + } modeventtype_t; + + typedef struct module *module_t; + typedef int (*modeventhand_t)(module_t, int /* modeventtype_t */, void *); + + /* + * Struct for registering modules statically via SYSINIT. + */ + typedef struct moduledata { + const char *name; /* module name */ + modeventhand_t evhand; /* event handler */ + void *priv; /* extra data */ + } moduledata_t; + #endif + + #endif /* !_ALIAS_MOD_H_ */ diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_nbt.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_nbt.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_nbt.c Fri May 6 13:07:49 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_nbt.c Sun Jun 11 18:57:27 2006 *************** *** 45,56 **** #include <sys/param.h> #include <sys/ctype.h> #include <sys/libkern.h> #else #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <string.h> - #include <arpa/inet.h> #endif #include <netinet/in_systm.h> --- 45,62 ---- #include <sys/param.h> #include <sys/ctype.h> #include <sys/libkern.h> + #include <sys/systm.h> + #include <sys/kernel.h> + #include <sys/types.h> + #include <sys/malloc.h> + #include <sys/module.h> + #include <sys/syslog.h> #else + #include <errno.h> #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <string.h> #endif #include <netinet/in_systm.h> *************** *** 62,69 **** --- 68,175 ---- #ifdef _KERNEL #include <netinet/libalias/alias.h> #include <netinet/libalias/alias_local.h> + #include <netinet/libalias/alias_mod.h> #else #include "alias_local.h" + #include "alias_mod.h" + #endif + + #define NETBIOS_NS_PORT_NUMBER 137 + #define NETBIOS_DGM_PORT_NUMBER 138 + + static int + AliasHandleUdpNbt(struct libalias *, struct ip *, struct alias_link *, + struct in_addr *, u_short); + + static int + AliasHandleUdpNbtNS(struct libalias *, struct ip *, struct alias_link *, + struct in_addr *, u_short *, struct in_addr *, u_short *); + #ifdef _KERNEL + static + #endif + int + fingerprint1(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL || + ah->alias_address == NULL || ah->alias_port == NULL) + return (NOK); + if (ntohs(*ah->dport) == NETBIOS_DGM_PORT_NUMBER + || ntohs(*ah->sport) == NETBIOS_DGM_PORT_NUMBER) + return (OK); + return (NOK); + } + + #ifdef _KERNEL + static + #endif + int + protohandler1(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + AliasHandleUdpNbt(la, pip, ah->lnk, ah->alias_address, *ah->alias_port); + return (OK); + } + + #ifdef _KERNEL + static + #endif + int + fingerprint2(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL || + ah->alias_address == NULL || ah->alias_port == NULL) + return (NOK); + if (ntohs(*ah->dport) == NETBIOS_NS_PORT_NUMBER + || ntohs(*ah->sport) == NETBIOS_NS_PORT_NUMBER) + return (OK); + return (NOK); + } + + #ifdef _KERNEL + static + #endif + int + protohandler2(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + AliasHandleUdpNbtNS(la, pip, ah->lnk, &pip->ip_src, ah->sport, + ah->alias_address, ah->alias_port); + return (OK); + } + + /* Kernel module definition. */ + struct proto_handler handlers[] = {{130, IN|OUT, UDP, &fingerprint1, &protohandler1}, + {140, IN|OUT, UDP, &fingerprint2, &protohandler2}, {EOH}}; + + static int + mod_handler(module_t mod, int type, void *data) + { + int error; + + switch (type) { + case MOD_LOAD: + error = 0; + attach_handlers(handlers); + break; + case MOD_UNLOAD: + error = 0; + detach_handlers(handlers); + break; + default: + error = EINVAL; + } + return (error); + } + + #ifdef _KERNEL + static + #endif + moduledata_t alias_mod = { + "alias_nbt", mod_handler, NULL + }; + + #ifdef _KERNEL + DECLARE_MODULE(alias_nbt, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND); + MODULE_VERSION(alias_nbt, 1); + MODULE_DEPEND(alias_nbt, libalias, 1, 1, 1); #endif typedef struct { *************** *** 212,217 **** --- 318,326 ---- #define DGM_POSITIVE_RES 0x15 #define DGM_NEGATIVE_RES 0x16 + #ifdef _KERNEL + static + #endif int AliasHandleUdpNbt( struct libalias *la, *************** *** 640,645 **** --- 749,757 ---- return ((u_char *) q); } + #ifdef _KERNEL + static + #endif int AliasHandleUdpNbtNS( struct libalias *la, diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_old.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_old.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_old.c Thu May 5 21:27:32 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_old.c Sun Jun 11 18:57:27 2006 *************** *** 29,34 **** --- 29,35 ---- #ifdef _KERNEL #include <sys/param.h> + #include <sys/proc.h> #else #include <sys/types.h> #include <stdlib.h> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_pptp.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_pptp.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_pptp.c Thu May 5 23:55:17 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_pptp.c Sun Jun 11 18:57:27 2006 *************** *** 39,44 **** --- 39,206 ---- #include <sys/cdefs.h> __FBSDID("$FreeBSD: src/sys/netinet/libalias/alias_pptp.c,v 1.14 2005/05/05 21:55:17 glebius Exp $"); + /* Includes */ + #ifdef _KERNEL + #if __FreeBSD__ >= 5 + #include <sys/limits.h> + #else + #include <machine/limits.h> + #endif + #include <sys/param.h> + #include <sys/proc.h> + #include <sys/ctype.h> + #include <sys/libkern.h> + #include <sys/systm.h> + #include <sys/kernel.h> + #include <sys/types.h> + #include <sys/malloc.h> + #include <sys/module.h> + #include <sys/syslog.h> + #else + #include <errno.h> + #include <limits.h> + #include <sys/types.h> + #include <stdio.h> + #endif + + #include <netinet/in_systm.h> + #include <netinet/in.h> + #include <netinet/ip.h> + #include <netinet/tcp.h> + + #ifdef _KERNEL + #include <netinet/libalias/alias.h> + #include <netinet/libalias/alias_local.h> + #include <netinet/libalias/alias_mod.h> + #else + #include "alias.h" + #include "alias_local.h" + #include "alias_mod.h" + #endif + + #define PPTP_CONTROL_PORT_NUMBER 1723 + + static void + AliasHandlePptpOut(struct libalias *, struct ip *, struct alias_link *); + + static void + AliasHandlePptpIn(struct libalias *, struct ip *, struct alias_link *); + + static int + AliasHandlePptpGreOut(struct libalias *, struct ip *); + + static int + AliasHandlePptpGreIn(struct libalias *, struct ip *); + + #ifdef _KERNEL + static + #endif + int + fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL) + return (NOK); + if (ntohs(*ah->dport) == PPTP_CONTROL_PORT_NUMBER + || ntohs(*ah->sport) == PPTP_CONTROL_PORT_NUMBER) + return (OK); + return (NOK); + } + + #ifdef _KERNEL + static + #endif + int + fingerprintgre(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + return (OK); + } + + #ifdef _KERNEL + static + #endif + int + protohandlerin(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + AliasHandlePptpIn(la, pip, ah->lnk); + return (OK); + } + + #ifdef _KERNEL + static + #endif + int + protohandlerout(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + AliasHandlePptpOut(la, pip, ah->lnk); + return (OK); + } + + #ifdef _KERNEL + static + #endif + int + protohandlergrein(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY || + AliasHandlePptpGreIn(la, pip) == 0) + return (OK); + return (NOK); + } + + #ifdef _KERNEL + static + #endif + int + protohandlergreout(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + if (AliasHandlePptpGreOut(la, pip) == 0) + return (OK); + return (NOK); + } + + /* Kernel module definition. */ + struct proto_handler handlers[] = {{200, IN, TCP, &fingerprint, &protohandlerin}, + {210, OUT, TCP, &fingerprint, &protohandlerout}, + /* + * WATCH OUT!!! these 2 handlers NEED a priority of INT_MAX (highest possible) + * cause they will ALWAYS process packets, so they must be the last one + * in chain: look fingerprintgre() above. + */ + {INT_MAX, IN, IP, &fingerprintgre, &protohandlergrein}, + {INT_MAX, OUT, IP, &fingerprintgre, &protohandlergreout}, {EOH}}; + static int + mod_handler(module_t mod, int type, void *data) + { + int error; + + switch (type) { + case MOD_LOAD: + error = 0; + attach_handlers(handlers); + break; + case MOD_UNLOAD: + error = 0; + detach_handlers(handlers); + break; + default: + error = EINVAL; + } + return (error); + } + + #ifdef _KERNEL + static + #endif + moduledata_t alias_mod = { + "alias_pptp", mod_handler, NULL + }; + + #ifdef _KERNEL + DECLARE_MODULE(alias_pptp, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND); + MODULE_VERSION(alias_pptp, 1); + MODULE_DEPEND(alias_pptp, libalias, 1, 1, 1); + #endif + /* Alias_pptp.c performs special processing for PPTP sessions under TCP. Specifically, watch PPTP control messages and alias the Call ID or the *************** *** 65,90 **** */ - /* Includes */ - #ifdef _KERNEL - #include <sys/param.h> - #else - #include <sys/types.h> - #include <stdio.h> - #endif - - #include <netinet/in_systm.h> - #include <netinet/in.h> - #include <netinet/ip.h> - #include <netinet/tcp.h> - - #ifdef _KERNEL - #include <netinet/libalias/alias.h> - #include <netinet/libalias/alias_local.h> - #else - #include "alias_local.h" - #endif - /* * PPTP definitions */ --- 227,232 ---- *************** *** 153,158 **** --- 295,303 ---- static PptpCallId AliasVerifyPptp(struct ip *, u_int16_t *); + #ifdef _KERNEL + static + #endif void AliasHandlePptpOut(struct libalias *la, struct ip *pip, /* IP packet to examine/patch */ *************** *** 225,230 **** --- 370,378 ---- } } + #ifdef _KERNEL + static + #endif void AliasHandlePptpIn(struct libalias *la, struct ip *pip, /* IP packet to examine/patch */ *************** *** 328,334 **** return (PptpCallId) (hptr + 1); } ! int AliasHandlePptpGreOut(struct libalias *la, struct ip *pip) { --- 476,484 ---- return (PptpCallId) (hptr + 1); } ! #ifdef _KERNEL ! static ! #endif int AliasHandlePptpGreOut(struct libalias *la, struct ip *pip) { *************** *** 353,359 **** return (0); } ! int AliasHandlePptpGreIn(struct libalias *la, struct ip *pip) { --- 503,511 ---- return (0); } ! #ifdef _KERNEL ! static ! #endif int AliasHandlePptpGreIn(struct libalias *la, struct ip *pip) { diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_proxy.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_proxy.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_proxy.c Mon Jun 27 09:36:02 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_proxy.c Sun Jun 11 18:57:27 2006 *************** *** 60,75 **** #include <sys/libkern.h> #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/limits.h> #else #include <sys/types.h> #include <sys/socket.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> - #include <string.h> #include <netdb.h> ! #include <arpa/inet.h> #endif /* BSD IPV4 includes */ --- 60,78 ---- #include <sys/libkern.h> #include <sys/kernel.h> #include <sys/malloc.h> + #if __FreeBSD_version < 500000 + #include <machine/limits.h> + #else #include <sys/limits.h> + #endif #else #include <sys/types.h> #include <sys/socket.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <netdb.h> ! #include <string.h> #endif /* BSD IPV4 includes */ *************** *** 156,161 **** --- 159,173 ---- static void ProxyEncodeIpHeader(struct ip *, int); #ifdef _KERNEL + + /* Use kernel allocator. */ + #if defined(_SYS_MALLOC_H_) + MALLOC_DECLARE(M_ALIAS); + #define malloc(x) malloc(x, M_ALIAS, M_NOWAIT|M_ZERO) + #define calloc(x, n) malloc(x*n) + #define free(x) free(x, M_ALIAS) + #endif + static int inet_aton(cp, addr) const char *cp; diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_skinny.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_skinny.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_skinny.c Mon Jun 27 09:36:02 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_skinny.c Sun Jun 11 18:57:27 2006 *************** *** 32,44 **** #ifdef _KERNEL #include <sys/param.h> #else #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <string.h> #include <unistd.h> - #include <arpa/inet.h> #endif #include <netinet/in_systm.h> --- 32,52 ---- #ifdef _KERNEL #include <sys/param.h> + #include <sys/proc.h> + #include <sys/kernel.h> + #include <sys/types.h> + #include <sys/malloc.h> + #include <sys/module.h> + #include <sys/syslog.h> + #include <sys/types.h> + #include <sys/systm.h> #else + #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <string.h> #include <unistd.h> #endif #include <netinet/in_systm.h> *************** *** 50,57 **** --- 58,130 ---- #ifdef _KERNEL #include <netinet/libalias/alias.h> #include <netinet/libalias/alias_local.h> + #include <netinet/libalias/alias_mod.h> #else #include "alias_local.h" + #include "alias_mod.h" + #endif + + static void + AliasHandleSkinny(struct libalias *, struct ip *, struct alias_link *); + + #ifdef _KERNEL + static + #endif + int + fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL) + return (NOK); + if (la->skinnyPort != 0 && (ntohs(*ah->sport) == la->skinnyPort || + ntohs(*ah->dport) == la->skinnyPort)) + return (OK); + return (NOK); + } + + #ifdef _KERNEL + static + #endif + int + protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + AliasHandleSkinny(la, pip, ah->lnk); + return (OK); + } + + struct proto_handler handlers[] = {{110, IN|OUT, TCP, &fingerprint, + &protohandler}, {EOH}}; + + static int + mod_handler(module_t mod, int type, void *data) + { + int error; + + switch (type) { + case MOD_LOAD: + error = 0; + attach_handlers(handlers); + break; + case MOD_UNLOAD: + error = 0; + detach_handlers(handlers); + break; + default: + error = EINVAL; + } + return (error); + } + + #ifdef _KERNEL + static + #endif + moduledata_t alias_mod = { + "alias_skinny", mod_handler, NULL + }; + + #ifdef _KERNEL + DECLARE_MODULE(alias_skinny, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND); + MODULE_VERSION(alias_skinny, 1); + MODULE_DEPEND(alias_skinny, libalias, 1, 1, 1); #endif /* *************** *** 233,238 **** --- 306,314 ---- return (0); } + #ifdef _KERNEL + static + #endif void AliasHandleSkinny(struct libalias *la, struct ip *pip, struct alias_link *lnk) { diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_smedia.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_smedia.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_smedia.c Mon Jun 27 09:36:02 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_smedia.c Sun Jun 11 18:57:27 2006 *************** *** 101,107 **** --- 101,114 ---- #ifdef _KERNEL #include <sys/param.h> #include <sys/libkern.h> + #include <sys/systm.h> + #include <sys/kernel.h> + #include <sys/types.h> + #include <sys/malloc.h> + #include <sys/module.h> + #include <sys/syslog.h> #else + #include <errno.h> #include <sys/types.h> #include <stdio.h> #include <string.h> *************** *** 116,123 **** --- 123,206 ---- #ifdef _KERNEL #include <netinet/libalias/alias.h> #include <netinet/libalias/alias_local.h> + #include <netinet/libalias/alias_mod.h> #else #include "alias_local.h" + #include "alias_mod.h" + #endif + + #define RTSP_CONTROL_PORT_NUMBER_1 554 + #define RTSP_CONTROL_PORT_NUMBER_2 7070 + #define TFTP_PORT_NUMBER 69 + + static void + AliasHandleRtspOut(struct libalias *, struct ip *, struct alias_link *, + int maxpacketsize); + #ifdef _KERNEL + static + #endif + int + fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL || + ah->maxpacketsize == 0) + return (NOK); + if (ntohs(*ah->dport) == RTSP_CONTROL_PORT_NUMBER_1 + || ntohs(*ah->sport) == RTSP_CONTROL_PORT_NUMBER_1 + || ntohs(*ah->dport) == RTSP_CONTROL_PORT_NUMBER_2 + || ntohs(*ah->sport) == RTSP_CONTROL_PORT_NUMBER_2 + || ntohs(*ah->dport) == TFTP_PORT_NUMBER) + return (OK); + return (NOK); + } + + #ifdef _KERNEL + static + #endif + int + protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + if (ntohs(*ah->dport) == TFTP_PORT_NUMBER) + FindRtspOut(la, pip->ip_src, pip->ip_dst, + *ah->sport, *ah->alias_port, IPPROTO_UDP); + else AliasHandleRtspOut(la, pip, ah->lnk, ah->maxpacketsize); + return (OK); + } + + struct proto_handler handlers[] = {{100, OUT, TCP|UDP, &fingerprint, + &protohandler}, {EOH}}; + + static int + mod_handler(module_t mod, int type, void *data) + { + int error; + + switch (type) { + case MOD_LOAD: + error = 0; + attach_handlers(handlers); + break; + case MOD_UNLOAD: + error = 0; + detach_handlers(handlers); + break; + default: + error = EINVAL; + } + return (error); + } + + #ifdef _KERNEL + static + #endif + moduledata_t alias_mod = { + "alias_smedia", mod_handler, NULL + }; + + #ifdef _KERNEL + DECLARE_MODULE(alias_smedia, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND); + MODULE_VERSION(alias_smedia, 1); + MODULE_DEPEND(alias_smedia, libalias, 1, 1, 1); #endif #define RTSP_CONTROL_PORT_NUMBER_1 554 *************** *** 392,397 **** --- 475,483 ---- return (0); } + #ifdef _KERNEL + static + #endif void AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *lnk, int maxpacketsize) { diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_util.c /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_util.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/alias_util.c Mon Jun 27 09:36:02 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/alias_util.c Sun Jun 11 18:57:27 2006 *************** *** 45,50 **** --- 45,51 ---- #ifdef _KERNEL #include <sys/param.h> + #include <sys/proc.h> #else #include <sys/types.h> #include <stdio.h> diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/libalias.3 /home/flag/src/freebsd7/src/sys/netinet/libalias/libalias.3 *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/libalias/libalias.3 Thu Nov 24 15:17:35 2005 --- /home/flag/src/freebsd7/src/sys/netinet/libalias/libalias.3 Sun Jun 18 16:09:34 2006 *************** *** 893,898 **** --- 893,901 ---- added support for RTSP/PNA. .An Ruslan Ermilov Aq ru@FreeBSD.org added support for PPTP and LSNAT as well as general hacking. + .An Paolo Pisati Aq piso@FreeBSD.org + made the library modular, moving support for all + the protocols (except for IP, TCP and UDP) to external modules. .Sh ACKNOWLEDGMENTS Listed below, in approximate chronological order, are individuals who have provided valuable comments and/or debugging assistance. *************** *** 1011,1016 **** --- 1014,1385 ---- a unique aliasing link can be established. In an alternate operating mode, the first choice of an aliasing port is also random and unrelated to the local port number. + .Sh Modular architecture (and ipfw support) + One of the latest improvement of libalias was to make its support + for new protocols independent from the rest of the library, giving it + the ability to load/unload at runtime support for new protocols. + To achieve this feature, all the code for protocols handling was moved + to a series of modules outside of the main library. + These modules are compiled from the same source base but works in a + different ways, according if they are compiled to work inside a kernel + or as part of a user land library. + .Ss Libalias modules in kernel land + When compiled to be part of a kernel, libalias modules are plain + simple kld, installed as default with all the other kernel modules: + .Pp + .Bd -ragged -offset indent + .An -split + .An /boot/kernel/alias_cuseeme.ko + .An /boot/kernel/alias_dummy.ko + .An /boot/kernel/alias_ftp.ko + .An /boot/kernel/alias_irc.ko + .An /boot/kernel/alias_nbt.ko + .An /boot/kernel/alias_pptp.ko + .An /boot/kernel/alias_skinny.ko + .An /boot/kernel/alias_smedia.ko + .Ed + .Pp + To load a new protocol just kldload it: + .Pp + kldload alias_ftp # add support for ftp protocol to kernel libalias + .Pp + and when you don't need it anymore, you can unload it: + .Pp + kldunload alias_ftp + .Pp + .Ss Libalias modules in user land + Due to the differences between kernel and user land (no kld mechanism, + many different address spaces, etc etc), we had to change a bit how to + handle modules loading/tracking/unloading in user land. + .Pp + While compiled for a user land libalias, all the modules are installed + in /usr/lib: + .Pp + .Bd -ragged -offset indent + .An -split + .An /usr/lib/libalias_cuseeme.a + .An /usr/lib/libalias_cuseeme.so -> /lib/libalias_cuseeme.so.4 + .An /usr/lib/libalias_cuseeme_p.a + .An /usr/lib/libalias_dummy.a + .An /usr/lib/libalias_dummy.so -> /lib/libalias_dummy.so.4 + .An /usr/lib/libalias_dummy_p.a + .An /usr/lib/libalias_ftp.a + .An /usr/lib/libalias_ftp.so -> /lib/libalias_ftp.so.4 + .An /usr/lib/libalias_ftp_p.a + .An /usr/lib/libalias_irc.a + .An /usr/lib/libalias_irc.so -> /lib/libalias_irc.so.4 + .An /usr/lib/libalias_irc_p.a + .An /usr/lib/libalias_nbt.a + .An /usr/lib/libalias_nbt.so -> /lib/libalias_nbt.so.4 + .An /usr/lib/libalias_nbt_p.a + .An /usr/lib/libalias_pptp.a + .An /usr/lib/libalias_pptp.so -> /lib/libalias_pptp.so.4 + .An /usr/lib/libalias_pptp_p.a + .An /usr/lib/libalias_skinny.a + .An /usr/lib/libalias_skinny.so -> /lib/libalias_skinny.so.4 + .An /usr/lib/libalias_skinny_p.a + .An /usr/lib/libalias_smedia.a + .An /usr/lib/libalias_smedia.so -> /lib/libalias_smedia.so.4 + .An /usr/lib/libalias_smedia_p.a + .Ed + .Pp + To take advantage of modules, an application must be + patched to handle SIGHUP signal and call LibAliasRefreshModules() + whenever it receives that signal (see below for details). + .Pp + If you have correctly installed libalias, in /etc you should + find a file called libalias.conf with the following contents (or + similar): + .Pp + .Bd -ragged -offset indent + .An -split + .An /usr/lib/libalias_cuseeme.so + .An /usr/lib/libalias_ftp.so + .An /usr/lib/libalias_irc.so + .An /usr/lib/libalias_nbt.so + .An /usr/lib/libalias_pptp.so + .An /usr/lib/libalias_skinny.so + .An /usr/lib/libalias_smedia.so + .Ed + .Pp + this file contains the paths to the modules that libalias will load. + To load/unload a new module just add its path to libalias.conf and + send a SIGHUP signal to the application that needs the new module: + .Pp + kill -HUP <process pid> + .Pp + .Sh Modular architecture: how it works + The modular architecture of libalias work (almost) the same when it's + running inside kernel or in user land. From alias_mod.c: + .Bd -literal + /* protocol and user land module handlers chains */ + struct chain handler_chain, dll_chain; + + handler_chain keep tracks of all the protocol handlers loaded, while + ddl_chain takes care of userland modules loaded. + + handler_chain is composed of struct proto_handler entries: + + struct proto_handler { + + /* handler priority */ + int pri; + /* flow direction */ + int16_t dir; + /* working protocol */ + int16_t proto; + /* fingerprint * function */ + int (*fingerprint)(struct libalias *la, + struct ip *pip, struct alias_data *ah); + /* aliasing * function */ + int (*protohandler)(struct libalias *la, + struct ip *pip, struct alias_data *ah); + struct proto_handler *next; + }; + .Ed + .Pp + where: + .Pp + pri is the priority assigned to a protocol handler, lower + is better. + .Pp + dir is the direction of packets: ingoing or outgoing. + .Pp + proto says at which protocol this packet belongs: IP, TCP or UDP + .Pp + fingerprint points to the fingerprint function while protohandler points + to the protocol handler function. + .Pp + The fingerprint function has the double of scope of checking if the + incoming packet is sound and if it belongs to any categories that this + module can handle. + .Pp + The protocol handler function is the function that actually manipulates + the packet to make libalias correctly nat it. + .Pp + When a packet enters libalias, if it meets a module hook, + libalias scan handler_chain to see if there's an handler that match + this type of packet (it checks protocol and direction of packet), then if + more then one handler is found, it starts with the module with + a lower priority number: it calls fingerprints and read the result. + .Pp + If the result value is equal to OK, then it calls the protocol handler + of this handler and return, else it skip to the fingerprint function + of the next eligible module, till the end of handler_chain + .Pp + Inside libalias, the module hook looks like this: + .Bd -literal + struct alias_data ad = { + lnk, + &original_address, + &alias_address, + &alias_port, + &ud->uh_sport, /* original source port */ + &ud->uh_dport, /* original dest port */ + 256 /* maxpacketsize */ + }; + + ... + + /* walk out chain */ + err = find_handler(IN, UDP, la, pip, &ad); + if (err == EHDNOF) + ; + .Ed + all data useful to a module are gathered together in a alias_data + structure, then find_handler is called. + find_handler is the function responsible of walking out the handler + chain, it receives as input parameters: + .Pp + IN: direction + .Pp + UDP: working protocol + .Pp + la: pointer to this instance of libalias + .Pp + pip: pointer to a struct ip + .Pp + ad: pointer to struct alias_data (see above) + .Pp + in this case, find_handler will search only for modules registered for + supporting INcoming UDP packets. + .Pp + As i said earlier, libalias in userland is a bit different, cause we + have to take care of module handling too (avoiding duplicate load of + module, avoiding module with same name, etc etc) so dll_chain was + introduced. + .Pp + dll_chain contains a list of all user land libalias modules loaded. + .Pp + When an application calls LibAliasRefreshModules(), libalias first unload + all the loaded modules, then reload all the modules listed in + /etc/libalias.conf: for every module loaded, a new entry to dll_chain + is added. + .Pp + dll_chain is composed of struct dll entries: + .Bd -literal + struct dll { + /* name of module */ + char name[DLL_LEN]; + /* + * ptr to shared obj obtained through + * dlopen() - use this ptr to get access + * to any symbols from a loaded module + * via dlsym() + */ + void *handle; + struct dll *next; + }; + .Ed + name is the name of the module + .Pp + handle is a pointer to the module obtained through dlopen() + .Pp + Whenever a module is loaded in user land, an entry is added to + dll_chain, than every protocol handler present in that module + is resolved and registered in handler_chain. + .Ss How to write a module for libalias + There's a module (called alias_dummy.[ch]) in libalias that can be + used as a skeleton for future work, here we analyse some parts of that + module. + From alias_dummy.c: + .Bd -literal + struct proto_handler handlers [] = {{666, IN|OUT, UDP|TCP, + &fingerprint, &protohandler}}; + .Ed + .Pp + The variable 'handlers' is the 'most important thing' in your module, + cause it describes the handlers present and let the outside world use + it in an opaque way. + .Pp + It must ALWAYS be present in every module, and it MUST retain + the name 'handlers', else if you'll try to load + this module in userland, it will complain about missing symbols: for + more info about module load/unload, please refer to + LibAliasRefreshModules, LibAliasLoadModule and LibAliasUnloadModule in + alias.c + .Pp + handlers[] contains all the proto_handler structures present in a + module. + .Bd -literal + static int + mod_handler(module_t mod, int type, void *data) + { + int error; + + switch (type) { + case MOD_LOAD: + error = 0; + attach_handlers(handlers); + break; + case MOD_UNLOAD: + error = 0; + detach_handlers(handlers; + break; + default: + error = EINVAL; + } + return (error); + } + .Ed + When running as kld, mod_handler register/deregister the module using + attach_handlers/detach_handlers respectively. + .Pp + Every module must contain at least 2 functions: one fingerprint + function and a protocol handler function. + .Bd -literal + #ifdef _KERNEL + static + #endif + int + fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah) { + + ... + } + + #ifdef _KERNEL + static + #endif + int + protohandler(struct libalias *la, struct ip *pip, + struct alias_data *ah) { + + ... + } + .Ed + and they must accept exactly these input parameters. + .Ss Patching an application for user land libalias modules + If you have any application that uses libalias and you want to add it + support for libalias modules, then follow this simple 5 steps + procedure. + .Bd -ragged -offset indent + .An -split + .An 1) first, figure out which file is the main file of your program + .An (let's call it main.c) + + .An 2) add this to the header section of main,c, if not already + .An present: + .Pp + .An #include <signal.h> + .Pp + .An 3) and this just after the header section: + .Pp + .An static void signal_handler(int); + .Pp + .An 4) add this line in the init function of you program or, if it + .An doesn't have any init function, put it in main(): + .Pp + .An signal(SIGHUP, signal_handler); + .Pp + .An 5) and place this function somewhere in main.c: + .Pp + .An static void + .An signal_handler(int sig) { + .Pp + .An LibAliasRefreshModules(); + .An } + .Pp + .An else, if your program already trap SIGHUP signal, just add a call + .An to LibAliasRefreshModules() in the function serving that signal. + .Pp + .An For example, to patch natd to use libalias modules, just add + .An the following line to RefreshAddr (int sig __unused): + .Pp + .An LibAliasRefreshModules() + .Pp + .An recompile and you are done. + .Ed + .Pp + .Ss Logging support in kernel land + .Pp + While working as kld, libalias now have log support that + happens on a buffer allocated inside struct libalias(from alias_local.h): + .Bd -literal + struct libalias { + ... + + /* log descriptor */ + #ifdef KERNEL_LOG + char *logDesc; /* + * ptr to an auto-malloced + * memory buffer when libalias + * works as kld + */ + #else + FILE *logDesc; /* + * ptr to /var/log/alias.log + * when libalias runs as a + * userland lib + */ + #endif + + ... + } + .Ed + so all the applications using libalias, will be able to handle their + own logs, if they want, accessing logDesc. + Moreover, every change to log buffer is automatically added to syslog + with facilities security and info. .Sh BUGS PPTP aliasing does not work when more than one internal client connects to the same external server at the same time, because diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/sys/netinet/raw_ip.c /home/flag/src/freebsd7/src/sys/netinet/raw_ip.c *** /home/flag/src/freebsd7_vanilla/src/sys/netinet/raw_ip.c Sun May 21 21:28:46 2006 --- /home/flag/src/freebsd7/src/sys/netinet/raw_ip.c Sun Jun 11 18:57:27 2006 *************** *** 378,383 **** --- 378,385 ---- case IP_FW_GET: case IP_FW_TABLE_GETSIZE: case IP_FW_TABLE_LIST: + case IP_FW_NAT_GET_CONFIG: + case IP_FW_NAT_GET_LOG: error = suser(curthread); if (error != 0) return (error); *************** *** 443,448 **** --- 445,452 ---- case IP_FW_TABLE_ADD: case IP_FW_TABLE_DEL: case IP_FW_TABLE_FLUSH: + case IP_FW_NAT_CFG: + case IP_FW_NAT_DEL: error = suser(curthread); if (error != 0) return (error); diff -rNPc --exclude=CVS /home/flag/src/freebsd7_vanilla/src/usr.sbin/ppp/main.c /home/flag/src/freebsd7/src/usr.sbin/ppp/main.c *** /home/flag/src/freebsd7_vanilla/src/usr.sbin/ppp/main.c Tue Dec 21 12:12:05 2004 --- /home/flag/src/freebsd7/src/usr.sbin/ppp/main.c Sun Jun 11 18:57:27 2006 *************** *** 328,333 **** --- 328,334 ---- #ifndef NONAT PacketAliasInit(); + LibAliasRefreshModules(); #endif label = ProcessArgs(argc, argv, &sw); --wac7ysb48OaltWcw--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060618153532.GA69905>