Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 13 Nov 2006 23:43:09 +0200
From:      Gleb Kurtsou <k-gleb@yandex.ru>
To:        Chris Dionissopoulos <dionch@freemail.gr>
Cc:        net@freebsd.org
Subject:   Re: macfw -- layer2 firewall
Message-ID:  <20061113214309.GA1366@h1.d>
In-Reply-To: <1039986302.20061113191650@freemail.gr>
References:  <200611090632.kA96Wd5Q098835@repoman.freebsd.org> <20061109200037.GA1398@h1.d> <20061109203858.GB60329@heff.fud.org.nz> <20061110200328.GA6904@h1.d> <20061110232108.GA65230@heff.fud.org.nz> <20061113114731.GA1620@h1.d> <1039986302.20061113191650@freemail.gr>

next in thread | previous in thread | raw e-mail | index | archive | help

--BXVAT5kNtrzKuDFl
Content-Type: text/plain; charset=koi8-r
Content-Disposition: inline

On (13/11/2006 19:16), Chris Dionissopoulos wrote:
[...]
> > In case somebody is interested..
> 
> I'm really interest to test your patch.

It looks like attachment was striped. Resending it.


--BXVAT5kNtrzKuDFl
Content-Type: text/plain; charset=koi8-r
Content-Disposition: attachment; filename="macfw.shar.txt"

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	macfw
#	macfw/etc
#	macfw/etc/rc.fw.mac
#	macfw/etc/rc.d
#	macfw/etc/rc.d/macfw.sh
#	macfw/etc/rc.fw.mac-admin
#	macfw/etc/rc.conf
#	macfw/macfwctl
#	macfw/macfwctl/macfwctl.c
#	macfw/macfwctl/Makefile
#	macfw/module
#	macfw/module/Makefile
#	macfw/module/macfw.c
#	macfw/module/macfwvar.h
#	macfw/module/patch-sys-macfw
#
echo c - macfw
mkdir -p macfw > /dev/null 2>&1
echo c - macfw/etc
mkdir -p macfw/etc > /dev/null 2>&1
echo x - macfw/etc/rc.fw.mac
sed 's/^X//' >macfw/etc/rc.fw.mac << 'END-of-macfw/etc/rc.fw.mac'
X192.168.77.38 00:D0:59:12:F4:F9
X192.168.77.40 00:A0:D2:10:3D:EF
X192.168.77.14 00:0A:E6:30:CF:5D
X192.168.77.15 4C:00:10:53:73:76
X192.168.77.9 00:04:61:6C:AB:C7
X192.168.77.47 00:0A:E6:77:06:FA
X192.168.77.90 00:02:A5:14:81:4C
X192.168.78.142 00:50:22:B0:8E:05
X192.168.77.49 4C:00:10:27:0E:F5
X192.168.77.41 00:AA:00:AD:04:15
X192.168.77.11 00:50:22:49:11:19
X192.168.77.151 00:04:61:5E:71:27
X192.168.77.165 00:04:61:4C:33:F5
X192.168.77.12 00:50:22:B0:9C:82
X192.168.77.18 00:04:61:52:0F:4E
X192.168.77.19 00:00:10:00:04:E8
X192.168.77.7 00:04:61:77:D9:3B
X192.168.77.16 00:04:61:43:AF:29
X192.168.77.21 00:10:B5:41:7C:FF
X192.168.77.13 00:04:75:E0:B4:61
X192.168.77.24 00:40:F4:7F:A1:3E
X192.168.77.152 00:04:4B:80:80:07
X192.168.77.156 00:13:8F:27:11:A3
X192.168.77.159 00:04:61:7B:38:6B
X192.168.77.181 00:0A:E6:7C:2D:37
X192.168.77.177 00:04:61:73:2D:75
X192.168.77.171 00:C0:DF:0F:DF:98
X192.168.77.157 00:0D:87:5F:42:E5
X192.168.77.155 00:E0:4C:77:60:95
X192.168.77.163 00:E0:4C:60:00:23
X192.168.77.162 00:14:78:02:C0:FC
X192.168.77.175 00:0A:E6:AD:FD:FB
X192.168.77.25 00:04:61:65:08:13
X192.168.77.29 00:0A:E6:30:D8:EE
X192.168.77.31 4C:00:10:54:AF:52
X192.168.77.37 00:04:61:93:D2:04
X192.168.77.99 C0:01:DE:AD:BA:BE
X192.168.77.50 00:C0:DF:10:BF:A8
X192.168.78.133 00:0C:F1:7D:F2:AD
X192.168.78.134 00:60:98:EF:2F:10
X192.168.78.135 00:80:48:23:2C:2E
X192.168.78.140 00:14:85:4B:0A:1B
X192.168.78.137 00:0A:48:18:20:4A
X192.168.78.148 00:13:8F:61:F1:80
X192.168.78.147 4C:00:10:73:28:E1
X192.168.76.1 00:0F:3D:34:8F:98
X192.168.78.20 00:03:47:B9:A5:B2
X192.168.77.153 00:04:61:4E:91:B0
X192.168.77.160 00:0A:E6:61:56:91
X192.168.77.154 00:02:44:69:88:3C
X192.168.77.161 00:50:CF:40:EE:20
X192.168.77.164 00:E0:4C:60:00:8C
X192.168.78.8 4C:00:10:73:14:7C
X192.168.78.5 00:04:61:12:34:56
X192.168.78.139 4C:00:10:71:25:C1
X192.168.78.11 00:0C:6E:06:57:76
X192.168.78.145 00:50:22:91:CD:CD
X192.168.77.34 00:15:F2:1D:2E:44
X192.168.77.43 00:04:61:4F:7E:2A
X192.168.78.153 00:50:FC:A1:A8:A2
X192.168.76.101 00:02:44:59:C9:30
X192.168.76.18 4C:00:10:3A:E4:12
X192.168.77.35 00:50:22:C8:93:72
X192.168.78.131 00:E0:4C:15:60:90
X192.168.78.150 00:E0:4C:A8:DC:48
X192.168.78.18 00:04:61:59:7F:74
X192.168.77.26 00:80:AD:79:51:B0
X192.168.77.33 4C:00:10:3A:5C:2F
X192.168.77.45 4C:00:10:53:79:9A
X192.168.78.151 00:13:8F:51:21:36
X192.168.76.4 00:05:5D:34:2C:D8
X192.168.76.99 00:02:44:75:B1:F1
X192.168.77.39 4C:00:10:00:FF:32
X192.168.76.13 00:17:31:E4:0D:53
X192.168.76.30 00:A0:D2:11:AB:E6
X192.168.79.59 00:13:D4:54:1A:9C
X192.168.76.33 00:08:A1:7E:F5:77
X192.168.76.35 00:E0:4C:70:6E:0B
X192.168.78.136 00:14:85:0B:6F:6A
X192.168.76.117 00:0F:EA:F4:45:54
X192.168.76.103 00:50:22:9B:FA:57
X192.168.77.48 00:E0:4C:21:A2:8F
X192.168.76.76 00:02:44:73:7C:C5
X192.168.76.77 00:0F:EA:8A:BB:61
X192.168.76.3 00:02:44:75:B2:00
X192.168.77.190 00:02:44:6F:F4:40
X192.168.77.46 00:0B:6A:77:DB:9C
X192.168.76.24 00:05:1C:0F:EF:0A
X192.168.78.132 00:04:61:58:50:7E
X192.168.76.5 A0:00:8F:E0:1A:1F
X192.168.76.6 00:50:22:C8:40:A3
X192.168.77.44 00:0E:A6:C0:57:21
X192.168.77.52 00:04:61:55:F0:8E
X192.168.78.12 4C:00:10:A2:5C:4D
X192.168.78.141 00:60:98:EF:14:06
X192.168.77.27 00:E0:4C:AA:1B:CB
X192.168.77.30 00:0D:9D:5F:8E:04
X192.168.78.15 00:0F:EA:3E:DB:1C
X192.168.78.6 00:04:61:98:56:B8
X192.168.76.21 00:C0:F6:B3:89:52
X192.168.76.16 4C:00:10:3B:21:21
X192.168.76.22 00:50:22:BB:28:94
X192.168.76.9 00:11:95:F5:6C:4D
X192.168.78.146 4C:00:10:74:E1:F5
X192.168.78.16 4C:00:10:76:0F:54
X192.168.78.13 00:0F:B0:A5:3E:06
X192.168.78.19 4C:00:10:51:10:51
X192.168.78.7 00:0C:F1:B9:72:CE
X192.168.78.143 00:0D:61:2E:B6:40
X192.168.78.14 00:04:61:55:9C:96
X192.168.76.14 00:40:F4:86:12:47
X192.168.76.7 00:02:44:34:F2:FA
X192.168.76.11 00:02:44:72:5B:C2
X192.168.78.152 4C:00:10:74:E7:32
X192.168.78.9 00:11:D8:A3:61:28
X192.168.76.34 00:04:61:79:EE:A5
X192.168.76.20 4C:00:10:74:A4:4C
X192.168.76.23 00:0A:E6:5C:F8:B2
X192.168.76.69 00:10:A4:96:B1:07
X192.168.76.25 00:04:61:79:29:CE
X192.168.77.196 00:10:A4:E9:48:40
X192.168.76.32 00:0A:CD:03:A9:13
X192.168.76.10 00:0F:EA:2B:A2:CC
X192.168.78.149 4C:00:10:51:19:CF
X192.168.77.53 00:04:61:63:CC:DB
X192.168.76.39 00:10:5A:BC:29:98
X192.168.79.57 00:14:85:85:69:2D
X192.168.76.15 00:02:44:72:5B:85
X192.168.76.36 00:C0:DF:07:F4:70
X192.168.78.21 00:15:F2:20:C3:6E
X192.168.79.9 00:03:47:0F:84:65
X192.168.76.37 00:40:F4:B6:12:A5
X192.168.76.38 00:08:A1:7F:0D:3C
X192.168.78.22 00:0A:48:17:13:42
X192.168.78.23 00:02:B3:48:C6:E8
X192.168.78.154 00:0A:E6:C7:0B:36
X192.168.77.55 00:02:44:57:00:11
X192.168.77.56 00:04:61:EB:FF:FF
X192.168.78.167 00:00:E2:7B:3F:1B
X192.168.77.54 00:0F:EA:37:B9:09
X192.168.77.57 00:0B:6A:A9:9C:3E
X192.168.78.24 00:0D:88:39:ED:84
X192.168.79.65 00:20:ED:7C:9C:44
X192.168.77.59 00:00:10:00:06:0E
X192.168.77.60 4C:00:10:3A:D3:A4
X192.168.78.31 00:04:61:65:C5:2F
X192.168.76.75 4C:00:10:74:B4:0D
X192.168.79.102 00:E0:4C:77:17:49
X192.168.76.40 00:C0:DF:0D:E2:08
X192.168.79.54 00:C0:26:A6:96:EA
X192.168.78.26 00:0D:88:39:EE:20
X192.168.78.27 00:D0:B7:B2:3F:37
X192.168.78.25 00:04:61:53:94:22
X192.168.77.65 00:0F:EA:B6:C2:65
X192.168.79.156 00:11:95:26:F5:5C
X192.168.79.157 00:0A:E6:74:91:D9
X192.168.79.153 00:E0:4C:21:A5:62
X192.168.79.56 00:11:95:26:F5:6B
X192.168.77.69 00:10:DC:70:D8:9A
X192.168.76.41 4C:00:10:3A:D4:29
X192.168.78.156 00:E0:4C:21:A5:4E
X192.168.76.46 00:0B:6A:7F:A8:06
X192.168.76.45 00:50:22:B0:92:F8
X192.168.76.42 00:14:78:02:A4:C4
X192.168.79.161 00:60:98:EF:36:18
X192.168.79.162 00:13:8F:7D:29:34
X192.168.77.73 00:04:61:94:3F:FE
X192.168.79.160 00:01:6C:E6:86:6F
X192.168.78.157 00:E0:4C:21:A6:0D
X192.168.76.43 04:68:02:40:02:15
X192.168.79.16 00:04:61:7A:41:93
X192.168.78.158 00:11:95:5C:2A:80
X192.168.79.5 00:04:61:5D:EE:42
X192.168.79.6 00:04:61:68:32:74
X192.168.76.49 00:03:0D:35:35:79
X192.168.76.51 00:04:61:69:71:54
X192.168.79.8 00:E0:4C:15:60:92
X192.168.78.163 00:E0:4C:7D:3D:36
X192.168.78.164 00:00:0E:21:02:C7
X192.168.76.52 00:11:D8:9F:E8:55
X192.168.79.7 00:0A:E4:A9:38:D5
X192.168.76.50 4C:00:10:74:B5:3A
X192.168.78.160 00:04:61:77:94:DA
X192.168.79.159 00:04:61:52:15:E8
X192.168.79.101 00:02:44:96:A2:D7
X192.168.79.163 4C:00:10:74:99:64
X192.168.76.60 00:0B:6A:AE:8C:AF
X192.168.76.61 00:30:18:43:BA:CE
X192.168.78.162 00:02:44:83:B5:10
X192.168.77.61 4C:00:10:51:37:46
X192.168.76.64 7A:00:B1:90:57:08
X192.168.77.74 00:0B:6A:7D:48:B7
X192.168.79.61 00:08:02:DE:00:2E
X192.168.77.75 00:E0:4C:F0:02:81
X192.168.77.79 00:50:22:93:D7:57
X192.168.77.176 00:C0:DF:03:19:FF
X192.168.79.165 00:E0:4C:77:27:45
X192.168.78.44 00:04:61:71:1D:AC
X192.168.78.30 00:04:61:43:75:DD
X192.168.77.183 00:14:85:86:1B:35
X192.168.77.191 4C:00:10:71:CF:D2
X192.168.78.168 00:01:6C:29:1B:38
X192.168.77.185 4C:00:10:3B:4A:B7
X192.168.78.34 00:14:85:F4:6B:C8
X192.168.77.81 00:0D:87:86:B3:C6
X192.168.77.95 00:C0:9F:91:33:58
X192.168.78.32 00:E0:4C:1A:B8:D7
X192.168.76.62 00:0B:6A:A9:06:5F
X192.168.79.51 00:00:10:00:00:00
X192.168.77.188 00:80:48:40:13:EF
X192.168.78.178 00:0B:6A:89:09:20
X192.168.77.166 4C:00:10:3B:76:3B
X192.168.79.60 00:13:8F:88:A9:F3
X192.168.79.62 00:E0:4C:45:1E:22
X192.168.77.82 00:0A:E6:85:E7:E0
X192.168.76.55 00:04:61:97:C4:DE
X192.168.77.83 00:13:8F:BB:F0:51
X192.168.77.84 00:13:D3:5E:FB:83
X192.168.77.192 00:11:2F:D9:81:5B
X192.168.79.18 00:E0:4C:D9:CC:D2
X192.168.79.155 00:14:85:4A:38:70
X192.168.79.158 00:E0:4C:77:1B:CA
X192.168.78.39 00:0F:EA:A2:31:98
X192.168.78.37 00:11:43:56:50:7F
X192.168.77.85 00:04:61:A3:68:0A
X192.168.77.193 00:13:8F:26:53:02
X192.168.77.86 00:02:44:AB:DB:51
X192.168.76.17 00:02:44:75:21:3C
X192.168.79.103 00:10:4B:57:F0:66
X192.168.77.70 00:C0:DF:03:14:92
X192.168.76.47 00:A1:B0:A2:D0:BE
X192.168.77.87 00:02:44:AB:DB:01
X192.168.78.170 00:14:78:02:C0:FE
X192.168.79.10 00:04:61:A7:20:90
X192.168.78.171 00:0F:EA:B8:D3:F1
X192.168.78.38 00:14:85:8A:F0:F5
X192.168.78.42 AA:AA:AA:AA:AA:AA
X192.168.78.165 00:00:00:00:E2:BB
X192.168.77.32 00:0C:6E:01:78:09
X192.168.78.48 00:E0:4C:A4:DF:3C
X192.168.79.17 00:15:F2:5C:ED:28
X192.168.77.91 00:04:61:76:AD:69
X192.168.78.172 00:0C:29:7F:AB:54
X192.168.79.152 00:13:8F:71:6E:BF
X192.168.79.151 00:0F:B0:93:00:13
X192.168.79.11 00:E0:4C:00:7B:22
X192.168.76.58 00:13:8F:2A:B4:81
X192.168.78.177 00:40:F4:B2:8B:44
X192.168.78.161 00:E0:4C:81:63:55
X192.168.78.174 00:E0:4C:A4:78:68
X192.168.77.62 00:04:61:6D:C6:86
X192.168.77.63 00:0B:6A:C7:43:CD
X192.168.78.175 00:13:8F:5E:EC:D7
X192.168.77.76 00:04:4B:80:80:03
X192.168.77.66 00:13:8F:3C:04:7C
X192.168.79.12 00:40:F4:CF:BC:18
X192.168.77.42 00:04:61:74:77:BD
X192.168.79.13 00:13:8F:6C:9D:A2
X192.168.76.67 00:0F:EA:2C:B1:B8
X192.168.76.44 00:15:60:C6:CE:8D
X192.168.79.14 00:E0:4C:A8:BB:06
X192.168.76.59 00:13:46:61:D8:88
X192.168.79.52 00:0C:76:38:0B:3C
X192.168.78.43 00:04:61:A8:3A:5F
X192.168.78.180 00:30:84:89:09:5B
X192.168.77.93 00:E0:4C:AA:E2:FB
X192.168.77.71 00:E0:4C:77:17:77
X192.168.76.19 00:E0:4C:60:6D:2A
X192.168.78.45 00:D0:59:BF:4A:04
X192.168.78.46 00:04:61:A3:05:C4
X192.168.78.181 00:0A:48:1D:E3:7C
X192.168.79.68 00:13:D4:6A:F8:B9
X192.168.76.68 00:D0:59:C1:C9:49
X192.168.76.54 00:11:2F:BD:08:B2
X192.168.78.182 00:FF:34:24:39:35
X192.168.78.183 00:13:8F:51:24:07
X192.168.78.47 4C:00:10:53:5C:61
X192.168.78.184 00:04:61:9F:7C:89
X192.168.79.19 00:E0:4C:EF:28:B3
X192.168.76.70 00:0A:48:0E:56:EF
X192.168.78.185 00:04:61:A8:7F:53
X192.168.76.71 00:13:8F:9F:B4:FC
X192.168.78.49 00:14:85:51:CD:49
X192.168.76.28 00:10:60:F6:F4:B6
X192.168.77.97 00:17:08:3D:81:8E
X192.168.76.72 00:14:85:10:3D:E6
X192.168.79.20 00:13:D3:3A:9B:43
X192.168.79.22 00:14:C2:D7:22:5F
X192.168.77.98 00:E0:4C:5A:D6:5B
X192.168.77.80 00:E0:4C:69:A0:E5
X192.168.77.170 00:15:E9:3D:3E:68
X192.168.77.178 00:16:36:3C:42:07
X192.168.77.198 00:D0:59:83:A4:13
X192.168.78.186 00:04:61:9F:23:31
X192.168.78.50 00:14:85:85:AE:CC
X192.168.76.73 00:0B:6A:E8:39:40
X192.168.79.69 00:13:8F:BC:A4:37
X192.168.79.70 00:40:CA:DE:F3:82
X192.168.78.188 00:16:E6:5C:AD:F8
X192.168.78.187 00:04:61:FF:FF:F1
X192.168.78.51 00:E0:4C:1A:D0:87
X192.168.76.81 00:E0:4C:85:2B:B2
X192.168.78.52 00:50:22:B0:8C:57
X192.168.76.85 00:15:E9:41:A0:8C
X192.168.78.53 00:02:44:8C:A4:45
X192.168.78.54 00:13:8F:35:91:35
X192.168.77.200 00:17:31:B6:F1:9C
X192.168.78.189 00:D0:59:A1:D5:AF
X192.168.77.101 00:01:6C:B8:E6:23
X192.168.78.55 00:08:A1:9F:38:97
X192.168.79.166 00:0E:A6:6D:47:D6
X192.168.79.71 00:C0:9F:C0:EC:F3
X192.168.79.72 00:13:8F:E2:46:38
X192.168.78.190 00:10:A4:C1:BC:11
X192.168.76.86 00:01:6C:F3:6A:BC
X192.168.77.202 00:0B:6A:ED:85:01
X192.168.77.203 00:13:8F:44:27:02
X192.168.77.201 00:50:70:C5:4C:C4
X192.168.77.205 00:04:61:6E:60:38
X192.168.78.191 00:01:02:F0:DA:88
X192.168.78.192 00:50:22:83:0C:D6
X192.168.77.204 00:00:00:00:00:00
X192.168.76.74 00:13:8F:C7:A3:B3
END-of-macfw/etc/rc.fw.mac
echo c - macfw/etc/rc.d
mkdir -p macfw/etc/rc.d > /dev/null 2>&1
echo x - macfw/etc/rc.d/macfw.sh
sed 's/^X//' >macfw/etc/rc.d/macfw.sh << 'END-of-macfw/etc/rc.d/macfw.sh'
X#!/bin/sh
X#
X
X# PROVIDE: macfw
X# REQUIRE: root mountcritlocal netif
X# KEYWORD: nojail
X
X. /etc/rc.subr
X
Xname="macfw"
Xrcvar=`set_rcvar`
Xload_rc_config $name
Xstart_cmd="macfw_start"
Xstop_cmd="macfw_stop"
X
Xmacfw_start()
X{
X	echo -n "Enabling macfw: "
X	/root/bin/macfwctl disable
X	/root/bin/macfwctl flush
X	for _f in $macfw_files; do
X		if [ -f $_f ]; then
X			echo -n "$_f "
X			while read _ip _mac; do
X				if [ -z "$_ip" -o -z "$_mac" ]; then 
X					continue
X				fi
X				/root/bin/macfwctl -d add "$_ip" "$_mac" 
X				# || exit 1
X			done < $_f
X		fi
X	done
X	/root/bin/macfwctl enable
X	echo "."
X}
X
Xmacfw_stop()
X{
X	echo "Disabling macfw."
X	/root/bin/macfwctl disable
X}
X
Xrun_rc_command "$1"
X
END-of-macfw/etc/rc.d/macfw.sh
echo x - macfw/etc/rc.fw.mac-admin
sed 's/^X//' >macfw/etc/rc.fw.mac-admin << 'END-of-macfw/etc/rc.fw.mac-admin'
X192.168.77.9 00:04:61:6C:AB:C7
X192.168.77.7 00:04:61:77:D9:3B
X192.168.79.60 00:13:8F:88:A9:F3
END-of-macfw/etc/rc.fw.mac-admin
echo x - macfw/etc/rc.conf
sed 's/^X//' >macfw/etc/rc.conf << 'END-of-macfw/etc/rc.conf'
Xmacfw_files="/etc/rc.fw.mac-admin   /etc/rc.fw.mac"
Xmacfw_enable="YES"
END-of-macfw/etc/rc.conf
echo c - macfw/macfwctl
mkdir -p macfw/macfwctl > /dev/null 2>&1
echo x - macfw/macfwctl/macfwctl.c
sed 's/^X//' >macfw/macfwctl/macfwctl.c << 'END-of-macfw/macfwctl/macfwctl.c'
X/*-
X * Copyright (c) 2006 Gleb Kurtsov 
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X *
X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X *
X */
X
X#include <sys/types.h>
X#include <sys/sysctl.h>
X#include <sys/socket.h>
X#include <netinet/in.h>
X#include <arpa/inet.h>
X#include <fcntl.h>
X#include <stdio.h>
X#include <errno.h>
X#include <string.h>
X#include <getopt.h>
X#include <libgen.h>
X
X#include "macfwvar.h"
X
X#define MACFW_DEV 		"/dev/macfw"
X#define MACFW_SYSCTL 		"net.inet.macfw"
X
Xstatic char *argv0;
Xstatic int opt_v = 0, opt_d = 0;
X
Xstatic int ac_stat(int macfw_fd, int argc, char **argv);
Xstatic int ac_enable(int macfw_fd, int argc, char **argv);
Xstatic int ac_show(int macfw_fd, int argc, char **argv);
Xstatic int ac_add(int macfw_fd, int argc, char **argv);
Xstatic int ac_flush(int macfw_fd, int argc, char **argv);
X
Xstruct ac_t {
X	const char *cmd, *args;
X	int open_flags;
X	int (*handler)(int, int, char **);
X};
Xstatic const struct ac_t acs[] = {
X	{ .cmd = "stat", .handler = ac_stat, .open_flags = -1 },
X	{ .cmd = "enable", .handler = ac_enable, .open_flags = -1 },
X	{ .cmd = "disable", .handler = ac_enable, .open_flags = -1 },
X	{ .cmd = "show", .handler = ac_show, .open_flags = O_RDONLY },
X	{ .cmd = "add", .handler = ac_add, .open_flags = O_RDWR, .args = "<ip> <mac>" },
X	{ .cmd = "flush", .handler = ac_flush, .open_flags = O_RDWR },
X	{ .cmd = "zero", .handler = ac_flush, .open_flags = O_RDWR },
X	{ .cmd = NULL }
X};
X
Xstatic void usage()
X{
X	const struct ac_t *ac;
X	
X	fprintf(stderr, "usage: %s [-vd] <command>\n"
X			"where <command> is one of:\n", argv0);
X	for (ac = &acs[0]; ac->cmd != NULL; ++ac) {
X		fprintf(stderr, "\t%s %s\n", ac->cmd, (ac->args == NULL ? "" : ac->args));
X	}
X}
X
Xstatic int ac_stat(int macfw_fd, int argc, char **argv)
X{
X	char buf[128];
X	struct {
X		unsigned int val;
X		const char *name;
X		const char *descr;
X	} _stat[] = {
X		{ .name = "enable", .descr = "Enabled" },
X		{ .name = "stat.pass", .descr = "Packets passed" },
X		{ .name = "stat.unknown", .descr = "Packets ignored" },
X		{ .name = "stat.spoof_ip", .descr = "Packets with spoofed IP" },
X		{ .name = "stat.spoof_mac", .descr = "Packets with spoofed MAC" },
X		{ .name = NULL }
X	}, *stat = _stat;
X	size_t sz;
X	int s;
X
X	for (; stat[0].name; ++stat) {
X		snprintf(buf, sizeof(buf), "%s.%s", MACFW_SYSCTL, stat[0].name);
X		sz = sizeof(stat[0].val);
X		s = sysctlbyname(buf, &stat[0].val, &sz, NULL, 0);
X		if (s == -1) {
X			fprintf(stderr, "sysctl(%s): %s\n", buf, strerror(errno));
X			return (2);
X		}
X		printf("%s: %u\n", stat[0].descr, stat[0].val);
X	}
X	return (0);
X}
X
Xstatic int ac_enable(int macfw_fd, int argc, char **argv)
X{
X	const char *buf = MACFW_SYSCTL ".enable";
X	int val, s;
X
X	val = (argv[0][0] == 'e' ? 1 : 0);
X	s = sysctlbyname(buf, NULL, NULL, &val, sizeof(val));
X	if (s == -1) {
X		fprintf(stderr, "sysctl(%s): %s\n", buf, strerror(errno));
X		return (2);
X	}
X	return (0);
X}
X
X
Xstatic int ac_show(int macfw_fd, int argc, char **argv)
X{
X	struct macfwioc_rule mr;
X	int s;
X
X	bzero(&mr, sizeof(struct macfwioc_rule));
X	s = ioctl(macfw_fd, MACFWIOCGETRULE, &mr);
X	while (s != -1) {
X		printf("%-16s %-18s%s",
X				inet_ntoa(mr.mr_in),
X				ether_ntoa(&mr.mr_ether),
X				(opt_v ? " " : "\n"));
X		if (opt_v)
X			printf("[ Pass: %5u, Spoofed IP: %5u, Spoofed MAC: %5u ]\n",
X					mr.mr_stat_pass, mr.mr_stat_spoof_ip, mr.mr_stat_spoof_mac);
X		s = ioctl(macfw_fd, MACFWIOCGETRULE, &mr);
X	}
X	if (errno != ENOENT) {
X		fprintf(stderr, "ioctl(%s, MACFWIOCGETRULE): %s\n", MACFW_DEV, strerror(errno));
X		return (3);
X	}
X	return (0);
X}
X
Xstatic int ac_add(int macfw_fd, int argc, char **argv)
X{
X	struct macfwioc_rule mr;
X	struct ether_addr *ea;
X	int s;
X
X	argc -= 1;
X	argv += 1;
X
X	bzero(&mr, sizeof(struct macfwioc_rule));
X	if (argc != 2 || (ea = ether_aton(argv[1])) == NULL || 
X			inet_aton(argv[0], &mr.mr_in) == 0) {
X		fprintf(stderr, "%s: add rule: illegal arguments\n", argv0);
X		usage();
X		return (1);
X	}
X	mr.mr_ether = *ea;
X	s = ioctl(macfw_fd, MACFWIOCADDRULE, &mr);
X	if (s == -1 && !(opt_d != 0 && errno == EEXIST)) {
X		fprintf(stderr, "ioctl(%s, MACFWIOCADDRULE): %s, %s: %s\n", 
X				MACFW_DEV, argv[0], argv[1], strerror(errno));
X		return (3);
X	}
X	return (0);
X}
X
Xstatic int ac_flush(int macfw_fd, int argc, char **argv)
X{
X	int s;
X
X	s = ioctl(macfw_fd, (argv[0][0] == 'f' ? MACFWIOCFLUSH : MACFWIOCZERO));
X	if (s == -1) {
X		fprintf(stderr, "ioctl(%s, MACFWIOCFLUSH): %s\n", MACFW_DEV, strerror(errno));
X		return (3);
X	}
X	return (0);
X}
X
Xint main(int argc, char** argv)
X{
X	int macfw_fd;
X	const struct ac_t *ac;
X	    
X	int s;
X
X	argv0 = basename(argv[0]);
X
X	for(s=0; s != '?' && (s = getopt(argc, argv, "vd")) != -1;) {
X		switch(s) {
X		case 'v':
X			opt_v = 1;
X			break;
X		case 'd':
X			opt_d = 1;
X			break;
X		default:
X			s = '?';
X		}
X	}
X
X	if (s == '?') {
X		usage();
X		return (1);
X	}
X	argc -= optind;
X	argv += optind;
X
X	if (argc < 1) {
X		ac = &acs[0];
X	} else {
X		const struct ac_t *ac_i;
X
X		for (ac = NULL, ac_i = &acs[0]; ac_i->cmd != NULL; ++ac_i) {
X			if (strcmp(argv[0], ac_i->cmd) == 0) {
X				ac = ac_i;
X				break;
X			}
X		}
X	}
X	if (ac == NULL) {
X		fprintf(stderr, "%s: illegal command: %s\n", argv0, argv[0]);
X		usage();
X		return (1);
X	}
X
X	if (ac->open_flags != -1) {
X		macfw_fd = open(MACFW_DEV, ac->open_flags);
X		if (macfw_fd == -1) {
X			fprintf(stderr, "open(%s): %s\n", MACFW_DEV, strerror(errno));
X			return (2);
X		}
X	} else {
X		macfw_fd = -1;
X	}
X
X	s = ac->handler(macfw_fd, argc, argv);
X
X	return (s);
X}
X
END-of-macfw/macfwctl/macfwctl.c
echo x - macfw/macfwctl/Makefile
sed 's/^X//' >macfw/macfwctl/Makefile << 'END-of-macfw/macfwctl/Makefile'
X
XPROG=		macfwctl
X
XCFLAGS+=	-I../module
X
X#DEBUG_FLAGS=	-O0 -g
X
XWARNS=		2
XNO_WERROR=	yes
X
X.if !defined(NODEBUG)
XDEBUG_FLAGS=	-g
X.endif
X
XNO_MAN=		yes
X
X.include <bsd.prog.mk>
END-of-macfw/macfwctl/Makefile
echo c - macfw/module
mkdir -p macfw/module > /dev/null 2>&1
echo x - macfw/module/Makefile
sed 's/^X//' >macfw/module/Makefile << 'END-of-macfw/module/Makefile'
X#
X
XKMOD=		macfw
XSRCS=		macfw.c
X
X#DEBUG_FLAGS+= 	-DMACFW_DEBUG
X
X.include <bsd.kmod.mk>
END-of-macfw/module/Makefile
echo x - macfw/module/macfw.c
sed 's/^X//' >macfw/module/macfw.c << 'END-of-macfw/module/macfw.c'
X/*-
X * Copyright (c) 2006 Gleb Kurtsov 
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X *
X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X *
X */
X
X#include <sys/param.h>
X#include <sys/systm.h>
X#include <sys/conf.h>
X#include <sys/lock.h>
X#include <sys/sx.h>
X#include <sys/mbuf.h>
X#include <sys/module.h>
X#include <sys/kernel.h>
X#include <sys/fcntl.h>
X#include <sys/sysctl.h>
X#include <sys/socket.h>
X#include <sys/socketvar.h>
X#include <sys/sysctl.h>
X#include <sys/syslog.h>
X#include <sys/stat.h>
X#include <sys/tree.h>
X#include <vm/uma.h>
X#include <net/if.h>
X#include <net/if_dl.h>
X#include <net/pfil.h>
X#include <net/ethernet.h>
X#include <net/route.h>
X#include <netinet/in.h>
X#include <netinet/in_systm.h>
X#include <netinet/in_var.h>
X#include <netinet/in_pcb.h>
X#include <netinet/ip.h>
X#include <netinet/ip_var.h>
X
X#include "macfwvar.h"
X
X#define MACFW_NAME "macfw"
X
Xstatic d_ioctl_t macfw_ioctl;
X
Xstatic struct cdevsw macfw_devsw = {
X	.d_version = D_VERSION,
X	.d_ioctl = macfw_ioctl,
X	.d_name = MACFW_NAME
X};
Xstatic int macfw_enable = 0;
Xstatic int macfw_log = 0;
Xstatic int macfw_pfil_hooked = 0;
Xstatic int macfw_ticket = 1;
Xstatic struct sx macfw_sxlock;
X
Xstatic struct cdev *macfw_dev;
X
Xstatic unsigned int macfw_stat_unknown = 0;
X
Xstruct macfw_entry {
X	RB_ENTRY(macfw_entry) macfwe_in_entry;
X	RB_ENTRY(macfw_entry) macfwe_ether_entry;
X	struct in_addr macfwe_in;
X	struct ether_addr macfwe_ether;
X	unsigned int macfwe_stat_pass;
X	unsigned int macfwe_stat_spoof_ip;
X	unsigned int macfwe_stat_spoof_mac;
X};
X
Xuma_zone_t macfw_entry_zone;
X
Xstatic int macfwe_in_cmp(struct macfw_entry *, struct macfw_entry *);
Xstatic int macfwe_ether_cmp(struct macfw_entry *, struct macfw_entry *);
X
XRB_HEAD(macfw_in_tree, macfw_entry);
XRB_PROTOTYPE(macfw_in_tree, macfw_entry, macfwe_in_entry, macfwe_in_cmp);
X
XRB_HEAD(macfw_ether_tree, macfw_entry);
XRB_PROTOTYPE(macfw_ether_tree, macfw_entry, macfwe_ether_entry, macfwe_ether_cmp);
X
Xstatic struct macfw_in_tree macfw_in_q;
Xstatic struct macfw_ether_tree macfw_ether_q;
X
XRB_GENERATE(macfw_in_tree, macfw_entry, macfwe_in_entry, macfwe_in_cmp);
XRB_GENERATE(macfw_ether_tree, macfw_entry, macfwe_ether_entry, macfwe_ether_cmp);
X
Xstatic int macfw_sysctl(SYSCTL_HANDLER_ARGS);
X
XSYSCTL_NODE(_net_inet, OID_AUTO, macfw, CTLFLAG_RW, 0, "macfw");
XSYSCTL_INT(_net_inet_macfw, OID_AUTO, enable, CTLFLAG_RW | CTLFLAG_SECURE3,
X	&macfw_enable, 0, "Enable macfw");
XSYSCTL_INT(_net_inet_macfw, OID_AUTO, log, CTLFLAG_RW | CTLFLAG_SECURE3,
X	&macfw_log, 0, "Log spoof attempts");
XSYSCTL_NODE(_net_inet_macfw, OID_AUTO, stat, CTLFLAG_RW, 0, "Statistics");
XSYSCTL_UINT(_net_inet_macfw_stat, OID_AUTO, unknown, CTLFLAG_RD,
X	&macfw_stat_unknown, 0, "Unknown");
XSYSCTL_PROC(_net_inet_macfw_stat, OID_AUTO, pass, CTLTYPE_UINT|CTLFLAG_RD,
X	0, __offsetof(struct macfw_entry, macfwe_stat_pass), macfw_sysctl, "IU", "Pass");
XSYSCTL_PROC(_net_inet_macfw_stat, OID_AUTO, spoof_ip, CTLTYPE_UINT|CTLFLAG_RD,
X	0, __offsetof(struct macfw_entry, macfwe_stat_spoof_ip), macfw_sysctl, "IU", "Spoofed IP");
XSYSCTL_PROC(_net_inet_macfw_stat, OID_AUTO, spoof_mac, CTLTYPE_UINT|CTLFLAG_RD,
X	0, __offsetof(struct macfw_entry, macfwe_stat_spoof_mac), macfw_sysctl, "IU", "Spoofed MAC");
X
Xstatic int macfw_sysctl(SYSCTL_HANDLER_ARGS)
X{
X	struct macfw_entry *e;
X	unsigned int r = 0;
X
X	sx_slock(&macfw_sxlock);
X	RB_FOREACH(e, macfw_in_tree, &macfw_in_q) {
X		r += *(unsigned int*)(((char*)e) + arg2);
X	}
X	sx_sunlock(&macfw_sxlock);
X
X	return (SYSCTL_OUT(req, &r, sizeof(r)));
X}
X
Xstatic int macfwe_in_cmp(struct macfw_entry *a, struct macfw_entry *b)
X{
X	if (ntohl(a->macfwe_in.s_addr) > ntohl(b->macfwe_in.s_addr))
X		return (1);
X	if (ntohl(a->macfwe_in.s_addr) < ntohl(b->macfwe_in.s_addr))
X		return (-1);
X	return (0);
X}
X
Xstatic int macfwe_ether_cmp(struct macfw_entry *a, struct macfw_entry *b)
X{
X	int i;
X
X	for (i = 0; i < ETHER_ADDR_LEN; ++i) {
X		if (a->macfwe_ether.octet[i] > b->macfwe_ether.octet[i])
X			return (1);
X		if (a->macfwe_ether.octet[i] < b->macfwe_ether.octet[i])
X			return (-1);
X	}
X
X	return (0);
X}
X
Xstatic void macfw_flush(void)
X{
X	struct macfw_in_tree old_macfw_in_q;
X	struct macfw_entry *e;
X
X	sx_xlock(&macfw_sxlock);
X	old_macfw_in_q = macfw_in_q;
X	RB_INIT(&macfw_in_q);
X	RB_INIT(&macfw_ether_q);
X	macfw_ticket++;
X	sx_xunlock(&macfw_sxlock);
X
X	while ((e = RB_MIN(macfw_in_tree, &old_macfw_in_q)) != NULL) {
X		RB_REMOVE(macfw_in_tree, &old_macfw_in_q, e);
X		uma_zfree(macfw_entry_zone, e);
X	}
X}
X
Xstatic int macfw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
X{
X	struct macfwioc_rule *rule;
X	struct macfw_entry *e;
X	int err = 0;
X
X	if (!(flags & FWRITE)) {
X		switch(cmd) {
X		case MACFWIOCGETRULE:
X			break;
X		default:
X			return (EACCES);
X		}
X	}
X
X	rule = (struct macfwioc_rule*) addr;
X
X	switch(cmd) {
X	case MACFWIOCFLUSH: 
X		macfw_flush();
X		break;
X	case MACFWIOCZERO: 
X		atomic_store_rel_int(&macfw_stat_unknown, 0);
X		sx_slock(&macfw_sxlock);
X		RB_FOREACH(e, macfw_in_tree, &macfw_in_q) {
X			atomic_store_rel_int(&e->macfwe_stat_pass, 0);
X			atomic_store_rel_int(&e->macfwe_stat_spoof_ip, 0);
X			atomic_store_rel_int(&e->macfwe_stat_spoof_mac, 0);
X		}
X		sx_sunlock(&macfw_sxlock);
X		break;
X	case MACFWIOCADDRULE:
X		e = uma_zalloc(macfw_entry_zone, M_WAITOK | M_ZERO);
X		e->macfwe_in = rule->mr_in;
X		e->macfwe_ether = rule->mr_ether;
X		
X		sx_xlock(&macfw_sxlock);
X		if (RB_INSERT(macfw_in_tree, &macfw_in_q, e) != NULL) {
X			err = EEXIST;
X#ifdef MACFW_DEBUG
X			log(LOG_DEBUG, MACFW_NAME ": MACFWIOCADDRULE: IP exist: %s\n",
X					inet_ntoa(rule->mr_in));
X#endif
X		} else if (RB_INSERT(macfw_ether_tree, &macfw_ether_q, e) != NULL){
X			RB_REMOVE(macfw_in_tree, &macfw_in_q, e);
X			err = EEXIST;
X#ifdef MACFW_DEBUG
X			log(LOG_DEBUG, MACFW_NAME ": MACFWIOCADDRULE: MAC exist: %*D\n",
X					ETHER_ADDR_LEN, (u_char *)(rule->mr_ether.octet), ":");
X#endif
X		} else {
X			macfw_ticket++;
X		}
X		sx_xunlock(&macfw_sxlock);
X
X		if (err != 0) {
X#ifdef MACFW_DEBUG
X			log(LOG_DEBUG, MACFW_NAME ": MACFWIOCADDRULE: ticket = %d, err = %d, %s <-> %*D\n",
X					rule->mr_ticket, 
X					err,
X					inet_ntoa(rule->mr_in), 
X					ETHER_ADDR_LEN, (u_char *)(rule->mr_ether.octet), ":");
X#endif
X			uma_zfree(macfw_entry_zone, e);
X		} else if (macfw_log) {
X			log(LOG_INFO, MACFW_NAME ": rule: %s <-> %*D\n",
X					inet_ntoa(rule->mr_in), 
X					ETHER_ADDR_LEN, (u_char *)(rule->mr_ether.octet), ":");
X		}
X		break;
X	case MACFWIOCGETRULE:
X		sx_slock(&macfw_sxlock);
X
X		if (rule->mr_ticket == 0) {
X			e = RB_MIN(macfw_in_tree, &macfw_in_q);
X		} else if (rule->mr_ticket == macfw_ticket) {
X			struct macfw_entry e_key;
X
X			bzero(&e_key, sizeof(struct macfw_entry));
X			e_key.macfwe_in = rule->mr_in;
X			e_key.macfwe_ether = rule->mr_ether;
X			e = RB_FIND(macfw_in_tree, &macfw_in_q, &e_key);
X			if (e != NULL)
X				e = RB_NEXT(macfw_in_tree, &macfw_in_q, e);
X		} else {
X			e = NULL;
X			err = EINVAL;
X		}
X
X		if (e != NULL) {
X			rule->mr_ticket = macfw_ticket;
X			rule->mr_in = e->macfwe_in;
X			rule->mr_ether = e->macfwe_ether;
X			rule->mr_stat_pass = atomic_load_acq_int(&e->macfwe_stat_pass);
X			rule->mr_stat_spoof_ip = atomic_load_acq_int(&e->macfwe_stat_spoof_ip);
X			rule->mr_stat_spoof_mac = atomic_load_acq_int(&e->macfwe_stat_spoof_mac);
X		} else {
X			bzero(rule, sizeof(struct macfwioc_rule));
X			err = ENOENT;
X		}
X		sx_sunlock(&macfw_sxlock);
X#ifdef MACFW_DEBUG
X		log(LOG_DEBUG, MACFW_NAME ": MACFWIOCGETRULE: ticket = %d, err = %d, %s <-> %*D\n",
X				rule->mr_ticket, 
X				err,
X				inet_ntoa(rule->mr_in), 
X				ETHER_ADDR_LEN, (u_char *)(rule->mr_ether.octet), ":");
X#endif
X		break;
X	default:
X		return (ENODEV);
X	}
X
X	return (err);
X}
X
Xstatic int macfw_in(void *arg, struct mbuf **m, struct ifnet *ifp,
X		int dir, struct inpcb *inp)
X{
X	struct macfw_entry e, *r;
X	union {
X		struct in_addr macfwe_in;
X		struct ether_addr macfwe_ether;
X	} e_spoof;
X	struct m_tag *mtag_ether_shost;
X	struct ip *ip;
X	enum { MACFW_PASS, MACFW_SPOOF_IP, MACFW_SPOOF_MAC } err = MACFW_PASS;
X
X	if (macfw_enable == 0)
X		return (0);
X
X	mtag_ether_shost = m_tag_locate(*m, MTAG_ETHER, MTAG_ETHER_SHOST, NULL);
X	if (mtag_ether_shost == NULL)
X		return (0);
X	e.macfwe_ether = *(struct ether_addr*)(mtag_ether_shost + 1);
X	m_tag_delete(*m, mtag_ether_shost);
X
X	ip = mtod(*m, struct ip *);
X	if (ip->ip_v != 4)
X		return (0);
X	e.macfwe_in = ip->ip_src;
X	
X	sx_slock(&macfw_sxlock);
X	r = RB_FIND(macfw_in_tree, &macfw_in_q, &e);
X	if (r == NULL) {
X		r = RB_FIND(macfw_ether_tree, &macfw_ether_q, &e);
X		if (r != NULL) {
X			err = MACFW_SPOOF_IP;
X			e_spoof.macfwe_in = r->macfwe_in;
X			atomic_add_int(&r->macfwe_stat_spoof_ip, 1);
X		} else {
X			atomic_add_int(&macfw_stat_unknown, 1);
X		}
X	} else {
X		if (macfwe_ether_cmp(r, &e) != 0) {
X			err = MACFW_SPOOF_MAC;
X			e_spoof.macfwe_ether = r->macfwe_ether;
X			atomic_add_int(&r->macfwe_stat_spoof_mac, 1);
X		} else {
X			atomic_add_int(&r->macfwe_stat_pass, 1);
X		}
X	}
X	sx_sunlock(&macfw_sxlock);
X
X	if (err == MACFW_PASS)
X		return (0);
X
X	if (macfw_log) {
X		switch(err) {
X		case MACFW_PASS:
X			/* make gcc happy */
X			break;
X		case MACFW_SPOOF_IP:
X#define __INET_NTOA__PRINTF(a) ((unsigned char *)&(a))[0] & 0xff, \
X			((unsigned char *)&(a))[1] & 0xff, \
X			((unsigned char *)&(a))[2] & 0xff, \
X			((unsigned char *)&(a))[3] & 0xff
X			log(LOG_ERR, MACFW_NAME ": %*D changed IP: "
X					"%d.%d.%d.%d -> %d.%d.%d.%d on %s\n", 
X					ETHER_ADDR_LEN, (u_char *)(e.macfwe_ether.octet), ":", 
X					__INET_NTOA__PRINTF(e_spoof.macfwe_in),
X					__INET_NTOA__PRINTF(e.macfwe_in),
X					ifp->if_xname);
X#undef __INET_NTOA__PRINTF
X			break;
X		case MACFW_SPOOF_MAC:
X			log(LOG_ERR, MACFW_NAME ": %s changed MAC: "
X					"%*D -> %*D on %s\n", 
X					inet_ntoa(e.macfwe_in), 
X					ETHER_ADDR_LEN, (u_char *)(e_spoof.macfwe_ether.octet), ":", 
X					ETHER_ADDR_LEN, (u_char *)(e.macfwe_ether.octet), ":", 
X					ifp->if_xname);
X			break;
X		}
X	}
X
X	m_freem(*m);
X	*m = NULL;
X	return (EACCES);
X}
X
Xstatic int macfw_add_pfil_hook(void)
X{
X	struct pfil_head *pfil_h;
X
X	if (macfw_pfil_hooked != 0)
X		return (EEXIST);
X
X	pfil_h = pfil_head_get(PFIL_TYPE_AF, AF_INET);
X	if (pfil_h == NULL)
X		return (ESRCH);
X	pfil_add_hook(macfw_in, NULL, PFIL_IN | PFIL_WAITOK, pfil_h);
X	
X	macfw_pfil_hooked = 1;
X	return (0);
X}
X
Xstatic int macfw_remove_pfil_hook(void)
X{
X	struct pfil_head *pfil_h;
X
X	if (macfw_pfil_hooked == 0)
X		return (ESRCH);
X
X	pfil_h = pfil_head_get(PFIL_TYPE_AF, AF_INET);
X	if (pfil_h == NULL)
X		return (ESRCH);
X	pfil_remove_hook(macfw_in, NULL, PFIL_IN | PFIL_WAITOK, pfil_h);
X	
X	macfw_pfil_hooked = 0;
X	return (0);
X}
X
X
Xstatic int macfw_modevent(module_t mod, int type, void *unused)
X{
X	int err = 0;
X
X	switch (type) {
X	case MOD_LOAD:
X		RB_INIT(&macfw_in_q);
X		RB_INIT(&macfw_ether_q);
X		sx_init(&macfw_sxlock, "arp-antispoof sx lock");
X		macfw_entry_zone = uma_zcreate("macfw entry", 
X				sizeof(struct macfw_entry),  NULL, NULL, NULL, NULL,
X				UMA_ALIGN_PTR, 0);
X		macfw_dev = make_dev(&macfw_devsw, 0, UID_ROOT, GID_WHEEL, 
X				S_IRUSR | S_IWUSR | S_IRGRP, MACFW_NAME);
X		err = macfw_add_pfil_hook();
X#ifdef MACFW_DEBUG
X		macfw_log = 1;
X		log(LOG_DEBUG, MACFW_NAME " loaded\n");
X#endif
X		break;
X	case MOD_UNLOAD:
X		err = macfw_remove_pfil_hook();
X		destroy_dev(macfw_dev);
X		macfw_flush();
X		sx_destroy(&macfw_sxlock);
X		uma_zdestroy(macfw_entry_zone);
X#ifdef MACFW_DEBUG
X		log(LOG_DEBUG, MACFW_NAME " unloaded\n");
X#endif
X		break;
X	default:
X		return EOPNOTSUPP;
X		break;
X	}
X
X	return (err);
X}
X
X
Xstatic moduledata_t macfw_mod = {
X	MACFW_NAME,
X	macfw_modevent,
X	0
X};
X
XDECLARE_MODULE(macfw, macfw_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY);
XMODULE_VERSION(macfw, 1);
X
END-of-macfw/module/macfw.c
echo x - macfw/module/macfwvar.h
sed 's/^X//' >macfw/module/macfwvar.h << 'END-of-macfw/module/macfwvar.h'
X/*-
X * Copyright (c) 2006 Gleb Kurtsov 
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X *
X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X *
X */
X
X#ifndef __MACFWVAR_H
X#define __MACFWVAR_H
X
X#include <sys/param.h>
X#include <sys/ioccom.h>
X#include <net/ethernet.h>
X#include <netinet/in.h>
X
Xstruct macfwioc_rule {
X	int mr_ticket;
X	struct ether_addr mr_ether;
X	struct in_addr mr_in;
X	unsigned int mr_stat_pass;
X	unsigned int mr_stat_spoof_ip;
X	unsigned int mr_stat_spoof_mac;
X};
X
X#define MACFWIOCFLUSH		_IO  ('Z',  1)
X#define MACFWIOCADDRULE		_IOW ('Z',  2, struct macfwioc_rule)
X#define MACFWIOCGETRULE		_IOWR('Z',  3, struct macfwioc_rule)
X#define MACFWIOCZERO		_IO  ('Z',  4)
X
X
X#endif
X
END-of-macfw/module/macfwvar.h
echo x - macfw/module/patch-sys-macfw
sed 's/^X//' >macfw/module/patch-sys-macfw << 'END-of-macfw/module/patch-sys-macfw'
XIndex: net/ethernet.h
X===================================================================
XRCS file: /pub/mirror/FreeBSD-CVS/src/sys/net/ethernet.h,v
Xretrieving revision 1.24
Xdiff -u -r1.24 ethernet.h
X--- net/ethernet.h	5 Oct 2004 19:28:52 -0000	1.24
X+++ net/ethernet.h	21 Jan 2006 16:36:26 -0000
X@@ -346,6 +346,9 @@
X 
X #ifdef _KERNEL
X 
X+#define MTAG_ETHER		1080579719
X+#define MTAG_ETHER_SHOST	0
X+
X struct ifnet;
X struct mbuf;
X struct rtentry;
XIndex: net/if_ethersubr.c
X===================================================================
XRCS file: /pub/mirror/FreeBSD-CVS/src/sys/net/if_ethersubr.c,v
Xretrieving revision 1.212
Xdiff -u -r1.212 if_ethersubr.c
X--- net/if_ethersubr.c	18 Jan 2006 14:24:39 -0000	1.212
X+++ net/if_ethersubr.c	21 Jan 2006 16:34:46 -0000
X@@ -726,6 +726,18 @@
X 		return;
X 	}
X 
X+#ifdef INET
X+	if (ether_type == ETHERTYPE_IP) {
X+		struct m_tag *mtag_shost;
X+
X+		mtag_shost = m_tag_alloc(MTAG_ETHER, MTAG_ETHER_SHOST, ETHER_ADDR_LEN, M_NOWAIT);
X+		if (mtag_shost != NULL) {
X+			memcpy(mtag_shost + 1, eh->ether_shost, ETHER_ADDR_LEN);
X+			m_tag_prepend(m, mtag_shost);
X+		}
X+	}
X+#endif
X+
X 	/* Strip off Ethernet header. */
X 	m_adj(m, ETHER_HDR_LEN);
X 
END-of-macfw/module/patch-sys-macfw
exit


--BXVAT5kNtrzKuDFl--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20061113214309.GA1366>