Rev 1530 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1530 | Rev 1541 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;; IPv4.INC ;; |
6 | ;; IPv4.INC ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; Part of the tcp/ip network stack for KolibriOS ;; |
8 | ;; Part of the tcp/ip network stack for KolibriOS ;; |
9 | ;; ;; |
9 | ;; ;; |
10 | ;; Based on the work of [Johnny_B] and [smb] ;; |
10 | ;; Based on the work of [Johnny_B] and [smb] ;; |
11 | ;; ;; |
11 | ;; ;; |
12 | ;; Written by hidnplayr@kolibrios.org ;; |
12 | ;; Written by hidnplayr@kolibrios.org ;; |
13 | ;; ;; |
13 | ;; ;; |
14 | ;; GNU GENERAL PUBLIC LICENSE ;; |
14 | ;; GNU GENERAL PUBLIC LICENSE ;; |
15 | ;; Version 2, June 1991 ;; |
15 | ;; Version 2, June 1991 ;; |
16 | ;; ;; |
16 | ;; ;; |
17 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
17 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
18 | 18 | ||
19 | $Revision: 1530 $ |
19 | $Revision: 1541 $ |
20 | 20 | ||
21 | MAX_FRAGMENTS equ 64 |
21 | MAX_FRAGMENTS equ 64 |
22 | MAX_IP equ MAX_NET_DEVICES |
22 | MAX_IP equ MAX_NET_DEVICES |
23 | IP_MAX_INTERFACES equ MAX_IP |
23 | IP_MAX_INTERFACES equ MAX_IP |
24 | 24 | ||
25 | struct IPv4_Packet |
25 | struct IPv4_Packet |
26 | .VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] |
26 | .VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] |
27 | .TypeOfService db ? ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0] |
27 | .TypeOfService db ? ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0] |
28 | .TotalLength dw ? |
28 | .TotalLength dw ? |
29 | .Identification dw ? |
29 | .Identification dw ? |
30 | .FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15] |
30 | .FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15] |
31 | .TimeToLive db ? ; |
31 | .TimeToLive db ? ; |
32 | .Protocol db ? |
32 | .Protocol db ? |
33 | .HeaderChecksum dw ? |
33 | .HeaderChecksum dw ? |
34 | .SourceAddress dd ? |
34 | .SourceAddress dd ? |
35 | .DestinationAddress dd ? |
35 | .DestinationAddress dd ? |
36 | .DataOrOptional: |
36 | .DataOrOptional: |
37 | ends |
37 | ends |
38 | 38 | ||
39 | struct FRAGMENT_slot |
39 | struct FRAGMENT_slot |
40 | .ttl dw ? ; Time to live for this entry, 0 for empty slot's |
40 | .ttl dw ? ; Time to live for this entry, 0 for empty slot's |
41 | .id dw ? ; Identification field from IP header |
41 | .id dw ? ; Identification field from IP header |
42 | .SrcIP dd ? ; .. from IP header |
42 | .SrcIP dd ? ; .. from IP header |
43 | .DstIP dd ? ; .. from IP header |
43 | .DstIP dd ? ; .. from IP header |
44 | .ptr dd ? ; Pointer to first packet |
44 | .ptr dd ? ; Pointer to first packet |
45 | .size: |
45 | .size: |
46 | ends |
46 | ends |
47 | 47 | ||
48 | struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets |
48 | struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets |
49 | .PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet) |
49 | .PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet) |
50 | .NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet) |
50 | .NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet) |
51 | .Owner dd ? ; Pointer to structure of driver |
51 | .Owner dd ? ; Pointer to structure of driver |
52 | rb 2 ; to match ethernet header size ; TODO: fix this hack |
52 | rb 2 ; to match ethernet header size ; TODO: fix this hack |
53 | .Data: ; Ip header begins here (we will need the IP header to re-construct the complete packet) |
53 | .Data: ; Ip header begins here (we will need the IP header to re-construct the complete packet) |
54 | ends |
54 | ends |
55 | 55 | ||
56 | 56 | ||
57 | align 4 |
57 | align 4 |
58 | uglobal |
58 | uglobal |
59 | 59 | ||
60 | IP_LIST rd MAX_IP |
60 | IP_LIST rd MAX_IP |
61 | SUBNET_LIST rd MAX_IP |
61 | SUBNET_LIST rd MAX_IP |
62 | DNS_LIST rd MAX_IP |
62 | DNS_LIST rd MAX_IP |
63 | GATEWAY_LIST rd MAX_IP |
63 | GATEWAY_LIST rd MAX_IP |
64 | 64 | ||
65 | IP_PACKETS_TX rd MAX_IP |
65 | IP_PACKETS_TX rd MAX_IP |
66 | IP_PACKETS_RX rd MAX_IP |
66 | IP_PACKETS_RX rd MAX_IP |
67 | 67 | ||
68 | FRAGMENT_LIST rb MAX_FRAGMENTS*FRAGMENT_slot.size |
68 | FRAGMENT_LIST rb MAX_FRAGMENTS*FRAGMENT_slot.size |
69 | endg |
69 | endg |
70 | 70 | ||
71 | 71 | ||
72 | ;----------------------------------------------------------------- |
72 | ;----------------------------------------------------------------- |
73 | ; |
73 | ; |
74 | ; IPv4_init |
74 | ; IPv4_init |
75 | ; |
75 | ; |
76 | ; This function resets all IP variables |
76 | ; This function resets all IP variables |
77 | ; |
77 | ; |
78 | ;----------------------------------------------------------------- |
78 | ;----------------------------------------------------------------- |
79 | macro IPv4_init { |
79 | macro IPv4_init { |
80 | 80 | ||
81 | xor eax, eax |
81 | xor eax, eax |
82 | mov edi, IP_LIST |
82 | mov edi, IP_LIST |
83 | mov ecx, 4*MAX_IP |
83 | mov ecx, 4*MAX_IP |
84 | rep stosd |
84 | rep stosd |
85 | 85 | ||
86 | mov edi, FRAGMENT_LIST |
86 | mov edi, FRAGMENT_LIST |
87 | mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP |
87 | mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP |
88 | rep stosd |
88 | rep stosd |
89 | 89 | ||
90 | } |
90 | } |
91 | 91 | ||
92 | 92 | ||
93 | ;----------------------------------------------------------------- |
93 | ;----------------------------------------------------------------- |
94 | ; |
94 | ; |
95 | ; Decrease TimeToLive of all fragment slots |
95 | ; Decrease TimeToLive of all fragment slots |
96 | ; |
96 | ; |
97 | ;----------------------------------------------------------------- |
97 | ;----------------------------------------------------------------- |
98 | macro IPv4_decrease_fragment_ttls { |
98 | macro IPv4_decrease_fragment_ttls { |
99 | 99 | ||
100 | local .loop |
100 | local .loop |
101 | 101 | ||
102 | mov esi, FRAGMENT_LIST |
102 | mov esi, FRAGMENT_LIST |
103 | mov ecx, MAX_FRAGMENTS |
103 | mov ecx, MAX_FRAGMENTS |
104 | .loop: |
104 | .loop: |
105 | cmp [esi + FRAGMENT_slot.ttl], 0 |
105 | cmp [esi + FRAGMENT_slot.ttl], 0 |
106 | je .try_next |
106 | je .try_next |
107 | dec [esi + FRAGMENT_slot.ttl] |
107 | dec [esi + FRAGMENT_slot.ttl] |
108 | jnz .try_next |
108 | jnz .try_next |
109 | DEBUGF 1,"Fragment slot timed-out!\n" |
109 | DEBUGF 1,"Fragment slot timed-out!\n" |
110 | ;;; TODO: clear all entry's of timed-out slot |
110 | ;;; TODO: clear all entry's of timed-out slot |
111 | .try_next: |
111 | .try_next: |
112 | add esi, 4 |
112 | add esi, 4 |
113 | loop .loop |
113 | loop .loop |
114 | } |
114 | } |
115 | 115 | ||
116 | 116 | ||
117 | 117 | ||
118 | macro IPv4_checksum ptr { |
118 | macro IPv4_checksum ptr { |
119 | 119 | ||
120 | ; This is the fast procedure to create or check a IP header without options |
120 | ; This is the fast procedure to create or check a IP header without options |
121 | ; To create a new checksum, the checksum field must be set to 0 before computation |
121 | ; To create a new checksum, the checksum field must be set to 0 before computation |
122 | ; To check an existing checksum, leave the checksum as is, and it will be 0 after this procedure, if it was correct |
122 | ; To check an existing checksum, leave the checksum as is, and it will be 0 after this procedure, if it was correct |
123 | 123 | ||
124 | push ebx |
124 | push ebx |
125 | xor ebx, ebx |
125 | xor ebx, ebx |
126 | add bl, [ptr+1] |
126 | add bl, [ptr+1] |
127 | adc bh, [ptr+0] |
127 | adc bh, [ptr+0] |
128 | 128 | ||
129 | adc bl, [ptr+3] |
129 | adc bl, [ptr+3] |
130 | adc bh, [ptr+2] |
130 | adc bh, [ptr+2] |
131 | 131 | ||
132 | adc bl, [ptr+5] |
132 | adc bl, [ptr+5] |
133 | adc bh, [ptr+4] |
133 | adc bh, [ptr+4] |
134 | 134 | ||
135 | adc bl, [ptr+7] |
135 | adc bl, [ptr+7] |
136 | adc bh, [ptr+6] |
136 | adc bh, [ptr+6] |
137 | 137 | ||
138 | adc bl, [ptr+9] |
138 | adc bl, [ptr+9] |
139 | adc bh, [ptr+8] |
139 | adc bh, [ptr+8] |
140 | 140 | ||
141 | ; we skip 11th and 12th byte, they are the checksum bytes and should be 0 for re-calculation |
141 | ; we skip 11th and 12th byte, they are the checksum bytes and should be 0 for re-calculation |
142 | 142 | ||
143 | adc bl, [ptr+13] |
143 | adc bl, [ptr+13] |
144 | adc bh, [ptr+12] |
144 | adc bh, [ptr+12] |
145 | 145 | ||
146 | adc bl, [ptr+15] |
146 | adc bl, [ptr+15] |
147 | adc bh, [ptr+14] |
147 | adc bh, [ptr+14] |
148 | 148 | ||
149 | adc bl, [ptr+17] |
149 | adc bl, [ptr+17] |
150 | adc bh, [ptr+16] |
150 | adc bh, [ptr+16] |
151 | 151 | ||
152 | adc bl, [ptr+19] |
152 | adc bl, [ptr+19] |
153 | adc bh, [ptr+18] |
153 | adc bh, [ptr+18] |
154 | 154 | ||
155 | adc ebx, 0 |
155 | adc ebx, 0 |
156 | 156 | ||
157 | push ecx |
157 | push ecx |
158 | mov ecx, ebx |
158 | mov ecx, ebx |
159 | shr ecx, 16 |
159 | shr ecx, 16 |
160 | and ebx, 0xffff |
160 | and ebx, 0xffff |
161 | add ebx, ecx |
161 | add ebx, ecx |
162 | 162 | ||
163 | mov ecx, ebx |
163 | mov ecx, ebx |
164 | shr ecx, 16 |
164 | shr ecx, 16 |
165 | add ebx, ecx |
165 | add ebx, ecx |
166 | 166 | ||
167 | not bx |
167 | not bx |
168 | jnz .not_zero |
168 | jnz .not_zero |
169 | dec bx |
169 | dec bx |
170 | .not_zero: |
170 | .not_zero: |
171 | xchg bl, bh |
171 | xchg bl, bh |
172 | pop ecx |
172 | pop ecx |
173 | 173 | ||
174 | neg word [ptr+10] ; zero will stay zero so we just get the checksum |
174 | neg word [ptr+10] ; zero will stay zero so we just get the checksum |
175 | add word [ptr+10], bx ; , else we will get (new checksum - old checksum) in the end, wich should be 0 :) |
175 | add word [ptr+10], bx ; , else we will get (new checksum - old checksum) in the end, wich should be 0 :) |
176 | pop ebx |
176 | pop ebx |
177 | 177 | ||
178 | } |
178 | } |
179 | 179 | ||
180 | 180 | ||
181 | 181 | ||
182 | ;----------------------------------------------------------------- |
182 | ;----------------------------------------------------------------- |
183 | ; |
183 | ; |
184 | ; IPv4_input: |
184 | ; IPv4_input: |
185 | ; |
185 | ; |
186 | ; Will check if IP Packet isnt damaged |
186 | ; Will check if IP Packet isnt damaged |
187 | ; and call appropriate handler. (TCP/UDP/ICMP/..) |
187 | ; and call appropriate handler. (TCP/UDP/ICMP/..) |
188 | ; |
188 | ; |
189 | ; It will also re-construct fragmented packets |
189 | ; It will also re-construct fragmented packets |
190 | ; |
190 | ; |
191 | ; IN: Pointer to buffer in [esp] |
191 | ; IN: Pointer to buffer in [esp] |
192 | ; size of buffer in [esp+4] |
192 | ; size of buffer in [esp+4] |
193 | ; pointer to device struct in ebx |
193 | ; pointer to device struct in ebx |
194 | ; pointer to IP Packet data in edx |
194 | ; pointer to IP Packet data in edx |
195 | ; OUT: / |
195 | ; OUT: / |
196 | ; |
196 | ; |
197 | ;----------------------------------------------------------------- |
197 | ;----------------------------------------------------------------- |
198 | align 4 |
198 | align 4 |
199 | IPv4_input: ; TODO: implement handler for IP options |
199 | IPv4_input: ; TODO: implement handler for IP options |
200 | ; TODO2: add code for raw sockets |
200 | ; TODO2: add code for raw sockets |
201 | 201 | ||
202 | DEBUGF 1,"IPv4_Handler, packet from: %u.%u.%u.%u ",\ |
202 | DEBUGF 1,"IPv4_Handler, packet from: %u.%u.%u.%u ",\ |
203 | [edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1 |
203 | [edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1 |
204 | DEBUGF 1,"to: %u.%u.%u.%u\n",\ |
204 | DEBUGF 1,"to: %u.%u.%u.%u\n",\ |
205 | [edx + IPv4_Packet.DestinationAddress]:1,[edx + IPv4_Packet.DestinationAddress + 1]:1,[edx + IPv4_Packet.DestinationAddress + 2]:1,[edx + IPv4_Packet.DestinationAddress + 3]:1 |
205 | [edx + IPv4_Packet.DestinationAddress]:1,[edx + IPv4_Packet.DestinationAddress + 1]:1,[edx + IPv4_Packet.DestinationAddress + 2]:1,[edx + IPv4_Packet.DestinationAddress + 3]:1 |
206 | 206 | ||
207 | ;------------------------------------------- |
207 | ;------------------------------------------- |
208 | ; Check if the packet still has time to live |
208 | ; Check if the packet still has time to live |
209 | 209 | ||
210 | cmp byte [edx + IPv4_Packet.TimeToLive], 0 |
210 | cmp byte [edx + IPv4_Packet.TimeToLive], 0 |
211 | je .dump |
211 | je .dump |
212 | 212 | ||
213 | ;-------------------------------------- |
213 | ;-------------------------------------- |
214 | ; First, check if IP packet has options |
214 | ; First, check if IP packet has options |
215 | 215 | ||
216 | movzx eax, [edx + IPv4_Packet.VersionAndIHL] |
216 | movzx eax, [edx + IPv4_Packet.VersionAndIHL] |
217 | and al , 0x0f ; get IHL(header length) |
217 | and al , 0x0f ; get IHL(header length) |
218 | cmp al , 0x05 ; IHL!= 5*4(20 bytes) |
218 | cmp al , 0x05 ; IHL!= 5*4(20 bytes) |
219 | jnz .has_options |
219 | jnz .has_options |
220 | 220 | ||
221 | ;------------------------------- |
221 | ;------------------------------- |
222 | ; Now, re-calculate the checksum |
222 | ; Now, re-calculate the checksum |
223 | 223 | ||
224 | IPv4_checksum edx |
224 | IPv4_checksum edx |
225 | jnz .dump ; if checksum isn't valid then dump packet |
225 | jnz .dump ; if checksum isn't valid then dump packet |
226 | 226 | ||
227 | DEBUGF 1,"IPv4 Checksum is correct\n" |
227 | DEBUGF 1,"IPv4 Checksum is correct\n" |
228 | 228 | ||
229 | ;----------------------------------- |
229 | ;----------------------------------- |
230 | ; Check if destination IP is correct |
230 | ; Check if destination IP is correct |
231 | 231 | ||
232 | call NET_ptr_to_num |
232 | call NET_ptr_to_num |
233 | shl edi, 2 |
233 | shl edi, 2 |
234 | 234 | ||
235 | ; check if it matches local ip |
235 | ; check if it matches local ip |
236 | 236 | ||
237 | mov eax, dword[IP_LIST+edi] |
237 | mov eax, dword[IP_LIST+edi] |
238 | cmp [edx + IPv4_Packet.DestinationAddress], eax |
238 | cmp [edx + IPv4_Packet.DestinationAddress], eax |
239 | je .ip_ok |
239 | je .ip_ok |
240 | 240 | ||
241 | ; check for broadcast |
241 | ; check for broadcast |
242 | 242 | ||
243 | mov eax, dword[SUBNET_LIST+edi] |
243 | mov eax, dword[SUBNET_LIST+edi] |
244 | not eax |
244 | not eax |
245 | or eax, dword[IP_LIST+edi] |
245 | or eax, dword[IP_LIST+edi] |
246 | cmp [edx + IPv4_Packet.DestinationAddress], eax |
246 | cmp [edx + IPv4_Packet.DestinationAddress], eax |
247 | je .ip_ok |
247 | je .ip_ok |
248 | 248 | ||
249 | ; or a special broadcast |
249 | ; or a special broadcast |
250 | 250 | ||
251 | cmp [edx + IPv4_Packet.DestinationAddress], -1 |
251 | cmp [edx + IPv4_Packet.DestinationAddress], -1 |
252 | je .ip_ok |
252 | je .ip_ok |
253 | 253 | ||
254 | ; maybe it's a multicast then |
254 | ; maybe it's a multicast then |
255 | 255 | ||
256 | mov eax, [edx + IPv4_Packet.DestinationAddress] |
256 | mov eax, [edx + IPv4_Packet.DestinationAddress] |
257 | and eax, 0xff000000 |
257 | and eax, 0xff000000 |
258 | ; cmp eax, 224 shl 24 |
258 | ; cmp eax, 224 shl 24 |
259 | ; je .ip_ok |
259 | ; je .ip_ok |
260 | 260 | ||
261 | ; or a loopback address |
261 | ; or a loopback address |
262 | 262 | ||
263 | cmp eax, 127 shl 24 |
263 | cmp eax, 127 shl 24 |
264 | je .ip_ok |
264 | je .ip_ok |
265 | 265 | ||
266 | ; or it's not meant for us.. |
266 | ; or it's not meant for us.. |
267 | 267 | ||
268 | DEBUGF 2,"Destination address does not match!\n" |
268 | DEBUGF 2,"Destination address does not match!\n" |
269 | jmp .dump |
269 | jmp .dump |
270 | 270 | ||
271 | ;------------------------ |
271 | ;------------------------ |
272 | ; Now we can update stats |
272 | ; Now we can update stats |
273 | 273 | ||
274 | .ip_ok: |
274 | .ip_ok: |
275 | inc [IP_PACKETS_RX+edi] |
275 | inc [IP_PACKETS_RX+edi] |
276 | 276 | ||
277 | ;---------------------------------- |
277 | ;---------------------------------- |
278 | ; Check if the packet is fragmented |
278 | ; Check if the packet is fragmented |
279 | 279 | ||
280 | test [edx + IPv4_Packet.FlagsAndFragmentOffset], 1 shl 5 ; Is 'more fragments' flag set ? |
280 | test [edx + IPv4_Packet.FlagsAndFragmentOffset], 1 shl 5 ; Is 'more fragments' flag set ? |
281 | jnz .has_fragments ; If so, we definately have a fragmented packet |
281 | jnz .has_fragments ; If so, we definately have a fragmented packet |
282 | 282 | ||
283 | test [edx + IPv4_Packet.FlagsAndFragmentOffset], 0xff1f ; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets |
283 | test [edx + IPv4_Packet.FlagsAndFragmentOffset], 0xff1f ; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets |
284 | jnz .is_last_fragment |
284 | jnz .is_last_fragment |
285 | 285 | ||
286 | ;------------------------------------------------------------------- |
286 | ;------------------------------------------------------------------- |
287 | ; No, it's just a regular IP packet, pass it to the higher protocols |
287 | ; No, it's just a regular IP packet, pass it to the higher protocols |
288 | 288 | ||
289 | .handle_it: ; We reach here if packet hasnt been fragmented, or when it already has been re-constructed |
289 | .handle_it: ; We reach here if packet hasnt been fragmented, or when it already has been re-constructed |
290 | movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
290 | movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
291 | and eax, 0x0000000f ; |
291 | and eax, 0x0000000f ; |
292 | shl eax, 2 ; |
292 | shl eax, 2 ; |
293 | movzx ecx, word [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet |
293 | movzx ecx, word [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet |
294 | xchg cl , ch ; |
294 | xchg cl , ch ; |
295 | sub ecx, eax ; |
295 | sub ecx, eax ; |
296 | 296 | ||
297 | add eax, edx |
297 | add eax, edx |
298 | push eax |
298 | push eax |
299 | 299 | ||
300 | mov esi, [edx + IPv4_Packet.SourceAddress] ; These values might be of interest to the higher protocols |
300 | mov esi, [edx + IPv4_Packet.SourceAddress] ; These values might be of interest to the higher protocols |
301 | mov edi, [edx + IPv4_Packet.DestinationAddress] ; |
301 | mov edi, [edx + IPv4_Packet.DestinationAddress] ; |
302 | mov al , [edx + IPv4_Packet.Protocol] |
302 | mov al , [edx + IPv4_Packet.Protocol] |
303 | pop edx ; Offset to data (tcp/udp/icmp/.. Packet) |
303 | pop edx ; Offset to data (tcp/udp/icmp/.. Packet) |
304 | 304 | ||
305 | cmp al , IP_PROTO_TCP |
305 | cmp al , IP_PROTO_TCP |
306 | je TCP_input |
306 | je TCP_input |
307 | 307 | ||
308 | cmp al , IP_PROTO_UDP |
308 | cmp al , IP_PROTO_UDP |
309 | je UDP_input |
309 | je UDP_input |
310 | 310 | ||
311 | cmp al , IP_PROTO_ICMP |
311 | cmp al , IP_PROTO_ICMP |
312 | je ICMP_input |
312 | je ICMP_input |
313 | 313 | ||
314 | DEBUGF 2,"unknown Internet protocol: %u\n", al |
314 | DEBUGF 2,"unknown Internet protocol: %u\n", al |
315 | 315 | ||
316 | .dump: |
316 | .dump: |
317 | DEBUGF 2,"IP_Handler - dumping\n" |
317 | DEBUGF 2,"IP_Handler - dumping\n" |
318 | ; inc [dumped_rx_count] |
318 | ; inc [dumped_rx_count] |
319 | call kernel_free |
319 | call kernel_free |
320 | add esp, 4 ; pop (balance stack) |
320 | add esp, 4 ; pop (balance stack) |
321 | ret |
321 | ret |
322 | 322 | ||
323 | 323 | ||
324 | ;--------------------------- |
324 | ;--------------------------- |
325 | ; Fragmented packet handler |
325 | ; Fragmented packet handler |
326 | 326 | ||
327 | 327 | ||
328 | .has_fragments: |
328 | .has_fragments: |
329 | movzx eax, [edx + IPv4_Packet.FlagsAndFragmentOffset] |
329 | movzx eax, [edx + IPv4_Packet.FlagsAndFragmentOffset] |
330 | xchg al , ah |
330 | xchg al , ah |
331 | shl ax , 3 |
331 | shl ax , 3 |
332 | 332 | ||
333 | DEBUGF 1,"Fragmented packet, offset:%u, id:%x\n", ax, [edx + IPv4_Packet.Identification]:4 |
333 | DEBUGF 1,"Fragmented packet, offset:%u, id:%x\n", ax, [edx + IPv4_Packet.Identification]:4 |
334 | 334 | ||
335 | test ax , ax ; Is this the first packet of the fragment? |
335 | test ax , ax ; Is this the first packet of the fragment? |
336 | jz .is_first_fragment |
336 | jz .is_first_fragment |
337 | 337 | ||
338 | 338 | ||
339 | ;------------------------------------------------------- |
339 | ;------------------------------------------------------- |
340 | ; We have a fragmented IP packet, but it's not the first |
340 | ; We have a fragmented IP packet, but it's not the first |
341 | 341 | ||
342 | DEBUGF 1,"Middle fragmented packet received!\n" |
342 | DEBUGF 1,"Middle fragmented packet received!\n" |
343 | 343 | ||
344 | call IPv4_find_fragment_slot |
344 | call IPv4_find_fragment_slot |
345 | cmp esi, -1 |
345 | cmp esi, -1 |
346 | je .dump |
346 | je .dump |
347 | 347 | ||
348 | mov word [esi + FRAGMENT_slot.ttl], 15 ; Reset the ttl |
348 | mov word [esi + FRAGMENT_slot.ttl], 15 ; Reset the ttl |
349 | mov esi, [esi + FRAGMENT_slot.ptr] |
349 | mov esi, [esi + FRAGMENT_slot.ptr] |
350 | or edi, -1 |
350 | or edi, -1 |
351 | .find_last_entry: ; The following routine will try to find the last entry |
351 | .find_last_entry: ; The following routine will try to find the last entry |
352 | cmp edi, [esi + FRAGMENT_entry.PrevPtr] |
352 | cmp edi, [esi + FRAGMENT_entry.PrevPtr] |
353 | jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
353 | jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
354 | mov edi, esi |
354 | mov edi, esi |
355 | mov esi, [esi + FRAGMENT_entry.NextPtr] |
355 | mov esi, [esi + FRAGMENT_entry.NextPtr] |
356 | cmp esi, -1 |
356 | cmp esi, -1 |
357 | jne .find_last_entry |
357 | jne .find_last_entry |
358 | ; We found the last entry (pointer is now in edi) |
358 | ; We found the last entry (pointer is now in edi) |
359 | ; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure |
359 | ; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure |
360 | 360 | ||
361 | pop eax ; pointer to packet |
361 | pop eax ; pointer to packet |
362 | mov [edi + FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry |
362 | mov [edi + FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry |
363 | mov [eax + FRAGMENT_entry.NextPtr], -1 |
363 | mov [eax + FRAGMENT_entry.NextPtr], -1 |
364 | mov [eax + FRAGMENT_entry.PrevPtr], edi |
364 | mov [eax + FRAGMENT_entry.PrevPtr], edi |
365 | mov [eax + FRAGMENT_entry.Owner], ebx |
365 | mov [eax + FRAGMENT_entry.Owner], ebx |
366 | 366 | ||
367 | add esp, 4 |
367 | add esp, 4 |
368 | ret |
368 | ret |
369 | 369 | ||
370 | 370 | ||
371 | ;------------------------------------ |
371 | ;------------------------------------ |
372 | ; We have received the first fragment |
372 | ; We have received the first fragment |
373 | 373 | ||
374 | .is_first_fragment: |
374 | .is_first_fragment: |
375 | DEBUGF 1,"First fragmented packet received!\n" |
375 | DEBUGF 1,"First fragmented packet received!\n" |
376 | ; try to locate a free slot.. |
376 | ; try to locate a free slot.. |
377 | mov ecx, MAX_FRAGMENTS |
377 | mov ecx, MAX_FRAGMENTS |
378 | mov esi, FRAGMENT_LIST |
378 | mov esi, FRAGMENT_LIST |
379 | .find_free_slot: |
379 | .find_free_slot: |
380 | cmp word [esi + FRAGMENT_slot.ttl], 0 |
380 | cmp word [esi + FRAGMENT_slot.ttl], 0 |
381 | je .found_free_slot |
381 | je .found_free_slot |
382 | add esi, FRAGMENT_slot.size |
382 | add esi, FRAGMENT_slot.size |
383 | loop .find_free_slot |
383 | loop .find_free_slot |
384 | jmp .dump ; If no free slot was found, dump the packet |
384 | jmp .dump ; If no free slot was found, dump the packet |
385 | 385 | ||
386 | .found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure |
386 | .found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure |
387 | mov word [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl |
387 | mov word [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl |
388 | mov ax , word [edx + IPv4_Packet.Identification] |
388 | mov ax , word [edx + IPv4_Packet.Identification] |
389 | mov word [esi + FRAGMENT_slot.id], ax |
389 | mov word [esi + FRAGMENT_slot.id], ax |
390 | mov eax, dword [edx + IPv4_Packet.SourceAddress] |
390 | mov eax, dword [edx + IPv4_Packet.SourceAddress] |
391 | mov dword [esi + FRAGMENT_slot.SrcIP], eax |
391 | mov dword [esi + FRAGMENT_slot.SrcIP], eax |
392 | mov eax, dword [edx + IPv4_Packet.DestinationAddress] |
392 | mov eax, dword [edx + IPv4_Packet.DestinationAddress] |
393 | mov dword [esi + FRAGMENT_slot.DstIP], eax |
393 | mov dword [esi + FRAGMENT_slot.DstIP], eax |
394 | pop eax |
394 | pop eax |
395 | mov dword [esi + FRAGMENT_slot.ptr], eax |
395 | mov dword [esi + FRAGMENT_slot.ptr], eax |
396 | ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure |
396 | ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure |
397 | mov [eax + FRAGMENT_entry.NextPtr], -1 |
397 | mov [eax + FRAGMENT_entry.NextPtr], -1 |
398 | mov [eax + FRAGMENT_entry.PrevPtr], -1 |
398 | mov [eax + FRAGMENT_entry.PrevPtr], -1 |
399 | mov [eax + FRAGMENT_entry.Owner], ebx |
399 | mov [eax + FRAGMENT_entry.Owner], ebx |
400 | 400 | ||
401 | add esp, 4 ; balance stack and exit |
401 | add esp, 4 ; balance stack and exit |
402 | ret |
402 | ret |
403 | 403 | ||
404 | 404 | ||
405 | ;----------------------------------- |
405 | ;----------------------------------- |
406 | ; We have received the last fragment |
406 | ; We have received the last fragment |
407 | 407 | ||
408 | .is_last_fragment: |
408 | .is_last_fragment: |
409 | DEBUGF 1,"Last fragmented packet received!\n" |
409 | DEBUGF 1,"Last fragmented packet received!\n" |
410 | 410 | ||
411 | call IPv4_find_fragment_slot |
411 | call IPv4_find_fragment_slot |
412 | cmp esi, -1 |
412 | cmp esi, -1 |
413 | je .dump |
413 | je .dump |
414 | 414 | ||
415 | mov esi, [esi + FRAGMENT_slot.ptr] ; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer |
415 | mov esi, [esi + FRAGMENT_slot.ptr] ; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer |
416 | push esi |
416 | push esi |
417 | xor eax, eax |
417 | xor eax, eax |
418 | or edi, -1 |
418 | or edi, -1 |
419 | 419 | ||
420 | .count_bytes: |
420 | .count_bytes: |
421 | cmp [esi + FRAGMENT_entry.PrevPtr], edi |
421 | cmp [esi + FRAGMENT_entry.PrevPtr], edi |
422 | jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
422 | jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
423 | mov cx, word [esi + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Add total length |
423 | mov cx, word [esi + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Add total length |
424 | xchg cl, ch |
424 | xchg cl, ch |
425 | DEBUGF 1,"Packet size: %u\n", cx |
425 | DEBUGF 1,"Packet size: %u\n", cx |
426 | add ax, cx |
426 | add ax, cx |
427 | movzx cx, byte [esi + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Sub Header length |
427 | movzx cx, byte [esi + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Sub Header length |
428 | and cx, 0x000F |
428 | and cx, 0x000F |
429 | shl cx, 2 |
429 | shl cx, 2 |
430 | DEBUGF 1,"Header size: %u\n", cx |
430 | DEBUGF 1,"Header size: %u\n", cx |
431 | sub ax, cx |
431 | sub ax, cx |
432 | mov edi, esi |
432 | mov edi, esi |
433 | mov esi, [esi + FRAGMENT_entry.NextPtr] |
433 | mov esi, [esi + FRAGMENT_entry.NextPtr] |
434 | cmp esi, -1 |
434 | cmp esi, -1 |
435 | jne .count_bytes |
435 | jne .count_bytes |
436 | 436 | ||
437 | mov esi, [esp+4] |
437 | mov esi, [esp+4] |
438 | mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code |
438 | mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code |
439 | mov [esi + FRAGMENT_entry.NextPtr], -1 |
439 | mov [esi + FRAGMENT_entry.NextPtr], -1 |
440 | mov [esi + FRAGMENT_entry.PrevPtr], edi |
440 | mov [esi + FRAGMENT_entry.PrevPtr], edi |
441 | mov [esi + FRAGMENT_entry.Owner], ebx |
441 | mov [esi + FRAGMENT_entry.Owner], ebx |
442 | 442 | ||
443 | mov cx, [edx + IPv4_Packet.TotalLength] ; Note: This time we dont substract Header length |
443 | mov cx, [edx + IPv4_Packet.TotalLength] ; Note: This time we dont substract Header length |
444 | xchg cl , ch |
444 | xchg cl , ch |
445 | DEBUGF 1,"Packet size: %u\n", cx |
445 | DEBUGF 1,"Packet size: %u\n", cx |
446 | add ax , cx |
446 | add ax , cx |
447 | DEBUGF 1,"Total Received data size: %u\n", eax |
447 | DEBUGF 1,"Total Received data size: %u\n", eax |
448 | 448 | ||
449 | push eax |
449 | push eax |
450 | mov ax , [edx + IPv4_Packet.FlagsAndFragmentOffset] |
450 | mov ax , [edx + IPv4_Packet.FlagsAndFragmentOffset] |
451 | xchg al , ah |
451 | xchg al , ah |
452 | shl ax , 3 |
452 | shl ax , 3 |
453 | add cx , ax |
453 | add cx , ax |
454 | pop eax |
454 | pop eax |
455 | DEBUGF 1,"Total Fragment size: %u\n", ecx |
455 | DEBUGF 1,"Total Fragment size: %u\n", ecx |
456 | 456 | ||
457 | cmp ax, cx |
457 | cmp ax, cx |
458 | jne .destroy_slot_pop |
458 | jne .destroy_slot_pop |
459 | 459 | ||
460 | push eax |
460 | push eax |
461 | push eax |
461 | push eax |
462 | call kernel_alloc |
462 | call kernel_alloc |
463 | test eax, eax |
463 | test eax, eax |
464 | je .destroy_slot_pop ; If we dont have enough space to allocate the buffer, discard all packets in slot |
464 | je .destroy_slot_pop ; If we dont have enough space to allocate the buffer, discard all packets in slot |
465 | mov edx, [esp+4] ; Get pointer to first fragment entry back in edx |
465 | mov edx, [esp+4] ; Get pointer to first fragment entry back in edx |
466 | 466 | ||
467 | .rebuild_packet_loop: |
467 | .rebuild_packet_loop: |
468 | movzx ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.FlagsAndFragmentOffset] ; Calculate the fragment offset |
468 | movzx ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.FlagsAndFragmentOffset] ; Calculate the fragment offset |
469 | xchg cl , ch ; intel byte order |
469 | xchg cl , ch ; intel byte order |
470 | shl cx , 3 ; multiply by 8 and clear first 3 bits |
470 | shl cx , 3 ; multiply by 8 and clear first 3 bits |
471 | DEBUGF 1,"Fragment offset: %u\n", cx |
471 | DEBUGF 1,"Fragment offset: %u\n", cx |
472 | 472 | ||
473 | lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment |
473 | lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment |
474 | movzx ebx, byte [edx + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Find header size (in ebx) of fragment |
474 | movzx ebx, byte [edx + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Find header size (in ebx) of fragment |
475 | and bx , 0x000F ; |
475 | and bx , 0x000F ; |
476 | shl bx , 2 ; |
476 | shl bx , 2 ; |
477 | 477 | ||
478 | lea esi, [edx + FRAGMENT_entry.Data] ; Set esi to the correct begin of fragment |
478 | lea esi, [edx + FRAGMENT_entry.Data] ; Set esi to the correct begin of fragment |
479 | movzx ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Calculate total length of fragment |
479 | movzx ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Calculate total length of fragment |
480 | xchg cl, ch ; intel byte order |
480 | xchg cl, ch ; intel byte order |
481 | 481 | ||
482 | cmp edi, eax ; Is this packet the first fragment ? |
482 | cmp edi, eax ; Is this packet the first fragment ? |
483 | je .first_fragment |
483 | je .first_fragment |
484 | sub cx, bx ; If not, dont copy the header |
484 | sub cx, bx ; If not, dont copy the header |
485 | add esi, ebx ; |
485 | add esi, ebx ; |
486 | .first_fragment: |
486 | .first_fragment: |
487 | 487 | ||
488 | push cx ; First copy dword-wise, then byte-wise |
488 | push cx ; First copy dword-wise, then byte-wise |
489 | shr cx, 2 ; |
489 | shr cx, 2 ; |
490 | rep movsd ; |
490 | rep movsd ; |
491 | pop cx ; |
491 | pop cx ; |
492 | and cx, 3 ; |
492 | and cx, 3 ; |
493 | rep movsb ; |
493 | rep movsb ; |
494 | 494 | ||
495 | push eax |
495 | push eax |
496 | push edx ; Push pointer to fragment onto stack |
496 | push edx ; Push pointer to fragment onto stack |
497 | mov ebx, [edx + FRAGMENT_entry.Owner] ; we need to remeber the owner, in case this is the last packet |
497 | mov ebx, [edx + FRAGMENT_entry.Owner] ; we need to remeber the owner, in case this is the last packet |
498 | mov edx, [edx + FRAGMENT_entry.NextPtr] ; Set edx to the next pointer |
498 | mov edx, [edx + FRAGMENT_entry.NextPtr] ; Set edx to the next pointer |
499 | call kernel_free ; free the previous fragment buffer (this uses the value from stack) |
499 | call kernel_free ; free the previous fragment buffer (this uses the value from stack) |
500 | pop eax |
500 | pop eax |
501 | cmp edx, -1 ; Check if it is last fragment in chain |
501 | cmp edx, -1 ; Check if it is last fragment in chain |
502 | jne .rebuild_packet_loop |
502 | jne .rebuild_packet_loop |
503 | 503 | ||
504 | pop ecx ; |
504 | pop ecx ; |
505 | xchg cl, ch |
505 | xchg cl, ch |
506 | mov edx, eax |
506 | mov edx, eax |
507 | mov word [edx + IPv4_Packet.TotalLength], cx |
507 | mov word [edx + IPv4_Packet.TotalLength], cx |
508 | add esp, 8 |
508 | add esp, 8 |
509 | 509 | ||
510 | xchg cl, ch ; |
510 | xchg cl, ch ; |
511 | 511 | ||
512 | push ecx ;;;; |
512 | push ecx ;;;; |
513 | push eax ;;;; |
513 | push eax ;;;; |
514 | 514 | ||
515 | ; mov esi, edx ; This prints the IP packet to the debug board (usefull when using serial output debug..) |
515 | ; mov esi, edx ; This prints the IP packet to the debug board (usefull when using serial output debug..) |
516 | ; ; |
516 | ; ; |
517 | ; packet_to_debug |
517 | ; packet_to_debug |
518 | 518 | ||
519 | jmp .handle_it ; edx = buf ptr, ecx = size, [esp] buf ptr, [esp+4], total size, ebx=device ptr |
519 | jmp .handle_it ; edx = buf ptr, ecx = size, [esp] buf ptr, [esp+4], total size, ebx=device ptr |
520 | 520 | ||
521 | .destroy_slot_pop: |
521 | .destroy_slot_pop: |
522 | add esp, 4 |
522 | add esp, 4 |
523 | .destroy_slot: |
523 | .destroy_slot: |
524 | DEBUGF 1,"Destroy fragment slot!\n" |
524 | DEBUGF 1,"Destroy fragment slot!\n" |
525 | ; TODO! |
525 | ; TODO! |
526 | jmp .dump |
526 | jmp .dump |
527 | 527 | ||
528 | 528 | ||
529 | 529 | ||
530 | 530 | ||
531 | ;----------------------------------- |
531 | ;----------------------------------- |
532 | ; The IP packet has some options |
532 | ; The IP packet has some options |
533 | 533 | ||
534 | .has_options: |
534 | .has_options: |
535 | jmp .dump |
535 | jmp .dump |
536 | 536 | ||
537 | 537 | ||
538 | 538 | ||
539 | ;----------------------------------------------------------------- |
539 | ;----------------------------------------------------------------- |
540 | ; |
540 | ; |
541 | ; find fragment slot |
541 | ; find fragment slot |
542 | ; |
542 | ; |
543 | ; IN: pointer to fragmented packet in edx |
543 | ; IN: pointer to fragmented packet in edx |
544 | ; OUT: pointer to slot in edi, -1 on error |
544 | ; OUT: pointer to slot in edi, -1 on error |
545 | ; |
545 | ; |
546 | ;----------------------------------------------------------------- |
546 | ;----------------------------------------------------------------- |
547 | align 4 |
547 | align 4 |
548 | IPv4_find_fragment_slot: |
548 | IPv4_find_fragment_slot: |
549 | 549 | ||
550 | ;;; TODO: the RFC says we should check protocol number too |
550 | ;;; TODO: the RFC says we should check protocol number too |
551 | 551 | ||
552 | push eax ebx ecx edx |
552 | push eax ebx ecx edx |
553 | mov ax , word [edx + IPv4_Packet.Identification] |
553 | mov ax , word [edx + IPv4_Packet.Identification] |
554 | mov ecx, MAX_FRAGMENTS |
554 | mov ecx, MAX_FRAGMENTS |
555 | mov esi, FRAGMENT_LIST |
555 | mov esi, FRAGMENT_LIST |
556 | mov ebx, dword [edx + IPv4_Packet.SourceAddress] |
556 | mov ebx, dword [edx + IPv4_Packet.SourceAddress] |
557 | mov edx, dword [edx + IPv4_Packet.DestinationAddress] |
557 | mov edx, dword [edx + IPv4_Packet.DestinationAddress] |
558 | .find_slot: |
558 | .find_slot: |
559 | cmp word [esi + FRAGMENT_slot.id], ax |
559 | cmp word [esi + FRAGMENT_slot.id], ax |
560 | jne .try_next |
560 | jne .try_next |
561 | cmp dword [esi + FRAGMENT_slot.SrcIP], ebx |
561 | cmp dword [esi + FRAGMENT_slot.SrcIP], ebx |
562 | jne .try_next |
562 | jne .try_next |
563 | cmp dword [esi + FRAGMENT_slot.DstIP], edx |
563 | cmp dword [esi + FRAGMENT_slot.DstIP], edx |
564 | je .found_slot |
564 | je .found_slot |
565 | .try_next: |
565 | .try_next: |
566 | add esi, FRAGMENT_slot.size |
566 | add esi, FRAGMENT_slot.size |
567 | loop .find_slot |
567 | loop .find_slot |
568 | ; pop edx ebx |
568 | ; pop edx ebx |
569 | or esi, -1 |
569 | or esi, -1 |
570 | ; ret |
570 | ; ret |
571 | 571 | ||
572 | .found_slot: |
572 | .found_slot: |
573 | pop edx ecx ebx eax |
573 | pop edx ecx ebx eax |
574 | ret |
574 | ret |
575 | 575 | ||
576 | 576 | ||
577 | ;------------------------------------------------------------------ |
577 | ;------------------------------------------------------------------ |
578 | ; |
578 | ; |
579 | ; IPv4_output |
579 | ; IPv4_output |
580 | ; |
580 | ; |
581 | ; IN: eax = dest ip |
581 | ; IN: eax = dest ip |
582 | ; ebx = source ip |
582 | ; ebx = source ip |
583 | ; ecx = data length |
583 | ; ecx = data length |
584 | ; dx = fragment id |
584 | ; dx = fragment id |
585 | ; di = TTL shl 8 + protocol |
585 | ; di = TTL shl 8 + protocol |
586 | ; |
586 | ; |
587 | ; OUT: eax = pointer to buffer start |
587 | ; OUT: eax = pointer to buffer start |
588 | ; ebx = pointer to device struct (needed for sending procedure) |
588 | ; ebx = pointer to device struct (needed for sending procedure) |
589 | ; ecx = unchanged (packet size of embedded data) |
589 | ; ecx = unchanged (packet size of embedded data) |
590 | ; edx = size of complete buffer |
590 | ; edx = size of complete buffer |
591 | ; edi = pointer to start of data (0 on error) |
591 | ; edi = pointer to start of data (0 on error) |
592 | ; |
592 | ; |
593 | ;------------------------------------------------------------------ |
593 | ;------------------------------------------------------------------ |
594 | align 4 |
594 | align 4 |
595 | IPv4_output: |
595 | IPv4_output: |
596 | 596 | ||
597 | DEBUGF 1,"IPv4_create_packet: size=%u\n", ecx |
597 | DEBUGF 1,"IPv4_create_packet: size=%u\n", ecx |
598 | 598 | ||
599 | cmp ecx, 65500 ; Max IPv4 packet size |
599 | cmp ecx, 65500 ; Max IPv4 packet size |
600 | jg .too_large |
600 | jg .too_large |
601 | 601 | ||
602 | push ecx eax ebx dx di |
602 | push ecx eax ebx dx di |
603 | 603 | ||
604 | call ARP_IP_to_MAC |
604 | call ARP_IP_to_MAC |
605 | 605 | ||
606 | test eax, 0xffff0000 ; error bits |
606 | test eax, 0xffff0000 ; error bits |
607 | jnz .arp_error |
607 | jnz .arp_error |
608 | 608 | ||
609 | .continue: |
609 | .continue: |
610 | 610 | ||
611 | push ebx ; push the mac |
611 | push ebx ; push the mac |
612 | push ax |
612 | push ax |
613 | 613 | ||
614 | call IPv4_dest_to_dev |
614 | call IPv4_dest_to_dev |
615 | inc [IP_PACKETS_TX+edi] |
615 | inc [IP_PACKETS_TX+edi] |
616 | mov ebx, [NET_DRV_LIST+edi] |
616 | mov ebx, [NET_DRV_LIST+edi] |
617 | lea eax, [ebx + ETH_DEVICE.mac] |
617 | lea eax, [ebx + ETH_DEVICE.mac] |
618 | mov edx, esp |
618 | mov edx, esp |
619 | mov ecx, [esp + 18] |
619 | mov ecx, [esp + 18] |
620 | add ecx, IPv4_Packet.DataOrOptional |
620 | add ecx, IPv4_Packet.DataOrOptional |
621 | mov di , ETHER_IPv4 |
621 | mov di , ETHER_IPv4 |
622 | call ETH_output |
622 | call ETH_output |
623 | jz .error |
623 | jz .error |
624 | 624 | ||
625 | add esp, 6 ; pop the mac |
625 | add esp, 6 ; pop the mac |
626 | 626 | ||
627 | mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) |
627 | mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) |
628 | mov [edi + IPv4_Packet.TypeOfService], 0 ; nothing special, just plain ip packet |
628 | mov [edi + IPv4_Packet.TypeOfService], 0 ; nothing special, just plain ip packet |
629 | mov [edi + IPv4_Packet.TotalLength], cx |
629 | mov [edi + IPv4_Packet.TotalLength], cx |
630 | rol [edi + IPv4_Packet.TotalLength], 8 ; internet byte order |
630 | rol [edi + IPv4_Packet.TotalLength], 8 ; internet byte order |
631 | mov [edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000 |
631 | mov [edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000 |
632 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
632 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
633 | popw word [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol |
633 | popw word [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol |
634 | ; [edi + IPv4_Packet.Protocol] |
634 | ; [edi + IPv4_Packet.Protocol] |
635 | popw [edi + IPv4_Packet.Identification] ; fragment id |
635 | popw [edi + IPv4_Packet.Identification] ; fragment id |
636 | popd [edi + IPv4_Packet.SourceAddress] |
636 | popd [edi + IPv4_Packet.SourceAddress] |
637 | popd [edi + IPv4_Packet.DestinationAddress] |
637 | popd [edi + IPv4_Packet.DestinationAddress] |
638 | 638 | ||
639 | pop ecx |
639 | pop ecx |
640 | 640 | ||
641 | IPv4_checksum edi |
641 | IPv4_checksum edi |
642 | add edi, IPv4_Packet.DataOrOptional |
642 | add edi, IPv4_Packet.DataOrOptional |
643 | DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx |
643 | DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx |
644 | ret |
644 | ret |
645 | 645 | ||
646 | .error: |
646 | .error: |
647 | add esp, 6 |
647 | add esp, 6 |
648 | .arp_error: |
648 | .arp_error: |
649 | add esp, 4+4+4+2+2 |
649 | add esp, 4+4+4+2+2 |
650 | .too_large: |
650 | .too_large: |
651 | DEBUGF 1,"IPv4_create_packet: Failed\n" |
651 | DEBUGF 1,"IPv4_create_packet: Failed\n" |
652 | sub edi, edi |
652 | sub edi, edi |
- | 653 | ret |
|
- | 654 | ||
- | 655 | ||
- | 656 | ||
- | 657 | ||
- | 658 | ||
- | 659 | ;------------------------------------------------------------------ |
|
- | 660 | ; |
|
- | 661 | ; IPv4_output_raw |
|
- | 662 | ; |
|
- | 663 | ; IN: eax = socket ptr |
|
- | 664 | ; ecx = data length |
|
- | 665 | ; esi = data ptr |
|
- | 666 | ; |
|
- | 667 | ; OUT: / |
|
- | 668 | ; |
|
- | 669 | ;------------------------------------------------------------------ |
|
- | 670 | align 4 |
|
- | 671 | IPv4_output_raw: |
|
- | 672 | ||
- | 673 | DEBUGF 1,"IPv4_output_raw: size=%u ptr=%x socket=%x\n", ecx, esi, eax |
|
- | 674 | ||
- | 675 | cmp ecx, 1480 ;;;;; |
|
- | 676 | jg .too_large |
|
- | 677 | ||
- | 678 | sub esp, 8 |
|
- | 679 | push esi eax |
|
- | 680 | ||
- | 681 | call ARP_IP_to_MAC |
|
- | 682 | ||
- | 683 | test eax, 0xffff0000 ; error bits |
|
- | 684 | jnz .arp_error |
|
- | 685 | ||
- | 686 | .continue: |
|
- | 687 | ||
- | 688 | push ebx ; push the mac |
|
- | 689 | push ax |
|
- | 690 | ||
- | 691 | call IPv4_dest_to_dev |
|
- | 692 | inc [IP_PACKETS_TX+edi] |
|
- | 693 | mov ebx, [NET_DRV_LIST+edi] |
|
- | 694 | lea eax, [ebx + ETH_DEVICE.mac] |
|
- | 695 | mov edx, esp |
|
- | 696 | mov ecx, [esp + 6+4] |
|
- | 697 | add ecx, IPv4_Packet.DataOrOptional |
|
- | 698 | mov di, ETHER_IPv4 |
|
- | 699 | call ETH_output |
|
- | 700 | jz .error |
|
- | 701 | ||
- | 702 | add esp, 6 ; pop the mac |
|
- | 703 | ||
- | 704 | mov dword[esp+4+4], edx |
|
- | 705 | mov dword[esp+4+4+4], eax |
|
- | 706 | ||
- | 707 | pop eax esi |
|
- | 708 | ;; todo: check socket options if we should add header, or just compute checksum |
|
- | 709 | ||
- | 710 | push edi ecx |
|
- | 711 | rep movsb |
|
- | 712 | pop ecx edi |
|
- | 713 | ||
- | 714 | ; [edi + IPv4_Packet.VersionAndIHL] ; IPv4, normal length (no Optional header) |
|
- | 715 | ; [edi + IPv4_Packet.TypeOfService] ; nothing special, just plain ip packet |
|
- | 716 | ; [edi + IPv4_Packet.TotalLength] |
|
- | 717 | ; [edi + IPv4_Packet.TotalLength] ; internet byte order |
|
- | 718 | ; [edi + IPv4_Packet.FlagsAndFragmentOffset] |
|
- | 719 | ||
- | 720 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
|
- | 721 | ||
- | 722 | ; [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol |
|
- | 723 | ; [edi + IPv4_Packet.Protocol] |
|
- | 724 | ; [edi + IPv4_Packet.Identification] ; fragment id |
|
- | 725 | ; [edi + IPv4_Packet.SourceAddress] |
|
- | 726 | ; [edi + IPv4_Packet.DestinationAddress] |
|
- | 727 | ||
- | 728 | IPv4_checksum edi ;;;; todo: checksum for IP packet with options! |
|
- | 729 | add edi, IPv4_Packet.DataOrOptional |
|
- | 730 | DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx |
|
- | 731 | call [ebx + NET_DEVICE.transmit] |
|
- | 732 | ret |
|
- | 733 | ||
- | 734 | .error: |
|
- | 735 | add esp, 6 |
|
- | 736 | .arp_error: |
|
- | 737 | add esp, 8+4+4 |
|
- | 738 | .too_large: |
|
- | 739 | DEBUGF 1,"IPv4_output_raw: Failed\n" |
|
- | 740 | sub edi, edi |
|
653 | ret |
741 | ret |
654 | 742 | ||
655 | 743 | ||
656 | ;-------------------------------------------------------- |
744 | ;-------------------------------------------------------- |
657 | ; |
745 | ; |
658 | ; |
746 | ; |
659 | ; IN: dword [esp] = pointer to buffer containing ipv4 packet to be fragmented |
747 | ; IN: dword [esp] = pointer to buffer containing ipv4 packet to be fragmented |
660 | ; dword [esp+4] = buffer size |
748 | ; dword [esp+4] = buffer size |
661 | ; esi = pointer to ip header in that buffer |
749 | ; esi = pointer to ip header in that buffer |
662 | ; ecx = max size of fragments |
750 | ; ecx = max size of fragments |
663 | ; |
751 | ; |
664 | ; OUT: / |
752 | ; OUT: / |
665 | ; |
753 | ; |
666 | ;-------------------------------------------------------- |
754 | ;-------------------------------------------------------- |
667 | 755 | ||
668 | align 4 |
756 | align 4 |
669 | IPv4_fragment: |
757 | IPv4_fragment: |
670 | 758 | ||
671 | DEBUGF 1,"IPv4_fragment\n" |
759 | DEBUGF 1,"IPv4_fragment\n" |
672 | 760 | ||
673 | and ecx, not 111b ; align 4 |
761 | and ecx, not 111b ; align 4 |
674 | 762 | ||
675 | cmp ecx, IPv4_Packet.DataOrOptional + 8 ; must be able to put at least 8 bytes |
763 | cmp ecx, IPv4_Packet.DataOrOptional + 8 ; must be able to put at least 8 bytes |
676 | jl .err2 |
764 | jl .err2 |
677 | 765 | ||
678 | push esi ecx |
766 | push esi ecx |
679 | mov eax, [esi + IPv4_Packet.DestinationAddress] |
767 | mov eax, [esi + IPv4_Packet.DestinationAddress] |
680 | call ARP_IP_to_MAC |
768 | call ARP_IP_to_MAC |
681 | pop ecx esi |
769 | pop ecx esi |
682 | cmp eax, -1 |
770 | cmp eax, -1 |
683 | jz .err2 |
771 | jz .err2 |
684 | 772 | ||
685 | push ebx |
773 | push ebx |
686 | push ax |
774 | push ax |
687 | 775 | ||
688 | mov ebx, [NET_DRV_LIST] |
776 | mov ebx, [NET_DRV_LIST] |
689 | lea eax, [ebx + ETH_DEVICE.mac] |
777 | lea eax, [ebx + ETH_DEVICE.mac] |
690 | push eax |
778 | push eax |
691 | 779 | ||
692 | 780 | ||
693 | push esi ; ptr to ip header |
781 | push esi ; ptr to ip header |
694 | sub ecx, 20 ; substract header size |
782 | sub ecx, 20 ; substract header size |
695 | push ecx ; max data size |
783 | push ecx ; max data size |
696 | push dword 0 ; offset |
784 | push dword 0 ; offset |
697 | 785 | ||
698 | .new_fragment: |
786 | .new_fragment: |
699 | DEBUGF 1,"Ipv4_fragment - new_fragmentn" |
787 | DEBUGF 1,"Ipv4_fragment - new_fragmentn" |
700 | 788 | ||
701 | 789 | ||
702 | mov eax, [esp + 3*4] |
790 | mov eax, [esp + 3*4] |
703 | lea ebx, [esp + 4*4] |
791 | lea ebx, [esp + 4*4] |
704 | mov di , ETHER_IPv4 |
792 | mov di , ETHER_IPv4 |
705 | call ETH_output |
793 | call ETH_output |
706 | 794 | ||
707 | cmp edi, -1 |
795 | cmp edi, -1 |
708 | jz .err |
796 | jz .err |
709 | 797 | ||
710 | ; copy header |
798 | ; copy header |
711 | mov esi, [esp + 2*4] |
799 | mov esi, [esp + 2*4] |
712 | mov ecx, 5 ; 5 dwords: TODO: use IHL field of the header! |
800 | mov ecx, 5 ; 5 dwords: TODO: use IHL field of the header! |
713 | rep movsd |
801 | rep movsd |
714 | 802 | ||
715 | ; copy data |
803 | ; copy data |
716 | mov esi, [esp + 2*4] |
804 | mov esi, [esp + 2*4] |
717 | add esi, 20 |
805 | add esi, 20 |
718 | add esi, [esp] ; offset |
806 | add esi, [esp] ; offset |
719 | 807 | ||
720 | mov ecx, [esp + 1*4] |
808 | mov ecx, [esp + 1*4] |
721 | DEBUGF 1,"IPv4_fragment - copying data (%u bytes)\n", ecx |
809 | DEBUGF 1,"IPv4_fragment - copying data (%u bytes)\n", ecx |
722 | rep movsb |
810 | rep movsb |
723 | 811 | ||
724 | ; now, correct header |
812 | ; now, correct header |
725 | mov ecx, [esp + 1*4] |
813 | mov ecx, [esp + 1*4] |
726 | add ecx, 20 |
814 | add ecx, 20 |
727 | xchg cl, ch |
815 | xchg cl, ch |
728 | mov [edi + IPv4_Packet.TotalLength], cx |
816 | mov [edi + IPv4_Packet.TotalLength], cx |
729 | 817 | ||
730 | mov ecx, [esp] ; offset |
818 | mov ecx, [esp] ; offset |
731 | xchg cl, ch |
819 | xchg cl, ch |
732 | 820 | ||
733 | ; cmp dword[esp + 4*4], 0 ; last fragment?;<<<<<< |
821 | ; cmp dword[esp + 4*4], 0 ; last fragment?;<<<<<< |
734 | ; je .last_fragment |
822 | ; je .last_fragment |
735 | or cx, 1 shl 2 ; more fragments |
823 | or cx, 1 shl 2 ; more fragments |
736 | ; .last_fragment: |
824 | ; .last_fragment: |
737 | mov [edi + IPv4_Packet.FlagsAndFragmentOffset], cx |
825 | mov [edi + IPv4_Packet.FlagsAndFragmentOffset], cx |
738 | 826 | ||
739 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
827 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
740 | 828 | ||
741 | ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< send the packet |
829 | ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< send the packet |
742 | mov ecx, [esp + 1*4] |
830 | mov ecx, [esp + 1*4] |
743 | 831 | ||
744 | push edx eax |
832 | push edx eax |
745 | IPv4_checksum edi |
833 | IPv4_checksum edi |
746 | 834 | ||
747 | call [ebx + NET_DEVICE.transmit] |
835 | call [ebx + NET_DEVICE.transmit] |
748 | ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< |
836 | ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< |
749 | 837 | ||
750 | mov ecx, [esp+4] |
838 | mov ecx, [esp+4] |
751 | add [esp], ecx |
839 | add [esp], ecx |
752 | 840 | ||
753 | mov ecx, [esp+3*4+6+4] ; ptr to begin of buff |
841 | mov ecx, [esp+3*4+6+4] ; ptr to begin of buff |
754 | add ecx, [esp+3*4+6+4+4] ; buff size |
842 | add ecx, [esp+3*4+6+4+4] ; buff size |
755 | sub ecx, [esp+2*4] ; ptr to ip header |
843 | sub ecx, [esp+2*4] ; ptr to ip header |
756 | add ecx, [esp] ; offset |
844 | add ecx, [esp] ; offset |
757 | 845 | ||
758 | DEBUGF 1,"Ipv4_fragment - bytes remaining: %u\n", ecx |
846 | DEBUGF 1,"Ipv4_fragment - bytes remaining: %u\n", ecx |
759 | 847 | ||
760 | cmp ecx, [esp+1*4] |
848 | cmp ecx, [esp+1*4] |
761 | jge .new_fragment |
849 | jge .new_fragment |
762 | 850 | ||
763 | mov [esp+4], ecx ; set fragment size to remaining packet size |
851 | mov [esp+4], ecx ; set fragment size to remaining packet size |
764 | jmp .new_fragment |
852 | jmp .new_fragment |
765 | 853 | ||
766 | .err: |
854 | .err: |
767 | DEBUGF 1,"Ipv4_fragment - failed\n" |
855 | DEBUGF 1,"Ipv4_fragment - failed\n" |
768 | .done: |
856 | .done: |
769 | add esp, 12 + 4 + 6 |
857 | add esp, 12 + 4 + 6 |
770 | .err2: |
858 | .err2: |
771 | DEBUGF 1,"Ipv4_fragment - dumping\n" |
859 | DEBUGF 1,"Ipv4_fragment - dumping\n" |
772 | call kernel_free |
860 | call kernel_free |
773 | add esp, 4 |
861 | add esp, 4 |
774 | 862 | ||
775 | ret |
863 | ret |
776 | 864 | ||
777 | 865 | ||
778 | 866 | ||
779 | ;--------------------------------------------------------------------------- |
867 | ;--------------------------------------------------------------------------- |
780 | ; |
868 | ; |
781 | ; IPv4_dest_to_dev |
869 | ; IPv4_dest_to_dev |
782 | ; |
870 | ; |
783 | ; IN: eax = Destination IP |
871 | ; IN: eax = Destination IP |
784 | ; OUT: edi = device id * 4 |
872 | ; OUT: edi = device id * 4 |
785 | ; |
873 | ; |
786 | ;--------------------------------------------------------------------------- |
874 | ;--------------------------------------------------------------------------- |
787 | align 4 |
875 | align 4 |
788 | IPv4_dest_to_dev: |
876 | IPv4_dest_to_dev: |
789 | 877 | ||
790 | cmp eax, 0xffffffff |
878 | cmp eax, 0xffffffff |
791 | je .invalid |
879 | je .invalid |
792 | 880 | ||
793 | xor edi, edi |
881 | xor edi, edi |
794 | mov ecx, MAX_IP |
882 | mov ecx, MAX_IP |
795 | 883 | ||
796 | .loop: |
884 | .loop: |
797 | mov ebx, [IP_LIST+edi] |
885 | mov ebx, [IP_LIST+edi] |
798 | and ebx, [SUBNET_LIST+edi] |
886 | and ebx, [SUBNET_LIST+edi] |
799 | jz .next |
887 | jz .next |
800 | 888 | ||
801 | mov edx, eax |
889 | mov edx, eax |
802 | and edx, [SUBNET_LIST+edi] |
890 | and edx, [SUBNET_LIST+edi] |
803 | 891 | ||
804 | cmp ebx, edx |
892 | cmp ebx, edx |
805 | je .found_it |
893 | je .found_it |
806 | .next: |
894 | .next: |
807 | add edi, 4 |
895 | add edi, 4 |
808 | loop .loop |
896 | loop .loop |
809 | 897 | ||
810 | .invalid: |
898 | .invalid: |
811 | xor edi, edi ; if none found, use device 0 as default device |
899 | xor edi, edi ; if none found, use device 0 as default device |
812 | 900 | ||
813 | .found_it: |
901 | .found_it: |
814 | DEBUGF 1,"IPv4_dest_to_dev: %u\n", edi |
902 | DEBUGF 1,"IPv4_dest_to_dev: %u\n", edi |
815 | 903 | ||
816 | ret |
904 | ret |
817 | 905 | ||
818 | 906 | ||
819 | 907 | ||
820 | ;--------------------------------------------------------------------------- |
908 | ;--------------------------------------------------------------------------- |
821 | ; |
909 | ; |
822 | ; IPv4_get_frgmnt_num |
910 | ; IPv4_get_frgmnt_num |
823 | ; |
911 | ; |
824 | ; IN: / |
912 | ; IN: / |
825 | ; OUT: fragment number in ax |
913 | ; OUT: fragment number in ax |
826 | ; |
914 | ; |
827 | ;--------------------------------------------------------------------------- |
915 | ;--------------------------------------------------------------------------- |
828 | align 4 |
916 | align 4 |
829 | IPv4_get_frgmnt_num: |
917 | IPv4_get_frgmnt_num: |
830 | xor ax, ax ;;; TODO: replace this with real code |
918 | xor ax, ax ;;; TODO: replace this with real code |
831 | 919 | ||
832 | ret |
920 | ret |
833 | 921 | ||
834 | 922 | ||
835 | ;--------------------------------------------------------------------------- |
923 | ;--------------------------------------------------------------------------- |
836 | ; |
924 | ; |
837 | ; IPv4_API |
925 | ; IPv4_API |
838 | ; |
926 | ; |
839 | ; This function is called by system function 75 |
927 | ; This function is called by system function 75 |
840 | ; |
928 | ; |
841 | ; IN: subfunction number in bl |
929 | ; IN: subfunction number in bl |
842 | ; device number in bh |
930 | ; device number in bh |
843 | ; ecx, edx, .. depends on subfunction |
931 | ; ecx, edx, .. depends on subfunction |
844 | ; |
932 | ; |
845 | ; OUT: |
933 | ; OUT: |
846 | ; |
934 | ; |
847 | ;--------------------------------------------------------------------------- |
935 | ;--------------------------------------------------------------------------- |
848 | align 4 |
936 | align 4 |
849 | IPv4_API: |
937 | IPv4_API: |
850 | 938 | ||
851 | movzx eax, bh |
939 | movzx eax, bh |
852 | shl eax, 2 |
940 | shl eax, 2 |
853 | 941 | ||
854 | test bl, bl |
942 | test bl, bl |
855 | jz .packets_tx ; 0 |
943 | jz .packets_tx ; 0 |
856 | dec bl |
944 | dec bl |
857 | jz .packets_rx ; 1 |
945 | jz .packets_rx ; 1 |
858 | dec bl |
946 | dec bl |
859 | jz .read_ip ; 2 |
947 | jz .read_ip ; 2 |
860 | dec bl |
948 | dec bl |
861 | jz .write_ip ; 3 |
949 | jz .write_ip ; 3 |
862 | dec bl |
950 | dec bl |
863 | jz .read_dns ; 4 |
951 | jz .read_dns ; 4 |
864 | dec bl |
952 | dec bl |
865 | jz .write_dns ; 5 |
953 | jz .write_dns ; 5 |
866 | dec bl |
954 | dec bl |
867 | jz .read_subnet ; 6 |
955 | jz .read_subnet ; 6 |
868 | dec bl |
956 | dec bl |
869 | jz .write_subnet ; 7 |
957 | jz .write_subnet ; 7 |
870 | dec bl |
958 | dec bl |
871 | jz .read_gateway ; 8 |
959 | jz .read_gateway ; 8 |
872 | dec bl |
960 | dec bl |
873 | jz .write_gateway ; 9 |
961 | jz .write_gateway ; 9 |
874 | 962 | ||
875 | .error: |
963 | .error: |
876 | mov eax, -1 |
964 | mov eax, -1 |
877 | ret |
965 | ret |
878 | 966 | ||
879 | .packets_tx: |
967 | .packets_tx: |
880 | add eax, IP_PACKETS_TX |
968 | add eax, IP_PACKETS_TX |
881 | mov eax, [eax] |
969 | mov eax, [eax] |
882 | ret |
970 | ret |
883 | 971 | ||
884 | .packets_rx: |
972 | .packets_rx: |
885 | add eax, IP_PACKETS_RX |
973 | add eax, IP_PACKETS_RX |
886 | mov eax, [eax] |
974 | mov eax, [eax] |
887 | ret |
975 | ret |
888 | 976 | ||
889 | .read_ip: |
977 | .read_ip: |
890 | add eax, IP_LIST |
978 | add eax, IP_LIST |
891 | mov eax, [eax] |
979 | mov eax, [eax] |
892 | ret |
980 | ret |
893 | 981 | ||
894 | .write_ip: |
982 | .write_ip: |
895 | add eax, IP_LIST |
983 | add eax, IP_LIST |
896 | mov [eax], ecx |
984 | mov [eax], ecx |
897 | xor eax, eax |
985 | xor eax, eax |
898 | ret |
986 | ret |
899 | 987 | ||
900 | .read_dns: |
988 | .read_dns: |
901 | add eax, DNS_LIST |
989 | add eax, DNS_LIST |
902 | mov eax, [eax] |
990 | mov eax, [eax] |
903 | ret |
991 | ret |
904 | 992 | ||
905 | .write_dns: |
993 | .write_dns: |
906 | add eax, DNS_LIST |
994 | add eax, DNS_LIST |
907 | mov [eax], ecx |
995 | mov [eax], ecx |
908 | xor eax, eax |
996 | xor eax, eax |
909 | ret |
997 | ret |
910 | 998 | ||
911 | .read_subnet: |
999 | .read_subnet: |
912 | add eax, SUBNET_LIST |
1000 | add eax, SUBNET_LIST |
913 | mov eax, [eax] |
1001 | mov eax, [eax] |
914 | ret |
1002 | ret |
915 | 1003 | ||
916 | .write_subnet: |
1004 | .write_subnet: |
917 | add eax, SUBNET_LIST |
1005 | add eax, SUBNET_LIST |
918 | mov [eax], ecx |
1006 | mov [eax], ecx |
919 | xor eax, eax |
1007 | xor eax, eax |
920 | ret |
1008 | ret |
921 | 1009 | ||
922 | .read_gateway: |
1010 | .read_gateway: |
923 | add eax, GATEWAY_LIST |
1011 | add eax, GATEWAY_LIST |
924 | mov eax, [eax] |
1012 | mov eax, [eax] |
925 | ret |
1013 | ret |
926 | 1014 | ||
927 | .write_gateway: |
1015 | .write_gateway: |
928 | add eax, GATEWAY_LIST |
1016 | add eax, GATEWAY_LIST |
929 | mov [eax], ecx |
1017 | mov [eax], ecx |
930 | xor eax, eax |
1018 | xor eax, eax |
931 | ret |
1019 | ret |
932 | 1020 | ||
933 | >< |
1021 | >< |
934 | 1022 | ||
935 | ><< |
1023 | ><< |
936 | 1024 | ||
937 | ><<< |
1025 | ><<< |
938 | 1026 | ||
939 | ><<<< |
1027 | ><<<< |
940 | 1028 | ||
941 | ><<<<< |
1029 | ><<<<< |
942 | 1030 | ||
943 | ><<<<<< |
1031 | ><<<<<< |
944 | 1032 | ||
945 | ><<<<<<< |
1033 | ><<<<<<< |
946 | 1034 | ||
947 | ><<<<<<<< |
1035 | ><<<<<<<< |
948 | 1036 | ||
949 | ><<<<<<<<< |
1037 | ><<<<<<<<< |
950 | 1038 | ||
951 | ><<<<<<<<<< |
1039 | ><<<<<<<<<< |
952 | 1040 | ||
953 | ><<<<<<<<<<< |
1041 | ><<<<<<<<<<< |
954 | 1042 | ||
955 | ><<<<<<<<<<<< |
1043 | ><<<<<<<<<<<< |
956 | 1044 | ||
957 | ><<<<<<<<<<<<< |
1045 | ><<<<<<<<<<<<< |
958 | 1046 | ||
959 | ><<<<<<<<<<<<<< |
1047 | ><<<<<<<<<<<<<< |
960 | 1048 | ||
961 | ><<<<<<<<<<<<<<< |
1049 | ><<<<<<<<<<<<<<< |
962 | 1050 | ||
963 | ><<<<<<<<<<<<<<<< |
1051 | ><<<<<<<<<<<<<<<< |
964 | 1052 | ||
965 | ><<<<<<<<<<<<<<<<< |
1053 | ><<<<<<<<<<<<<<<<< |
966 | 1054 | ||
967 | ><<<<<<<<<<<<<<<<<< |
1055 | ><<<<<<<<<<<<<<<<<< |
968 | 1056 | ||
969 | ><<<<<<<<<<<<<<<<<<< |
1057 | ><<<<<<<<<<<<<<<<<<< |
970 | 1058 | ||
971 | ><<<<<<<<<<<<<<<<<<<< |
1059 | ><<<<<<<<<<<<<<<<<<<< |
972 | 1060 | ||
973 | ><<<<<<<<<<<<<<<<<<<<< |
1061 | ><<<<<<<<<<<<<<<<<<<<< |
974 | 1062 | ||
975 | ><<<<<<<<<<<<<<<<<<<<<< |
1063 | ><<<<<<<<<<<<<<<<<<<<<< |
976 | 1064 | ||
977 | ><<<<<<<<<<<<<<<<<<<<<<< |
1065 | ><<<<<<<<<<<<<<<<<<<<<<< |
978 | 1066 | ||
979 | ><<<<<<<<<<<<<<<<<<<<<<<< |
1067 | ><<<<<<<<<<<<<<<<<<<<<<<< |
980 | 1068 | ||
981 | ><<<<<<<<<<<<<<<<<<<<<<<<< |
1069 | ><<<<<<<<<<<<<<<<<<<<<<<<< |
982 | 1070 | ||
983 | ><<<<<<<<<<<<<<<<<<<<<<<<<< |
1071 | ><<<<<<<<<<<<<<<<<<<<<<<<<< |
984 | 1072 | ||
985 | ><<<<<<<<<<<<<<<<<<<<<<<<<<< |
1073 | ><<<<<<<<<<<<<<<<<<<<<<<<<<< |
986 | 1074 | ||
987 | ><<<<<<<<<<<<<<<<<<<<<<<<<<<< |
1075 | ><<<<<<<<<<<<<<<<<<<<<<<<<<<< |
988 | 1076 | ||
989 | >><><<><<<><<<<><<<<<><<<<<<><<<<<<<><<<<<<<<><<<<<<<<<><<<<<<<<<<><<<<<<<<<<<><<<<<<<<<<<<><<<<<<<<<<<<<><<<<<<<<<<<<<<><<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<<<<<<<> |
1077 | >><><<><<<><<<<><<<<<><<<<<<><<<<<<<><<<<<<<<><<<<<<<<<><<<<<<<<<<><<<<<<<<<<<><<<<<<<<<<<<><<<<<<<<<<<<<><<<<<<<<<<<<<<><<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<<<<<<><<<<<<<<<<<<<<<<<<<<<<<<<<<<> |
990 | ;>< |
1078 | ;>< |
991 | ;><< |
1079 | ;><< |
992 | ;><<< |
1080 | ;><<< |
993 | ;><<<< |
1081 | ;><<<< |
994 | ;><<<<< |
1082 | ;><<<<< |
995 | ;> |
1083 | ;> |