Rev 3698 | Rev 3861 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3545 | hidnplayr | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
3 | ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; |
||
4 | ;; Distributed under terms of the GNU General Public License ;; |
||
5 | ;; ;; |
||
6 | ;; IPv4.INC ;; |
||
7 | ;; ;; |
||
8 | ;; Part of the TCP/IP network stack for KolibriOS ;; |
||
9 | ;; ;; |
||
10 | ;; Based on the work of [Johnny_B] and [smb] ;; |
||
11 | ;; ;; |
||
12 | ;; Written by hidnplayr@kolibrios.org ;; |
||
13 | ;; ;; |
||
14 | ;; GNU GENERAL PUBLIC LICENSE ;; |
||
15 | ;; Version 2, June 1991 ;; |
||
16 | ;; ;; |
||
17 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
18 | |||
19 | $Revision: 3515 $ |
||
20 | |||
21 | MAX_FRAGMENTS = 64 |
||
22 | |||
23 | struct IPv4_header |
||
24 | |||
25 | VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] |
||
26 | TypeOfService db ? ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0] |
||
27 | TotalLength dw ? |
||
28 | Identification dw ? |
||
29 | FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15] |
||
30 | TimeToLive db ? ; |
||
31 | Protocol db ? |
||
32 | HeaderChecksum dw ? |
||
33 | SourceAddress dd ? |
||
34 | DestinationAddress dd ? |
||
35 | |||
36 | ends |
||
37 | |||
38 | struct FRAGMENT_slot |
||
39 | |||
40 | ttl dw ? ; Time to live for this entry, 0 for empty slot's |
||
41 | id dw ? ; Identification field from IP header |
||
42 | SrcIP dd ? ; .. from IP header |
||
43 | DstIP dd ? ; .. from IP header |
||
44 | ptr dd ? ; Pointer to first packet |
||
45 | |||
46 | ends |
||
47 | |||
48 | struct FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets |
||
49 | |||
50 | PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet) |
||
51 | NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet) |
||
52 | Owner dd ? ; Pointer to structure of driver |
||
53 | rb 2 ; to match ethernet header size ;;; FIXME |
||
54 | ; Ip header begins here (we will need the IP header to re-construct the complete packet) |
||
55 | ends |
||
56 | |||
57 | |||
3698 | hidnplayr | 58 | uglobal |
3545 | hidnplayr | 59 | align 4 |
60 | |||
3600 | hidnplayr | 61 | IP_LIST rd NET_DEVICES_MAX |
62 | SUBNET_LIST rd NET_DEVICES_MAX |
||
63 | DNS_LIST rd NET_DEVICES_MAX |
||
64 | GATEWAY_LIST rd NET_DEVICES_MAX |
||
65 | BROADCAST_LIST rd NET_DEVICES_MAX |
||
3545 | hidnplayr | 66 | |
3600 | hidnplayr | 67 | IP_packets_tx rd NET_DEVICES_MAX |
68 | IP_packets_rx rd NET_DEVICES_MAX |
||
69 | IP_packets_dumped rd NET_DEVICES_MAX |
||
3545 | hidnplayr | 70 | |
3600 | hidnplayr | 71 | FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot |
3698 | hidnplayr | 72 | |
3545 | hidnplayr | 73 | endg |
74 | |||
75 | |||
76 | ;----------------------------------------------------------------- |
||
77 | ; |
||
78 | ; IPv4_init |
||
79 | ; |
||
80 | ; This function resets all IP variables |
||
81 | ; |
||
82 | ;----------------------------------------------------------------- |
||
83 | macro IPv4_init { |
||
84 | |||
85 | xor eax, eax |
||
86 | mov edi, IP_LIST |
||
3600 | hidnplayr | 87 | mov ecx, 7*NET_DEVICES_MAX + (sizeof.FRAGMENT_slot*MAX_FRAGMENTS)/4 |
3711 | clevermous | 88 | rep stosd |
3545 | hidnplayr | 89 | |
90 | } |
||
91 | |||
92 | |||
93 | ;----------------------------------------------------------------- |
||
94 | ; |
||
95 | ; Decrease TimeToLive of all fragment slots |
||
96 | ; |
||
97 | ;----------------------------------------------------------------- |
||
98 | macro IPv4_decrease_fragment_ttls { |
||
99 | |||
100 | local .loop, .next |
||
101 | |||
102 | mov esi, FRAGMENT_LIST |
||
103 | mov ecx, MAX_FRAGMENTS |
||
104 | .loop: |
||
105 | cmp [esi + FRAGMENT_slot.ttl], 0 |
||
106 | je .next |
||
107 | dec [esi + FRAGMENT_slot.ttl] |
||
108 | jz .died |
||
109 | .next: |
||
110 | add esi, sizeof.FRAGMENT_slot |
||
111 | dec ecx |
||
112 | jnz .loop |
||
113 | jmp .done |
||
114 | |||
115 | .died: |
||
3556 | hidnplayr | 116 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4 Fragment slot timed-out!\n" |
3545 | hidnplayr | 117 | ;;; TODO: clear all entry's of timed-out slot |
118 | jmp .next |
||
119 | |||
120 | .done: |
||
121 | } |
||
122 | |||
123 | |||
124 | |||
125 | macro IPv4_checksum ptr { |
||
126 | |||
127 | ; This is the fast procedure to create or check an IP header without options |
||
128 | ; To create a new checksum, the checksum field must be set to 0 before computation |
||
129 | ; To check an existing checksum, leave the checksum as is, and it will be 0 after this procedure, if it was correct |
||
130 | |||
131 | push ebx |
||
132 | xor ebx, ebx |
||
133 | add bl, [ptr+1] |
||
134 | adc bh, [ptr+0] |
||
135 | |||
136 | adc bl, [ptr+3] |
||
137 | adc bh, [ptr+2] |
||
138 | |||
139 | adc bl, [ptr+5] |
||
140 | adc bh, [ptr+4] |
||
141 | |||
142 | adc bl, [ptr+7] |
||
143 | adc bh, [ptr+6] |
||
144 | |||
145 | adc bl, [ptr+9] |
||
146 | adc bh, [ptr+8] |
||
147 | |||
148 | ; we skip 11th and 12th byte, they are the checksum bytes and should be 0 for re-calculation |
||
149 | |||
150 | adc bl, [ptr+13] |
||
151 | adc bh, [ptr+12] |
||
152 | |||
153 | adc bl, [ptr+15] |
||
154 | adc bh, [ptr+14] |
||
155 | |||
156 | adc bl, [ptr+17] |
||
157 | adc bh, [ptr+16] |
||
158 | |||
159 | adc bl, [ptr+19] |
||
160 | adc bh, [ptr+18] |
||
161 | |||
162 | adc ebx, 0 |
||
163 | |||
164 | push ecx |
||
165 | mov ecx, ebx |
||
166 | shr ecx, 16 |
||
167 | and ebx, 0xffff |
||
168 | add ebx, ecx |
||
169 | |||
170 | mov ecx, ebx |
||
171 | shr ecx, 16 |
||
172 | add ebx, ecx |
||
173 | |||
174 | not bx |
||
175 | jnz .not_zero |
||
176 | dec bx |
||
177 | .not_zero: |
||
178 | xchg bl, bh |
||
179 | pop ecx |
||
180 | |||
181 | neg word [ptr+10] ; zero will stay zero so we just get the checksum |
||
182 | add word [ptr+10], bx ; , else we will get (new checksum - old checksum) in the end, wich should be 0 :) |
||
183 | pop ebx |
||
184 | |||
185 | } |
||
186 | |||
187 | |||
188 | |||
189 | ;----------------------------------------------------------------- |
||
190 | ; |
||
191 | ; IPv4_input: |
||
192 | ; |
||
193 | ; Will check if IPv4 Packet isnt damaged |
||
194 | ; and call appropriate handler. (TCP/UDP/ICMP/..) |
||
195 | ; |
||
196 | ; It will also re-construct fragmented packets |
||
197 | ; |
||
198 | ; IN: Pointer to buffer in [esp] |
||
199 | ; size of buffer in [esp+4] |
||
200 | ; pointer to device struct in ebx |
||
201 | ; pointer to IPv4 header in edx |
||
202 | ; size of IPv4 packet in ecx |
||
203 | ; OUT: / |
||
204 | ; |
||
205 | ;----------------------------------------------------------------- |
||
206 | align 4 |
||
207 | IPv4_input: ; TODO: add IPv4 raw sockets support |
||
208 | |||
3556 | hidnplayr | 209 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input, packet from: %u.%u.%u.%u ",\ |
3545 | hidnplayr | 210 | [edx + IPv4_header.SourceAddress + 0]:1,[edx + IPv4_header.SourceAddress + 1]:1,\ |
211 | [edx + IPv4_header.SourceAddress + 2]:1,[edx + IPv4_header.SourceAddress + 3]:1 |
||
3556 | hidnplayr | 212 | DEBUGF DEBUG_NETWORK_VERBOSE, "to: %u.%u.%u.%u\n",\ |
3545 | hidnplayr | 213 | [edx + IPv4_header.DestinationAddress + 0]:1,[edx + IPv4_header.DestinationAddress + 1]:1,\ |
214 | [edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1 |
||
215 | |||
216 | ;------------------------------- |
||
217 | ; re-calculate the checksum |
||
218 | |||
219 | IPv4_checksum edx |
||
220 | jnz .dump ; if checksum isn't valid then dump packet |
||
221 | |||
3556 | hidnplayr | 222 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Checksum ok\n" |
3545 | hidnplayr | 223 | |
224 | ;----------------------------------- |
||
225 | ; Check if destination IP is correct |
||
226 | |||
3643 | hidnplayr | 227 | call NET_ptr_to_num4 |
3545 | hidnplayr | 228 | |
229 | ; check if it matches local ip (Using RFC1122 strong end system model) |
||
230 | |||
231 | mov eax, [edx + IPv4_header.DestinationAddress] |
||
232 | cmp eax, [IP_LIST + edi] |
||
233 | je .ip_ok |
||
234 | |||
235 | ; check for broadcast (IP or (not SUBNET)) |
||
236 | |||
237 | cmp eax, [BROADCAST_LIST + edi] |
||
238 | je .ip_ok |
||
239 | |||
240 | ; or a special broadcast (255.255.255.255) |
||
241 | |||
242 | cmp eax, 0xffffffff |
||
243 | je .ip_ok |
||
244 | |||
245 | ; mayb |