{
AFX Lite TCP Firewall by Aphex
http://www.iamaphex.cjb.net
[email protected]
Usage: afxfw.exe
1<port> <port> <port>...
2
3Example: afxfw.exe 25 80 1433 6667
4
5This firewall is the simplest of it's kind. It is a packet
6filtering firewall that monitors SYN packets. When a SYN
7packet is sent to an unauthorized TCP port a RST packet
8is sent to same port, immediately tearing down the
9connection.
10
11The rules apply to both local and remote connections.
12}
13
14program Project1;
15
16{$APPTYPE CONSOLE}
17
18uses
19Windows,
20Winsock2;
21
22type
23TIPHEADER = record
24ip_verlen: byte;
25ip_tos: byte;
26ip_len: word;
27ip_id: word;
28ip_offset: word;
29ip_ttl: byte;
30ip_protocol: byte;
31ip_checksum: word;
32ip_saddr: longword;
33ip_daddr: longword;
34end;
35
36TTCPHEADER = record
37th_sport: word;
38th_dport: word;
39th_seq: longword;
40th_ack: longword;
41th_len: byte;
42th_flags: byte;
43th_win: word;
44th_checksum: word;
45th_upr: word;
46end;
47
48TPACKET = record
49d_ip: TIPHEADER;
50d_tcp: TTCPHEADER;
51end;
52
53TPACKETARRAY = array [0..sizeof(TPACKET)-1] of char;
54
55var
56WSAData: TWSAData;
57ArgLoop: integer;
58Ports: array [0..31] of word;
59
60const
61IOC_RCVALL: cardinal = IOC_IN or $18000000 or 1;
62
63function IntToStr(I: integer):string;
64var
65v1: string;
66begin
67Str(I, v1);
68Result := v1;
69end;
70
71function StrToInt(const S: string): integer;
72var
73v1: Integer;
74begin
75Val(S, Result, v1);
76end;
77
78function CheckSum(var Buffer; Size: integer): word;
79type
80TWordArray = array[0..1] of word;
81var
82lSumm: LongWord;
83iLoop: integer;
84begin
85lSumm := 0;
86iLoop := 0;
87while Size > 1 do
88begin
89lSumm := lSumm + TWordArray(Buffer)[iLoop];
90inc(iLoop);
91Size := Size - SizeOf(word);
92end;
93if Size = 1 then lSumm := lSumm + Byte(TWordArray(Buffer)[iLoop]);
94lSumm := (lSumm shr 16) + (lSumm and $FFFF);
95lSumm := lSumm + (lSumm shr 16);
96Result := word(not lSumm);
97end;
98
99procedure RSTHeader(FromIP: dword; FromPort: word; ToIP: dword; ToPort: word; var Buffer: TPACKETARRAY; var Socket: TSockAddr; var Size: dword; Seq: dword);
100var
101ipHdr: TIPHEADER;
102tcpHdr: TTCPHEADER;
103TcpHeaderLen: word;
104ChecksumSize: word;
105DataPointer: ^byte;
106
107procedure IncPtr(Value: integer);
108begin
109DataPointer := pointer(integer(DataPointer) + Value);
110end;
111
112begin
113Size := sizeof(ipHdr) + sizeof(tcpHdr);
114ipHdr.ip_verlen := ((4 shl 4) or sizeof(ipHdr) div sizeof(longword));
115ipHdr.ip_tos := 0;
116ipHdr.ip_len := htons(Size);
117ipHdr.ip_id := 0;
118ipHdr.ip_offset := 0;
119ipHdr.ip_ttl := 128;
120ipHdr.ip_protocol := 6;
121ipHdr.ip_checksum := 0;
122ipHdr.ip_saddr := FromIP;
123ipHdr.ip_daddr := ToIP;
124ChecksumSize := 0;
125tcpHdr.th_sport := FromPort;
126tcpHdr.th_dport := ToPort;
127tcpHdr.th_seq := htonl(Seq);
128tcpHdr.th_ack := 0;
129tcpHdr.th_len := 80;
130tcpHdr.th_flags := 20;
131tcpHdr.th_win := htons(65535);
132tcpHdr.th_checksum := 0;
133tcpHdr.th_upr := 0;
134DataPointer := @Buffer[0];
135FillChar(Buffer, SizeOf(Buffer), 0);
136Move(ipHdr.ip_saddr, DataPointer^, SizeOf(ipHdr.ip_saddr));
137IncPtr(SizeOf(ipHdr.ip_saddr));
138ChecksumSize := ChecksumSize + sizeof(ipHdr.ip_saddr);
139Move(ipHdr.ip_daddr, DataPointer^, sizeof(ipHdr.ip_daddr));
140IncPtr(SizeOf(ipHdr.ip_daddr));
141ChecksumSize := ChecksumSize + sizeof(ipHdr.ip_daddr);
142IncPtr(1);
143Inc(ChecksumSize);
144Move(ipHdr.ip_protocol, DataPointer^, sizeof(ipHdr.ip_protocol));
145IncPtr(sizeof(ipHdr.ip_protocol));
146ChecksumSize := ChecksumSize + sizeof(ipHdr.ip_protocol);
147TcpHeaderLen := htons(sizeof(tcpHdr));
148Move(TcpHeaderLen, DataPointer^, sizeof(TcpHeaderLen));
149IncPtr(sizeof(TcpHeaderLen));
150ChecksumSize := ChecksumSize + sizeof(TcpHeaderLen);
151Move(tcpHdr, DataPointer^, sizeof(tcpHdr));
152IncPtr(sizeof(tcpHdr));
153ChecksumSize := ChecksumSize + sizeof(tcpHdr);
154tcpHdr.th_checksum := CheckSum(Buffer, ChecksumSize);
155FillChar(Buffer, sizeof(Buffer), 0);
156DataPointer := @Buffer[0];
157Move(ipHdr, DataPointer^, sizeof(ipHdr));
158IncPtr(sizeof(ipHdr));
159Move(tcpHdr, DataPointer^, sizeof(tcpHdr));
160Socket.sin_family := AF_INET;
161Socket.sin_port := 0;
162Socket.sin_addr.S_addr := ToIP;
163end;
164
165procedure Main;
166var
167rSocket, sSocket: TSocket;
168Data, RST: TPACKET;
169BytesReceived, BytesSent: dword;
170Control: dword;
171SockAddrIn: TSockAddrIn;
172ArgLoop, Option: integer;
173
174function GetInAddr: TInAddr;
175var
176Host: array[0..128] of char;
177HostEnt: PHostEnt;
178begin
179GetHostName(@Host, 128);
180HostEnt := GetHostByName(@Host);
181Result := PInAddr(HostEnt^.h_addr_list^)^
182end;
183
184begin
185if WSAStartup(WINSOCK_VERSION, WSAData) = 0 then
186begin
187rSocket := Socket(PF_INET, SOCK_RAW, 0);
188sSocket := Socket(PF_INET, SOCK_RAW, 0);
189if ((rSocket <> INVALID_SOCKET) and (sSocket <> INVALID_SOCKET)) then
190begin
191SetSockOpt(sSocket, 0, 2, @Option, SizeOf(Option));
192SockAddrIn.sin_family := AF_INET;
193SockAddrIn.sin_addr := GetInAddr;
194SockAddrIn.sin_port := htons(0);
195bind(rSocket, @SockAddrIn, SizeOf(SockAddrIn));
196WSAIoctl(rSocket, IOC_RCVALL, @Control, SizeOf(Control), nil, 0, @BytesReceived, nil, nil);
197while rSocket <> INVALID_SOCKET do
198begin
199BytesReceived := recv(rSocket, Data, SizeOf(Data), 0);
200if BytesReceived > 0 then
201begin
202if Data.d_ip.ip_protocol = 6 then
203begin
204if (Data.d_tcp.th_flags and 2) <> 0 then
205begin
206for ArgLoop := 0 to 31 do
207begin
208if Ports[ArgLoop] = htons(Data.d_tcp.th_dport) then
209begin
210RSTHeader(Data.d_ip.ip_saddr, Data.d_tcp.th_sport, Data.d_ip.ip_daddr, Data.d_tcp.th_dport, TPACKETARRAY(RST), SockAddrIn, BytesSent, ntohl(Data.d_tcp.th_seq) + 1);
211SendTo(sSocket, RST, BytesSent, 0, SockAddrIn, sizeof(SockAddrIn));
212Break;
213end;
214end;
215end;
216end;
217end
218else
219begin
220Break;
221end;
222end;
223end;
224end;
225WSACleanup;
226end;
227
228begin
229WriteLn('AFX Lite TCP Firewall by Aphex');
230WriteLn('http://www.iamaphex.cjb.net');
231WriteLn(' [email protected] ');
232if ParamStr(1) = '' then
233begin
234WriteLn('');
235WriteLn('Usage: afxfw.exe <port> <port> <port>...');
236Halt(0);
237end;
238for ArgLoop := 1 to 32 do
239begin
240if ParamStr(ArgLoop) <> '' then
241begin
242Ports[ArgLoop - 1] := StrToInt(ParamStr(ArgLoop));
243end;
244end;
245Main;
246end.</port></port></port></port></port></port>