Rev 1171 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1171 | Rev 1196 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2009. 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 | ;; IP.INC ;; |
6 | ;; IP.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: 922 $ |
19 | $Revision: 922 $ |
20 | 20 | ||
21 | ; IP underlying protocols numbers |
21 | ; IP underlying protocols numbers |
22 | 22 | ||
23 | ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel |
23 | ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel |
24 | 24 | ||
25 | MAX_FRAGMENTS equ 16 |
25 | MAX_FRAGMENTS equ 16 |
26 | MAX_IP equ MAX_NET_DEVICES |
26 | MAX_IP equ MAX_NET_DEVICES |
27 | 27 | ||
28 | struct IPv4_Packet |
28 | struct IPv4_Packet |
29 | .VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] |
29 | .VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] |
30 | .TypeOfService db ? |
30 | .TypeOfService db ? |
31 | .TotalLength dw ? |
31 | .TotalLength dw ? |
32 | .Identification dw ? |
32 | .Identification dw ? |
33 | .FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15] |
33 | .FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15] |
34 | .TimeToLive db ? ; |
34 | .TimeToLive db ? ; |
35 | .Protocol db ? |
35 | .Protocol db ? |
36 | .HeaderChecksum dw ? |
36 | .HeaderChecksum dw ? |
37 | .SourceAddress dd ? |
37 | .SourceAddress dd ? |
38 | .DestinationAddress dd ? |
38 | .DestinationAddress dd ? |
39 | .DataOrOptional: |
39 | .DataOrOptional: |
40 | ends |
40 | ends |
41 | 41 | ||
42 | struct FRAGMENT_slot |
42 | struct FRAGMENT_slot |
43 | .ttl dw ? ; Time to live for this entry, 0 for empty slot's |
43 | .ttl dw ? ; Time to live for this entry, 0 for empty slot's |
44 | .id dw ? ; Identification field from IP header |
44 | .id dw ? ; Identification field from IP header |
45 | .SrcIP dd ? ; .. from IP header |
45 | .SrcIP dd ? ; .. from IP header |
46 | .DstIP dd ? ; .. from IP header |
46 | .DstIP dd ? ; .. from IP header |
47 | .ptr dd ? ; Pointer to first packet |
47 | .ptr dd ? ; Pointer to first packet |
48 | .size: |
48 | .size: |
49 | ends |
49 | ends |
50 | 50 | ||
51 | struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets |
51 | struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets |
52 | .PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet) |
52 | .PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet) |
53 | .NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet) |
53 | .NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet) |
54 | .Owner dd ? ; Pointer to structure of driver |
54 | .Owner dd ? ; Pointer to structure of driver |
55 | rb 2 ; to match ethernet header size |
55 | rb 2 ; to match ethernet header size |
56 | .Data: ; Ip header begins here (we will need the IP header to re-construct the complete packet) |
56 | .Data: ; Ip header begins here (we will need the IP header to re-construct the complete packet) |
57 | ends |
57 | ends |
58 | 58 | ||
59 | align 4 |
59 | align 4 |
60 | uglobal |
60 | uglobal |
61 | BROADCAST dd ? |
61 | BROADCAST dd ? |
62 | IP_LIST rd MAX_IP |
62 | IP_LIST rd MAX_IP |
63 | SUBNET_LIST rd MAX_IP |
63 | SUBNET_LIST rd MAX_IP |
64 | DNS_LIST rd MAX_IP |
64 | DNS_LIST rd MAX_IP |
65 | GATEWAY_LIST rd MAX_IP |
65 | GATEWAY_LIST rd MAX_IP |
66 | IP_PACKETS_TX rd MAX_IP |
66 | IP_PACKETS_TX rd MAX_IP |
67 | IP_PACKETS_RX rd MAX_IP |
67 | IP_PACKETS_RX rd MAX_IP |
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 | ; IN: / |
78 | ; IN: / |
79 | ; OUT: / |
79 | ; OUT: / |
80 | ; |
80 | ; |
81 | ;----------------------------------------------------------------- |
81 | ;----------------------------------------------------------------- |
82 | 82 | ||
83 | align 4 |
83 | align 4 |
84 | IPv4_init: |
84 | IPv4_init: |
85 | 85 | ||
86 | or eax, -1 |
86 | or eax, -1 |
87 | mov edi, BROADCAST |
87 | mov edi, BROADCAST |
- | 88 | stosd |
|
- | 89 | xor eax, eax |
|
88 | mov ecx, 1+4*MAX_IP |
90 | mov ecx, 4*MAX_IP |
89 | rep stosd |
91 | rep stosd |
90 | 92 | ||
91 | xor eax, eax |
93 | xor eax, eax |
92 | mov edi, FRAGMENT_LIST |
94 | mov edi, FRAGMENT_LIST |
93 | mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP |
95 | mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP |
94 | rep stosd |
96 | rep stosd |
95 | 97 | ||
96 | ret |
98 | ret |
97 | 99 | ||
98 | 100 | ||
99 | 101 | ||
100 | ;----------------------------------------------------------------- |
102 | ;----------------------------------------------------------------- |
101 | ; |
103 | ; |
102 | ; IP_Handler: |
104 | ; IP_Handler: |
103 | ; |
105 | ; |
104 | ; Called by eth_handler, |
106 | ; Called by eth_handler, |
105 | ; will check if IP Packet isnt damaged |
107 | ; will check if IP Packet isnt damaged |
106 | ; and call appropriate handler. (TCP/UDP/ICMP/..) |
108 | ; and call appropriate handler. (TCP/UDP/ICMP/..) |
107 | ; |
109 | ; |
108 | ; It will also re-construct fragmented packets |
110 | ; It will also re-construct fragmented packets |
109 | ; |
111 | ; |
110 | ; IN: Pointer to buffer in [esp] |
112 | ; IN: Pointer to buffer in [esp] |
111 | ; size of buffer in [esp+4] |
113 | ; size of buffer in [esp+4] |
112 | ; pointer to device struct in ebx |
114 | ; pointer to device struct in ebx |
113 | ; pointer to IP Packet data in edx |
115 | ; pointer to IP Packet data in edx |
114 | ; OUT: / |
116 | ; OUT: / |
115 | ; |
117 | ; |
116 | ;----------------------------------------------------------------- |
118 | ;----------------------------------------------------------------- |
117 | 119 | ||
118 | align 4 |
120 | align 4 |
119 | IPv4_Handler: |
121 | IPv4_handler: |
120 | 122 | ||
121 | DEBUGF 1,"IP_Handler - start\n" |
123 | DEBUGF 1,"IP_Handler - start\n" |
122 | mov cx , [edx + IPv4_Packet.HeaderChecksum] |
124 | mov cx , [edx + IPv4_Packet.HeaderChecksum] |
123 | xchg ch , cl ; Get the checksum in intel format |
125 | xchg ch , cl ; Get the checksum in intel format |
124 | 126 | ||
125 | mov word [edx + IPv4_Packet.HeaderChecksum], 0 ; Clear checksum field to recalculating checksum |
127 | mov word [edx + IPv4_Packet.HeaderChecksum], 0 ; Clear checksum field to recalculating checksum |
126 | 128 | ||
127 | movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
129 | movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
128 | and eax, 0x0000000F ; |
130 | and eax, 0x0000000F ; |
129 | shl eax, 2 ; |
131 | shl eax, 2 ; |
130 | 132 | ||
131 | push edx |
133 | push edx |
132 | stdcall checksum_jb, edx, eax ; buf_ptr, buf_size |
134 | stdcall checksum_jb, edx, eax ; buf_ptr, buf_size |
133 | pop edx |
135 | pop edx |
134 | cmp cx , ax |
136 | cmp cx , ax |
135 | jnz .dump ; if CHECKSUM isn't valid then dump Packet |
137 | jnz .dump ; if CHECKSUM isn't valid then dump Packet |
136 | 138 | ||
137 | mov eax, [edx + IPv4_Packet.DestinationAddress] |
139 | mov eax, [edx + IPv4_Packet.DestinationAddress] |
138 | mov edi, BROADCAST |
140 | mov edi, BROADCAST |
139 | mov ecx, MAX_IP+1 |
141 | mov ecx, MAX_IP+1 |
140 | repnz scasd |
142 | repnz scasd |
141 | jz .ip_ok |
143 | jz .ip_ok |
142 | 144 | ||
143 | not eax |
145 | not eax |
144 | test eax, 127 shl 24 ; 127.x.x.x |
146 | test eax, 127 shl 24 ; 127.x.x.x |
145 | jz .ip_ok |
147 | jz .ip_ok |
146 | 148 | ||
147 | ; TODO: we need to check for broadcasts (other then 255.255.255.255) |
149 | ; TODO: we need to check for broadcasts (other then 255.255.255.255) |
148 | 150 | ||
149 | jmp .dump |
151 | jmp .dump |
150 | 152 | ||
151 | .ip_ok: |
153 | .ip_ok: |
152 | call ETH_struc2dev ; TODO: make this work on other protocols too! |
154 | call ETH_struc2dev ; TODO: make this work on other protocols too! |
153 | inc [IP_PACKETS_RX+4*edi] |
155 | inc [IP_PACKETS_RX+4*edi] |
154 | DEBUGF 1,"IP_Handler - packet from %u.%u.%u.%u\n",\ |
156 | DEBUGF 1,"IP_Handler - packet from %u.%u.%u.%u\n",\ |
155 | [edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1 |
157 | [edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1 |
156 | 158 | ||
157 | mov al , [edx + IPv4_Packet.VersionAndIHL] |
159 | mov al , [edx + IPv4_Packet.VersionAndIHL] |
158 | and al , 0x0f ; get IHL(header length) |
160 | and al , 0x0f ; get IHL(header length) |
159 | cmp al , 0x05 ; IHL!= 5*4(20 bytes) |
161 | cmp al , 0x05 ; IHL!= 5*4(20 bytes) |
160 | jnz .dump ; TODO: dont dump packets wich have optional fiels !!! /!\ |
162 | jnz .dump ; TODO: dont dump packets wich have optional fiels !!! /!\ |
161 | 163 | ||
162 | cmp byte [edx + IPv4_Packet.TimeToLive], 0 |
164 | cmp byte [edx + IPv4_Packet.TimeToLive], 0 |
163 | je .dump |
165 | je .dump |
164 | 166 | ||
165 | movzx eax, word [edx + IPv4_Packet.FlagsAndFragmentOffset] |
167 | movzx eax, word [edx + IPv4_Packet.FlagsAndFragmentOffset] |
166 | xchg al , ah |
168 | xchg al , ah |
167 | 169 | ||
168 | test ax , 1 shl 13 ; Is 'more fragments' flag set ? |
170 | test ax , 1 shl 13 ; Is 'more fragments' flag set ? |
169 | jnz .yes_fragments ; If so, we definately have a fragmented packet |
171 | jnz .yes_fragments ; If so, we definately have a fragmented packet |
170 | 172 | ||
171 | test ax , 0x1fff ; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets |
173 | test ax , 0x1fff ; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets |
172 | jnz .last_fragment |
174 | jnz .last_fragment |
173 | 175 | ||
174 | .handle_it: ; We reach here if packet hasnt been fragmented, or when it already has been re-constructed |
176 | .handle_it: ; We reach here if packet hasnt been fragmented, or when it already has been re-constructed |
175 | movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
177 | movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
176 | and eax, 0x0000000F ; |
178 | and eax, 0x0000000F ; |
177 | shl eax, 2 ; |
179 | shl eax, 2 ; |
178 | 180 | ||
179 | movzx ecx, word [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet |
181 | movzx ecx, word [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet |
180 | xchg cl , ch ; |
182 | xchg cl , ch ; |
181 | sub ecx, eax ; |
183 | sub ecx, eax ; |
182 | 184 | ||
183 | add eax, edx |
185 | add eax, edx |
184 | push eax |
186 | push eax |
185 | mov al , [edx + IPv4_Packet.Protocol] |
187 | mov al , [edx + IPv4_Packet.Protocol] |
186 | pop edx ; Offset to data (tcp/udp/icmp/.. Packet) |
188 | pop edx ; Offset to data (tcp/udp/icmp/.. Packet) |
187 | 189 | ||
188 | cmp al , IP_PROTO_TCP |
190 | cmp al , IP_PROTO_TCP |
189 | ; je TCP_Handler |
191 | ; je TCP_handler |
190 | 192 | ||
191 | cmp al , IP_PROTO_UDP |
193 | cmp al , IP_PROTO_UDP |
192 | je UDP_Handler |
194 | je UDP_handler |
193 | 195 | ||
194 | cmp al , IP_PROTO_ICMP |
196 | cmp al , IP_PROTO_ICMP |
195 | je ICMP_Handler |
197 | je ICMP_handler |
196 | 198 | ||
197 | DEBUGF 1,"IP_Handler - unknown protocol:%u\n",al |
199 | DEBUGF 1,"IP_Handler - unknown protocol:%u\n",al |
198 | 200 | ||
199 | .dump: |
201 | .dump: |
200 | DEBUGF 1,"IP_Handler - done\n" |
202 | DEBUGF 1,"IP_Handler - done\n" |
201 | ; inc [dumped_rx_count] |
203 | ; inc [dumped_rx_count] |
202 | call kernel_free |
204 | call kernel_free |
203 | add esp, 4 ; pop (balance stack) |
205 | add esp, 4 ; pop (balance stack) |
204 | ret |
206 | ret |
205 | 207 | ||
206 | 208 | ||
207 | .yes_fragments: |
209 | .yes_fragments: |
208 | shl ax , 3 |
210 | shl ax , 3 |
209 | DEBUGF 1,"Fragmented packet, offset:%u, id:%x\n", ax, [edx + IPv4_Packet.Identification]:4 |
211 | DEBUGF 1,"Fragmented packet, offset:%u, id:%x\n", ax, [edx + IPv4_Packet.Identification]:4 |
210 | 212 | ||
211 | test ax , ax ; Is this the first packet of the fragment? |
213 | test ax , ax ; Is this the first packet of the fragment? |
212 | jnz .not_first_fragment |
214 | jnz .not_first_fragment |
213 | 215 | ||
214 | DEBUGF 1,"First fragmented packet received!\n" |
216 | DEBUGF 1,"First fragmented packet received!\n" |
215 | ; try to locate a free slot.. |
217 | ; try to locate a free slot.. |
216 | mov ecx, MAX_FRAGMENTS |
218 | mov ecx, MAX_FRAGMENTS |
217 | mov esi, FRAGMENT_LIST |
219 | mov esi, FRAGMENT_LIST |
218 | .find_free_slot: |
220 | .find_free_slot: |
219 | cmp word [esi + FRAGMENT_slot.ttl], 0 |
221 | cmp word [esi + FRAGMENT_slot.ttl], 0 |
220 | je .found_free_slot |
222 | je .found_free_slot |
221 | add esi, FRAGMENT_slot.size |
223 | add esi, FRAGMENT_slot.size |
222 | loop .find_free_slot |
224 | loop .find_free_slot |
223 | jmp .dump ; If no free slot was found, dump the packet |
225 | jmp .dump ; If no free slot was found, dump the packet |
224 | 226 | ||
225 | .found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure |
227 | .found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure |
226 | mov word [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl |
228 | mov word [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl |
227 | mov ax , word [edx + IPv4_Packet.Identification] |
229 | mov ax , word [edx + IPv4_Packet.Identification] |
228 | mov word [esi + FRAGMENT_slot.id], ax |
230 | mov word [esi + FRAGMENT_slot.id], ax |
229 | mov eax, dword [edx + IPv4_Packet.SourceAddress] |
231 | mov eax, dword [edx + IPv4_Packet.SourceAddress] |
230 | mov dword [esi + FRAGMENT_slot.SrcIP], eax |
232 | mov dword [esi + FRAGMENT_slot.SrcIP], eax |
231 | mov eax, dword [edx + IPv4_Packet.DestinationAddress] |
233 | mov eax, dword [edx + IPv4_Packet.DestinationAddress] |
232 | mov dword [esi + FRAGMENT_slot.DstIP], eax |
234 | mov dword [esi + FRAGMENT_slot.DstIP], eax |
233 | pop eax |
235 | pop eax |
234 | mov dword [esi + FRAGMENT_slot.ptr], eax |
236 | mov dword [esi + FRAGMENT_slot.ptr], eax |
235 | ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure |
237 | ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure |
236 | mov [eax + FRAGMENT_entry.NextPtr], -1 |
238 | mov [eax + FRAGMENT_entry.NextPtr], -1 |
237 | mov [eax + FRAGMENT_entry.PrevPtr], -1 |
239 | mov [eax + FRAGMENT_entry.PrevPtr], -1 |
238 | mov [eax + FRAGMENT_entry.Owner], ebx |
240 | mov [eax + FRAGMENT_entry.Owner], ebx |
239 | 241 | ||
240 | add esp, 4 ; balance stack and exit |
242 | add esp, 4 ; balance stack and exit |
241 | ret |
243 | ret |
242 | 244 | ||
243 | 245 | ||
244 | 246 | ||
245 | .not_first_fragment: |
247 | .not_first_fragment: |
246 | DEBUGF 1,"Middle fragmented packet received!\n" |
248 | DEBUGF 1,"Middle fragmented packet received!\n" |
247 | 249 | ||
248 | call .find_fragment_slot |
250 | call .find_fragment_slot |
249 | cmp esi, -1 |
251 | cmp esi, -1 |
250 | je .dump |
252 | je .dump |
251 | 253 | ||
252 | mov word [esi + FRAGMENT_slot.ttl], 15 ; Reset the ttl |
254 | mov word [esi + FRAGMENT_slot.ttl], 15 ; Reset the ttl |
253 | mov esi, [esi + FRAGMENT_slot.ptr] |
255 | mov esi, [esi + FRAGMENT_slot.ptr] |
254 | or edi, -1 |
256 | or edi, -1 |
255 | .find_last_entry: ; The following routine will try to find the last entry |
257 | .find_last_entry: ; The following routine will try to find the last entry |
256 | cmp edi, [esi + FRAGMENT_entry.PrevPtr] |
258 | cmp edi, [esi + FRAGMENT_entry.PrevPtr] |
257 | jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
259 | jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
258 | mov edi, esi |
260 | mov edi, esi |
259 | mov esi, [esi + FRAGMENT_entry.NextPtr] |
261 | mov esi, [esi + FRAGMENT_entry.NextPtr] |
260 | cmp esi, -1 |
262 | cmp esi, -1 |
261 | jne .find_last_entry |
263 | jne .find_last_entry |
262 | ; We found the last entry (pointer is noww in edi) |
264 | ; We found the last entry (pointer is noww in edi) |
263 | ; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure |
265 | ; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure |
264 | 266 | ||
265 | pop eax ; pointer to packet |
267 | pop eax ; pointer to packet |
266 | mov [edi + FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry |
268 | mov [edi + FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry |
267 | mov [eax + FRAGMENT_entry.NextPtr], -1 |
269 | mov [eax + FRAGMENT_entry.NextPtr], -1 |
268 | mov [eax + FRAGMENT_entry.PrevPtr], edi |
270 | mov [eax + FRAGMENT_entry.PrevPtr], edi |
269 | mov [eax + FRAGMENT_entry.Owner], ebx |
271 | mov [eax + FRAGMENT_entry.Owner], ebx |
270 | 272 | ||
271 | add esp, 4 |
273 | add esp, 4 |
272 | ret |
274 | ret |
273 | 275 | ||
274 | 276 | ||
275 | 277 | ||
276 | .last_fragment: |
278 | .last_fragment: |
277 | DEBUGF 1,"Last fragmented packet received!\n" |
279 | DEBUGF 1,"Last fragmented packet received!\n" |
278 | call .find_fragment_slot |
280 | call .find_fragment_slot |
279 | cmp esi, -1 |
281 | cmp esi, -1 |
280 | je .dump |
282 | je .dump |
281 | 283 | ||
282 | 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 |
284 | 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 |
283 | push esi |
285 | push esi |
284 | xor eax, eax ; |
286 | xor eax, eax ; |
285 | or edi, -1 |
287 | or edi, -1 |
286 | .count_bytes: |
288 | .count_bytes: |
287 | cmp [esi + FRAGMENT_entry.PrevPtr], edi |
289 | cmp [esi + FRAGMENT_entry.PrevPtr], edi |
288 | jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
290 | jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
289 | mov cx, word [esi + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Add total length |
291 | mov cx, word [esi + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Add total length |
290 | xchg cl, ch |
292 | xchg cl, ch |
291 | DEBUGF 1,"Packet size: %u\n", cx |
293 | DEBUGF 1,"Packet size: %u\n", cx |
292 | add ax, cx |
294 | add ax, cx |
293 | movzx cx, byte [esi + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Sub Header length |
295 | movzx cx, byte [esi + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Sub Header length |
294 | and cx, 0x000F |
296 | and cx, 0x000F |
295 | shl cx, 2 |
297 | shl cx, 2 |
296 | DEBUGF 1,"Header size: %u\n", cx |
298 | DEBUGF 1,"Header size: %u\n", cx |
297 | sub ax, cx |
299 | sub ax, cx |
298 | mov edi, esi |
300 | mov edi, esi |
299 | mov esi, [esi + FRAGMENT_entry.NextPtr] |
301 | mov esi, [esi + FRAGMENT_entry.NextPtr] |
300 | cmp esi, -1 |
302 | cmp esi, -1 |
301 | jne .count_bytes |
303 | jne .count_bytes |
302 | 304 | ||
303 | mov esi, [esp+4] ;;; |
305 | mov esi, [esp+4] ;;; |
304 | mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code |
306 | mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code |
305 | mov [esi + FRAGMENT_entry.NextPtr], -1 |
307 | mov [esi + FRAGMENT_entry.NextPtr], -1 |
306 | mov [esi + FRAGMENT_entry.PrevPtr], edi |
308 | mov [esi + FRAGMENT_entry.PrevPtr], edi |
307 | mov [esi + FRAGMENT_entry.Owner], ebx |
309 | mov [esi + FRAGMENT_entry.Owner], ebx |
308 | 310 | ||
309 | mov cx, [edx + IPv4_Packet.TotalLength] ; Note: This time we dont substract Header length |
311 | mov cx, [edx + IPv4_Packet.TotalLength] ; Note: This time we dont substract Header length |
310 | xchg cl , ch |
312 | xchg cl , ch |
311 | DEBUGF 1,"Packet size: %u\n", cx |
313 | DEBUGF 1,"Packet size: %u\n", cx |
312 | add ax , cx |
314 | add ax , cx |
313 | DEBUGF 1,"Total Received data size: %u\n", eax |
315 | DEBUGF 1,"Total Received data size: %u\n", eax |
314 | 316 | ||
315 | push eax |
317 | push eax |
316 | mov ax , [edx + IPv4_Packet.FlagsAndFragmentOffset] |
318 | mov ax , [edx + IPv4_Packet.FlagsAndFragmentOffset] |
317 | xchg al , ah |
319 | xchg al , ah |
318 | shl ax , 3 |
320 | shl ax , 3 |
319 | add cx , ax |
321 | add cx , ax |
320 | pop eax |
322 | pop eax |
321 | DEBUGF 1,"Total Fragment size: %u\n", ecx |
323 | DEBUGF 1,"Total Fragment size: %u\n", ecx |
322 | 324 | ||
323 | cmp ax, cx |
325 | cmp ax, cx |
324 | jne .destroy_slot_pop |
326 | jne .destroy_slot_pop |
325 | 327 | ||
326 | push eax |
328 | push eax |
327 | push eax |
329 | push eax |
328 | call kernel_alloc |
330 | call kernel_alloc |
329 | test eax, eax |
331 | test eax, eax |
330 | je .destroy_slot_pop ; If we dont have enough space to allocate the buffer, discard all packets in slot |
332 | je .destroy_slot_pop ; If we dont have enough space to allocate the buffer, discard all packets in slot |
331 | mov edx, [esp+4] ; Get pointer to first fragment entry back in edx |
333 | mov edx, [esp+4] ; Get pointer to first fragment entry back in edx |
332 | 334 | ||
333 | .rebuild_packet_loop: |
335 | .rebuild_packet_loop: |
334 | movzx ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.FlagsAndFragmentOffset] ; Calculate the fragment offset |
336 | movzx ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.FlagsAndFragmentOffset] ; Calculate the fragment offset |
335 | xchg cl , ch ; intel byte order |
337 | xchg cl , ch ; intel byte order |
336 | shl cx , 3 ; multiply by 8 and clear first 3 bits |
338 | shl cx , 3 ; multiply by 8 and clear first 3 bits |
337 | DEBUGF 1,"Fragment offset: %u\n", cx |
339 | DEBUGF 1,"Fragment offset: %u\n", cx |
338 | 340 | ||
339 | lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment |
341 | lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment |
340 | movzx ebx, byte [edx + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Find header size (in ebx) of fragment |
342 | movzx ebx, byte [edx + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL] ; Find header size (in ebx) of fragment |
341 | and bx , 0x000F ; |
343 | and bx , 0x000F ; |
342 | shl bx , 2 ; |
344 | shl bx , 2 ; |
343 | 345 | ||
344 | lea esi, [edx + FRAGMENT_entry.Data] ; Set esi to the correct begin of fragment |
346 | lea esi, [edx + FRAGMENT_entry.Data] ; Set esi to the correct begin of fragment |
345 | movzx ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Calculate total length of fragment |
347 | movzx ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] ; Calculate total length of fragment |
346 | xchg cl, ch ; intel byte order |
348 | xchg cl, ch ; intel byte order |
347 | 349 | ||
348 | cmp edi, eax ; Is this packet the first fragment ? |
350 | cmp edi, eax ; Is this packet the first fragment ? |
349 | je .first_fragment |
351 | je .first_fragment |
350 | sub cx, bx ; If not, dont copy the header |
352 | sub cx, bx ; If not, dont copy the header |
351 | add esi, ebx ; |
353 | add esi, ebx ; |
352 | .first_fragment: |
354 | .first_fragment: |
353 | 355 | ||
354 | push cx ; First copy dword-wise, then byte-wise |
356 | push cx ; First copy dword-wise, then byte-wise |
355 | shr cx, 2 ; |
357 | shr cx, 2 ; |
356 | rep movsd ; |
358 | rep movsd ; |
357 | pop cx ; |
359 | pop cx ; |
358 | and cx, 3 ; |
360 | and cx, 3 ; |
359 | rep movsb ; |
361 | rep movsb ; |
360 | 362 | ||
361 | push eax |
363 | push eax |
362 | push edx ; Push pointer to fragment onto stack |
364 | push edx ; Push pointer to fragment onto stack |
363 | mov edx, [edx + FRAGMENT_entry.NextPtr] ; Set edx to the next pointer |
365 | mov edx, [edx + FRAGMENT_entry.NextPtr] ; Set edx to the next pointer |
364 | call kernel_free ; free the previous fragment buffer (this uses the value from stack) |
366 | call kernel_free ; free the previous fragment buffer (this uses the value from stack) |
365 | pop eax |
367 | pop eax |
366 | cmp edx, -1 ; Check if it is last fragment in chain |
368 | cmp edx, -1 ; Check if it is last fragment in chain |
367 | jne .rebuild_packet_loop |
369 | jne .rebuild_packet_loop |
368 | 370 | ||
369 | pop ecx ; |
371 | pop ecx ; |
370 | xchg cl, ch |
372 | xchg cl, ch |
371 | mov edx, eax |
373 | mov edx, eax |
372 | mov word [edx + IPv4_Packet.TotalLength], cx |
374 | mov word [edx + IPv4_Packet.TotalLength], cx |
373 | add esp, 8 |
375 | add esp, 8 |
374 | 376 | ||
375 | xchg cl, ch ; This prints the IP packet to the debug board (usefull when using serial output debug..) |
377 | xchg cl, ch ; This prints the IP packet to the debug board (usefull when using serial output debug..) |
376 | push ecx ;;;; |
378 | push ecx ;;;; |
377 | push eax ;;;; |
379 | push eax ;;;; |
378 | ; mov esi, edx ; |
380 | ; mov esi, edx ; |
379 | ; ; |
381 | ; ; |
380 | ; @@: ; |
382 | ; @@: ; |
381 | ; lodsb ; |
383 | ; lodsb ; |
382 | ; DEBUGF 1,"%x ", eax:2 ; |
384 | ; DEBUGF 1,"%x ", eax:2 ; |
383 | ; loop @r ; |
385 | ; loop @r ; |
384 | 386 | ||
385 | movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
387 | movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
386 | and ax, 0x000F ; |
388 | and ax, 0x000F ; |
387 | shl ax, 2 ; |
389 | shl ax, 2 ; |
388 | sub ecx, eax ; |
390 | sub ecx, eax ; |
389 | add eax, edx |
391 | add eax, edx |
390 | push eax |
392 | push eax |
391 | mov al , [edx + IPv4_Packet.Protocol] |
393 | mov al , [edx + IPv4_Packet.Protocol] |
392 | pop edx ; Offset to data (tcp/udp/icmp/.. Packet) |
394 | pop edx ; Offset to data (tcp/udp/icmp/.. Packet) |
393 | 395 | ||
394 | ; cmp al , IP_PROTO_TCP |
396 | cmp al , IP_PROTO_TCP |
395 | ; je TCP_Handler |
397 | ; je TCP_handler |
396 | 398 | ||
397 | cmp al , IP_PROTO_UDP |
399 | cmp al , IP_PROTO_UDP |
398 | je UDP_Handler |
400 | je UDP_handler |
399 | 401 | ||
400 | cmp al , IP_PROTO_ICMP |
402 | cmp al , IP_PROTO_ICMP |
401 | je ICMP_Handler_fragments |
403 | je ICMP_handler_fragments |
402 | 404 | ||
403 | DEBUGF 1,"IP_Handler - unknown protocol:%u\n",al |
405 | DEBUGF 1,"IP_Handler - unknown protocol:%u\n",al |
404 | 406 | ||
405 | call kernel_free |
407 | call kernel_free |
406 | add esp, 8 ; pop (balance stack) |
408 | add esp, 8 ; pop (balance stack) |
407 | 409 | ||
408 | ret |
410 | ret |
409 | 411 | ||
410 | 412 | ||
411 | .destroy_slot_pop: |
413 | .destroy_slot_pop: |
412 | add esp, 4 |
414 | add esp, 4 |
413 | .destroy_slot: |
415 | .destroy_slot: |
414 | DEBUGF 1,"Destroy fragment slot!\n" |
416 | DEBUGF 1,"Destroy fragment slot!\n" |
415 | ; TODO! |
417 | ; TODO! |
416 | jmp .dump |
418 | jmp .dump |
417 | 419 | ||
418 | 420 | ||
419 | 421 | ||
420 | ;----------------------------------------------------------------- |
422 | ;----------------------------------------------------------------- |
421 | ; |
423 | ; |
422 | ; find fragment slot |
424 | ; find fragment slot |
423 | ; |
425 | ; |
424 | ; IN: pointer to fragmented packet in edx ; TODO: the RFC says we should check protocol too |
426 | ; IN: pointer to fragmented packet in edx ; TODO: the RFC says we should check protocol too |
425 | ; OUT: pointer to slot in edi, -1 on error |
427 | ; OUT: pointer to slot in edi, -1 on error |
426 | ; |
428 | ; |
427 | ;----------------------------------------------------------------- |
429 | ;----------------------------------------------------------------- |
428 | 430 | ||
429 | .find_fragment_slot: |
431 | .find_fragment_slot: |
430 | 432 | ||
431 | push eax ebx ecx edx |
433 | push eax ebx ecx edx |
432 | mov ax , word [edx + IPv4_Packet.Identification] |
434 | mov ax , word [edx + IPv4_Packet.Identification] |
433 | mov ecx, MAX_FRAGMENTS |
435 | mov ecx, MAX_FRAGMENTS |
434 | mov esi, FRAGMENT_LIST |
436 | mov esi, FRAGMENT_LIST |
435 | mov ebx, dword [edx + IPv4_Packet.SourceAddress] |
437 | mov ebx, dword [edx + IPv4_Packet.SourceAddress] |
436 | mov edx, dword [edx + IPv4_Packet.DestinationAddress] |
438 | mov edx, dword [edx + IPv4_Packet.DestinationAddress] |
437 | .find_slot: |
439 | .find_slot: |
438 | cmp word [esi + FRAGMENT_slot.id], ax |
440 | cmp word [esi + FRAGMENT_slot.id], ax |
439 | jne .try_next |
441 | jne .try_next |
440 | cmp dword [esi + FRAGMENT_slot.SrcIP], ebx |
442 | cmp dword [esi + FRAGMENT_slot.SrcIP], ebx |
441 | jne .try_next |
443 | jne .try_next |
442 | cmp dword [esi + FRAGMENT_slot.DstIP], edx |
444 | cmp dword [esi + FRAGMENT_slot.DstIP], edx |
443 | je .found_slot |
445 | je .found_slot |
444 | .try_next: |
446 | .try_next: |
445 | add esi, FRAGMENT_slot.size |
447 | add esi, FRAGMENT_slot.size |
446 | loop .find_slot |
448 | loop .find_slot |
447 | ; pop edx ebx |
449 | ; pop edx ebx |
448 | or esi, -1 |
450 | or esi, -1 |
449 | ; ret |
451 | ; ret |
450 | 452 | ||
451 | .found_slot: |
453 | .found_slot: |
452 | pop edx ecx ebx eax |
454 | pop edx ecx ebx eax |
453 | ret |
455 | ret |
454 | 456 | ||
455 | 457 | ||
456 | ;----------------------------------------------------------------- |
458 | ;----------------------------------------------------------------- |
457 | ; |
459 | ; |
458 | ; Decrease TimeToLive of all fragment slots |
460 | ; Decrease TimeToLive of all fragment slots |
459 | ; |
461 | ; |
460 | ; IN: / |
462 | ; IN: / |
461 | ; OUT: / |
463 | ; OUT: / |
462 | ; |
464 | ; |
463 | ;----------------------------------------------------------------- |
465 | ;----------------------------------------------------------------- |
464 | 466 | ||
465 | align 4 |
467 | align 4 |
466 | IPv4_decrease_fragment_ttls: |
468 | IPv4_decrease_fragment_ttls: |
467 | 469 | ||
468 | mov esi, FRAGMENT_LIST |
470 | mov esi, FRAGMENT_LIST |
469 | mov ecx, MAX_FRAGMENTS |
471 | mov ecx, MAX_FRAGMENTS |
470 | .loop: |
472 | .loop: |
471 | cmp [esi + FRAGMENT_slot.ttl], 0 |
473 | cmp [esi + FRAGMENT_slot.ttl], 0 |
472 | je .try_next |
474 | je .try_next |
473 | dec [esi + FRAGMENT_slot.ttl] |
475 | dec [esi + FRAGMENT_slot.ttl] |
474 | jnz .try_next |
476 | jnz .try_next |
475 | DEBUGF 1,"Fragment slot timed-out!\n" |
477 | DEBUGF 1,"Fragment slot timed-out!\n" |
476 | ; TODO: clear all entry's of timed-out slot |
478 | ; TODO: clear all entry's of timed-out slot |
477 | .try_next: |
479 | .try_next: |
478 | add esi, 4 |
480 | add esi, 4 |
479 | loop .loop |
481 | loop .loop |
480 | ret |
482 | ret |
481 | 483 | ||
482 | 484 | ||
483 | 485 | ||
484 | 486 | ||
485 | 487 | ||
486 | ;----------------------------------------------------------------- |
488 | ;----------------------------------------------------------------- |
487 | ; |
489 | ; |
488 | ; Create_IPv4_Packet |
490 | ; Create_IPv4_Packet |
489 | ; |
491 | ; |
490 | ; IN: eax = dest ip |
492 | ; IN: eax = dest ip |
491 | ; ebx = source ip |
493 | ; ebx = source ip |
492 | ; ecx = data length |
494 | ; ecx = data length |
493 | ; dx = fragment id |
495 | ; dx = fragment id |
494 | ; di = protocol |
496 | ; di = protocol |
495 | ; |
497 | ; |
496 | ; OUT: eax points to buffer start |
498 | ; OUT: eax points to buffer start |
497 | ; ebx is size of complete buffer |
499 | ; ebx is size of complete buffer |
498 | ; edi = pointer to start of data (-1 on error) |
500 | ; edi = pointer to start of data (-1 on error) |
499 | ; ecx = unchanged (packet size of embedded data) |
501 | ; ecx = unchanged (packet size of embedded data) |
500 | ; edx = pointer to device struct (needed for sending procedure) |
502 | ; edx = pointer to device struct (needed for sending procedure) |
501 | ; esi = pointer to sending procedure |
503 | ; esi = pointer to sending procedure |
502 | ; |
504 | ; |
503 | ;----------------------------------------------------------------- |
505 | ;----------------------------------------------------------------- |
504 | 506 | ||
505 | ;;; TODO: create fragmented packets |
507 | ;;; TODO: create fragmented packets |
506 | 508 | ||
507 | align 4 |
509 | align 4 |
508 | IPv4_create_Packet: |
510 | IPv4_create_packet: |
509 | 511 | ||
510 | DEBUGF 1,"Create IPv4 Packet\n" |
512 | DEBUGF 1,"Create IPv4 Packet\n" |
511 | 513 | ||
512 | cmp ecx, 1514 |
514 | cmp ecx, 1514 |
513 | jg .exit_ |
515 | jg .exit_ |
514 | 516 | ||
515 | cmp eax, -1 |
517 | cmp eax, -1 |
516 | je .broadcast ; If it is broadcast, just send |
518 | je .broadcast ; If it is broadcast, just send |
517 | - | ||
518 | push eax |
- | |
519 | stdcall arp_table_manager, ARP_TABLE_IP_TO_MAC, eax, temp_dstmac ;opcode,IP,MAC_ptr - Get the MAC address. |
519 | |
- | 520 | call ARP_IP_to_MAC |
|
520 | cmp eax, ARP_NO_ENTRY |
521 | |
521 | pop eax |
522 | cmp eax, -1 |
522 | jne .send |
523 | jne .found |
523 | 524 | ||
524 | DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n" |
525 | DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n" |
525 | 526 | ||
526 | ; TODO: QUEUE! |
527 | ; TODO: QUEUE! |
527 | or edi, -1 |
528 | or edi, -1 |
528 | 529 | ||
529 | ret |
530 | ret |
- | 531 | ||
- | 532 | .found: |
|
- | 533 | push ax |
|
- | 534 | push ebx |
|
- | 535 | ||
- | 536 | jmp .send |
|
530 | 537 | ||
531 | .broadcast: |
538 | .broadcast: |
532 | mov dword [temp_dstmac], -1 |
539 | push word -1 |
533 | mov word [temp_dstmac+4], -1 |
540 | push dword -1 |
534 | 541 | ||
535 | 542 | ||
536 | .send: |
543 | .send: |
537 | push ecx eax ebx dx di |
544 | push ecx eax ebx dx di |
538 | call IPv4_dest_to_dev |
545 | call IPv4_dest_to_dev |
539 | inc [IP_PACKETS_TX+4*edi] |
546 | inc [IP_PACKETS_TX+4*edi] |
540 | mov edi, [ETH_DRV_LIST + 4*edi] |
547 | mov edi, [ETH_DRV_LIST + 4*edi] |
541 | lea eax, [edi + ETH_DEVICE.mac] |
548 | lea eax, [edi + ETH_DEVICE.mac] |
542 | mov ebx, temp_dstmac |
549 | lea ebx, [esp+16] |
543 | mov ecx, [esp+12] |
550 | mov ecx, [esp+12] |
544 | add ecx, IPv4_Packet.DataOrOptional |
551 | add ecx, IPv4_Packet.DataOrOptional |
- | 552 | mov edx, edi ;;; |
|
545 | mov di , ETHER_IPv4 |
553 | mov di , ETHER_IPv4 |
546 | call ETH_create_Packet ; TODO: figure out a way to make this work with other protocols too |
554 | call ETH_create_Packet ; TODO: figure out a way to make this work with other protocols too |
547 | cmp edi, -1 |
555 | cmp edi, -1 |
548 | je .exit |
556 | je .exit |
549 | 557 | ||
550 | mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) |
558 | mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) |
551 | mov [edi + IPv4_Packet.TypeOfService], 0 |
559 | mov [edi + IPv4_Packet.TypeOfService], 0 |
552 | xchg ch, cl |
560 | xchg ch, cl |
553 | mov [edi + IPv4_Packet.TotalLength], cx |
561 | mov [edi + IPv4_Packet.TotalLength], cx |
554 | mov [edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000 |
562 | mov [edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000 |
555 | mov [edi + IPv4_Packet.TimeToLive], 128 |
563 | mov [edi + IPv4_Packet.TimeToLive], 128 |
556 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
564 | mov [edi + IPv4_Packet.HeaderChecksum], 0 |
557 | pop cx |
565 | pop cx |
558 | mov [edi + IPv4_Packet.Protocol], cl |
566 | mov [edi + IPv4_Packet.Protocol], cl |
559 | pop cx |
567 | pop cx |
560 | mov [edi + IPv4_Packet.Identification], cx |
568 | mov [edi + IPv4_Packet.Identification], cx |
561 | pop ecx |
569 | pop ecx |
562 | mov [edi + IPv4_Packet.SourceAddress], ecx |
570 | mov [edi + IPv4_Packet.SourceAddress], ecx |
563 | pop ecx |
571 | pop ecx |
564 | mov [edi + IPv4_Packet.DestinationAddress], ecx |
572 | mov [edi + IPv4_Packet.DestinationAddress], ecx |
565 | 573 | ||
566 | push eax |
574 | push eax |
567 | stdcall checksum_jb, edi, IPv4_Packet.DataOrOptional ; buf_ptr, buf_size |
575 | stdcall checksum_jb, edi, IPv4_Packet.DataOrOptional ; buf_ptr, buf_size |
568 | xchg al, ah |
576 | xchg al, ah |
569 | mov [edi + IPv4_Packet.HeaderChecksum], ax |
577 | mov [edi + IPv4_Packet.HeaderChecksum], ax |
570 | pop eax ecx |
578 | pop eax ecx |
571 | add edi, IPv4_Packet.DataOrOptional |
579 | add edi, IPv4_Packet.DataOrOptional |
572 | 580 | ||
573 | DEBUGF 1,"IPv4 Packet for device %x created successfully\n", edx |
581 | DEBUGF 1,"IPv4 Packet for device %x created successfully\n", edx |
- | 582 | ||
- | 583 | add esp, 6 |
|
574 | 584 | ||
575 | ret |
585 | ret |
576 | 586 | ||
577 | .exit: |
587 | .exit: |
578 | add esp, 16 |
588 | add esp, 16+6 |
579 | .exit_: |
589 | .exit_: |
580 | DEBUGF 1,"Create IPv4 Packet - failed\n" |
590 | DEBUGF 1,"Create IPv4 Packet - failed\n" |
581 | or edi, -1 |
591 | or edi, -1 |
582 | ret |
592 | ret |
583 | 593 | ||
584 | - | ||
585 | uglobal |
- | |
586 | temp_dstmac dp ? ; TODO: place this in stack instead! |
- | |
587 | endg |
- | |
588 | 594 | ||
589 | 595 | ||
590 | ;--------------------------------------------------------------------------- |
596 | ;--------------------------------------------------------------------------- |
591 | ; |
597 | ; |
592 | ; IPv4_dest_to_dev |
598 | ; IPv4_dest_to_dev |
593 | ; |
599 | ; |
594 | ; IN: Destination IP in eax |
600 | ; IN: Destination IP in eax |
595 | ; OUT: device id in edi |
601 | ; OUT: device id in edi |
596 | ; |
602 | ; |
597 | ;--------------------------------------------------------------------------- |
603 | ;--------------------------------------------------------------------------- |
598 | 604 | ||
599 | align 4 |
605 | align 4 |
600 | IPv4_dest_to_dev: |
606 | IPv4_dest_to_dev: |
601 | 607 | ||
602 | DEBUGF 1,"IPv4 destination to device: " |
608 | DEBUGF 1,"IPv4 destination to device: " |
603 | 609 | ||
604 | xor edi, edi |
610 | xor edi, edi |
605 | mov ecx, MAX_IP |
611 | mov ecx, MAX_IP |
606 | 612 | ||
607 | .loop: |
613 | .loop: |
608 | mov ebx, [IP_LIST+edi] ; we dont need to worry about non exisiting ip interfaces |
614 | mov ebx, [IP_LIST+edi] ; we dont need to worry about non exisiting ip interfaces |
609 | and ebx, [SUBNET_LIST+edi] ; they have IP and SUBNET set to all one's, so they will have no match except 255.255.255.255 |
615 | and ebx, [SUBNET_LIST+edi] ; they have IP and SUBNET set to all one's, so they will have no match except 255.255.255.255 |
610 | ; (only a moron would insert that ip into this function..) |
616 | ; (only a moron would insert that ip into this function..) |
611 | mov edx, eax |
617 | mov edx, eax |
612 | and edx, [SUBNET_LIST+edi] |
618 | and edx, [SUBNET_LIST+edi] |
613 | 619 | ||
614 | cmp ebx, edx |
620 | cmp ebx, edx |
615 | je .found_it |
621 | je .found_it |
616 | 622 | ||
617 | add edi, 4 |
623 | add edi, 4 |
618 | loop .loop |
624 | loop .loop |
619 | 625 | ||
620 | xor edi, edi ; if none found, use device 0 as default device |
626 | xor edi, edi ; if none found, use device 0 as default device |
621 | 627 | ||
622 | .found_it: |
628 | .found_it: |
623 | shr edi, 2 |
629 | shr edi, 2 |
624 | 630 | ||
625 | DEBUGF 1,"%u\n",edi |
631 | DEBUGF 1,"%u\n",edi |
626 | 632 | ||
627 | ret |
633 | ret |
628 | 634 | ||
629 | 635 | ||
630 | 636 | ||
631 | ;--------------------------------------------------------------------------- |
637 | ;--------------------------------------------------------------------------- |
632 | ; |
638 | ; |
633 | ; IPv4_get_frgmnt_num |
639 | ; IPv4_get_frgmnt_num |
634 | ; |
640 | ; |
635 | ; IN: / |
641 | ; IN: / |
636 | ; OUT: fragment number in ax |
642 | ; OUT: fragment number in ax |
637 | ; |
643 | ; |
638 | ;--------------------------------------------------------------------------- |
644 | ;--------------------------------------------------------------------------- |
639 | 645 | ||
640 | align 4 |
646 | align 4 |
641 | IPv4_get_frgmnt_num: |
647 | IPv4_get_frgmnt_num: |
642 | xor ax, ax ;;; TODO: replace this with real code |
648 | xor ax, ax ;;; TODO: replace this with real code |
643 | 649 | ||
644 | ret |
650 | ret |
645 | 651 | ||
646 | 652 | ||
647 | ;--------------------------------------------------------------------------- |
653 | ;--------------------------------------------------------------------------- |
648 | ; |
654 | ; |
649 | ; IPv4_API |
655 | ; IPv4_API |
650 | ; |
656 | ; |
651 | ; This function is called by system function 75 |
657 | ; This function is called by system function 75 |
652 | ; |
658 | ; |
653 | ; IN: subfunction number in bl |
659 | ; IN: subfunction number in bl |
654 | ; device number in bh |
660 | ; device number in bh |
655 | ; ecx, edx, .. depends on subfunction |
661 | ; ecx, edx, .. depends on subfunction |
656 | ; |
662 | ; |
657 | ; OUT: |
663 | ; OUT: |
658 | ; |
664 | ; |
659 | ;--------------------------------------------------------------------------- |
665 | ;--------------------------------------------------------------------------- |
660 | 666 | ||
661 | align 4 |
667 | align 4 |
662 | IPv4_API: |
668 | IPv4_API: |
663 | 669 | ||
664 | movzx eax, bh |
670 | movzx eax, bh |
665 | shl eax, 2 |
671 | shl eax, 2 |
666 | 672 | ||
667 | test bl, bl |
673 | test bl, bl |
668 | jz .packets_tx ; 0 |
674 | jz .packets_tx ; 0 |
669 | dec bl |
675 | dec bl |
670 | jz .packets_rx ; 1 |
676 | jz .packets_rx ; 1 |
671 | dec bl |
677 | dec bl |
672 | jz .read_ip ; 2 |
678 | jz .read_ip ; 2 |
673 | dec bl |
679 | dec bl |
674 | jz .write_ip ; 3 |
680 | jz .write_ip ; 3 |
675 | dec bl |
681 | dec bl |
676 | jz .read_dns ; 4 |
682 | jz .read_dns ; 4 |
677 | dec bl |
683 | dec bl |
678 | jz .write_dns ; 5 |
684 | jz .write_dns ; 5 |
679 | dec bl |
685 | dec bl |
680 | jz .read_subnet ; 6 |
686 | jz .read_subnet ; 6 |
681 | dec bl |
687 | dec bl |
682 | jz .write_subnet ; 7 |
688 | jz .write_subnet ; 7 |
683 | dec bl |
689 | dec bl |
684 | jz .read_gateway ; 8 |
690 | jz .read_gateway ; 8 |
685 | dec bl |
691 | dec bl |
686 | jz .write_gateway ; 9 |
692 | jz .write_gateway ; 9 |
687 | 693 | ||
688 | .error: |
694 | .error: |
689 | mov eax, -1 |
695 | mov eax, -1 |
690 | ret |
696 | ret |
691 | 697 | ||
692 | .packets_tx: |
698 | .packets_tx: |
693 | add eax, IP_PACKETS_TX |
699 | add eax, IP_PACKETS_TX |
694 | mov eax, [eax] |
700 | mov eax, [eax] |
695 | ret |
701 | ret |
696 | 702 | ||
697 | .packets_rx: |
703 | .packets_rx: |
698 | add eax, IP_PACKETS_RX |
704 | add eax, IP_PACKETS_RX |
699 | mov eax, [eax] |
705 | mov eax, [eax] |
700 | ret |
706 | ret |
701 | 707 | ||
702 | .read_ip: |
708 | .read_ip: |
703 | add eax, IP_LIST |
709 | add eax, IP_LIST |
704 | mov eax, [eax] |
710 | mov eax, [eax] |
705 | ret |
711 | ret |
706 | 712 | ||
707 | .write_ip: |
713 | .write_ip: |
708 | add eax, IP_LIST |
714 | add eax, IP_LIST |
709 | mov [eax], ecx |
715 | mov [eax], ecx |
710 | xor eax, eax |
716 | xor eax, eax |
711 | ret |
717 | ret |
712 | 718 | ||
713 | .read_dns: |
719 | .read_dns: |
714 | add eax, DNS_LIST |
720 | add eax, DNS_LIST |
715 | mov eax, [eax] |
721 | mov eax, [eax] |
716 | ret |
722 | ret |
717 | 723 | ||
718 | .write_dns: |
724 | .write_dns: |
719 | add eax, DNS_LIST |
725 | add eax, DNS_LIST |
720 | mov [eax], ecx |
726 | mov [eax], ecx |
721 | xor eax, eax |
727 | xor eax, eax |
722 | ret |
728 | ret |
723 | 729 | ||
724 | .read_subnet: |
730 | .read_subnet: |
725 | add eax, SUBNET_LIST |
731 | add eax, SUBNET_LIST |
726 | mov eax, [eax] |
732 | mov eax, [eax] |
727 | ret |
733 | ret |
728 | 734 | ||
729 | .write_subnet: |
735 | .write_subnet: |
730 | add eax, SUBNET_LIST |
736 | add eax, SUBNET_LIST |
731 | mov [eax], ecx |
737 | mov [eax], ecx |
732 | xor eax, eax |
738 | xor eax, eax |
733 | ret |
739 | ret |
734 | 740 | ||
735 | .read_gateway: |
741 | .read_gateway: |
736 | add eax, GATEWAY_LIST |
742 | add eax, GATEWAY_LIST |
737 | mov eax, [eax] |
743 | mov eax, [eax] |
738 | ret |
744 | ret |
739 | 745 | ||
740 | .write_gateway: |
746 | .write_gateway: |
741 | add eax, GATEWAY_LIST |
747 | add eax, GATEWAY_LIST |
742 | mov [eax], ecx |
748 | mov [eax], ecx |
743 | xor eax, eax |
749 | xor eax, eax |
744 | ret |
750 | ret |