Rev 6122 | Rev 6475 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3545 | hidnplayr | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
6122 | hidnplayr | 3 | ;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;; |
3545 | hidnplayr | 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 | |||
4850 | mario79 | 19 | $Revision: 6220 $ |
3545 | hidnplayr | 20 | |
4053 | hidnplayr | 21 | IPv4_MAX_FRAGMENTS = 64 |
4387 | hidnplayr | 22 | IPv4_MAX_ROUTES = 64 |
3545 | hidnplayr | 23 | |
4387 | hidnplayr | 24 | IPv4_ROUTE_FLAG_UP = 1 shl 0 |
25 | IPv4_ROUTE_FLAG_GATEWAY = 1 shl 1 |
||
26 | IPv4_ROUTE_FLAG_HOST = 1 shl 2 |
||
27 | IPv4_ROUTE_FLAG_D = 1 shl 3 ; Route was created by a redirect |
||
28 | IPv4_ROUTE_FLAG_M = 1 shl 4 ; Route was modified by a redirect |
||
29 | |||
3545 | hidnplayr | 30 | struct IPv4_header |
31 | |||
32 | VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] |
||
33 | TypeOfService db ? ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0] |
||
34 | TotalLength dw ? |
||
35 | Identification dw ? |
||
36 | FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15] |
||
37 | TimeToLive db ? ; |
||
38 | Protocol db ? |
||
39 | HeaderChecksum dw ? |
||
40 | SourceAddress dd ? |
||
41 | DestinationAddress dd ? |
||
42 | |||
43 | ends |
||
44 | |||
4052 | hidnplayr | 45 | struct IPv4_FRAGMENT_slot |
3545 | hidnplayr | 46 | |
47 | ttl dw ? ; Time to live for this entry, 0 for empty slot's |
||
48 | id dw ? ; Identification field from IP header |
||
49 | SrcIP dd ? ; .. from IP header |
||
50 | DstIP dd ? ; .. from IP header |
||
51 | ptr dd ? ; Pointer to first packet |
||
52 | |||
53 | ends |
||
54 | |||
4052 | hidnplayr | 55 | struct IPv4_FRAGMENT_entry ; This structure will replace the ethernet header in fragmented ip packets |
3545 | hidnplayr | 56 | |
57 | PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet) |
||
58 | NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet) |
||
59 | Owner dd ? ; Pointer to structure of driver |
||
60 | rb 2 ; to match ethernet header size ;;; FIXME |
||
61 | ; Ip header begins here (we will need the IP header to re-construct the complete packet) |
||
62 | ends |
||
63 | |||
4387 | hidnplayr | 64 | struct IPv4_ROUTE |
3545 | hidnplayr | 65 | |
4387 | hidnplayr | 66 | Destination dd ? |
67 | Gateway dd ? |
||
68 | Flags dd ? |
||
69 | Use dd ? |
||
70 | Interface dd ? |
||
71 | |||
72 | ends |
||
73 | |||
74 | |||
3698 | hidnplayr | 75 | uglobal |
3545 | hidnplayr | 76 | align 4 |
77 | |||
3600 | hidnplayr | 78 | IP_LIST rd NET_DEVICES_MAX |
79 | SUBNET_LIST rd NET_DEVICES_MAX |
||
80 | DNS_LIST rd NET_DEVICES_MAX |
||
81 | GATEWAY_LIST rd NET_DEVICES_MAX |
||
82 | BROADCAST_LIST rd NET_DEVICES_MAX |
||
3545 | hidnplayr | 83 | |
4052 | hidnplayr | 84 | IPv4_packets_tx rd NET_DEVICES_MAX |
85 | IPv4_packets_rx rd NET_DEVICES_MAX |
||
86 | IPv4_packets_dumped rd NET_DEVICES_MAX |
||
3545 | hidnplayr | 87 | |
4052 | hidnplayr | 88 | IPv4_FRAGMENT_LIST rb IPv4_MAX_FRAGMENTS * sizeof.IPv4_FRAGMENT_slot |
3698 | hidnplayr | 89 | |
4387 | hidnplayr | 90 | IPv4_ROUTES rd IPv4_MAX_ROUTES * sizeof.IPv4_ROUTE |
91 | |||
3545 | hidnplayr | 92 | endg |
93 | |||
94 | |||
6011 | hidnplayr | 95 | ;-----------------------------------------------------------------; |
96 | ; ; |
||
97 | ; ipv4_init: Resets all IPv4 variables ; |
||
98 | ; ; |
||
99 | ;-----------------------------------------------------------------; |
||
100 | macro ipv4_init { |
||
3545 | hidnplayr | 101 | |
102 | xor eax, eax |
||
103 | mov edi, IP_LIST |
||
4052 | hidnplayr | 104 | mov ecx, 7*NET_DEVICES_MAX + (sizeof.IPv4_FRAGMENT_slot*IPv4_MAX_FRAGMENTS)/4 |
3711 | clevermous | 105 | rep stosd |
3545 | hidnplayr | 106 | |
107 | } |
||
108 | |||
109 | |||
6011 | hidnplayr | 110 | ;-----------------------------------------------------------------; |
111 | ; ; |
||
112 | ; Decrease TimeToLive of all fragment slots ; |
||
113 | ; ; |
||
114 | ;-----------------------------------------------------------------; |
||
115 | macro ipv4_decrease_fragment_ttls { |
||
3545 | hidnplayr | 116 | |
117 | local .loop, .next |
||
118 | |||
4052 | hidnplayr | 119 | mov esi, IPv4_FRAGMENT_LIST |
120 | mov ecx, IPv4_MAX_FRAGMENTS |
||
3545 | hidnplayr | 121 | .loop: |
4052 | hidnplayr | 122 | cmp [esi + IPv4_FRAGMENT_slot.ttl], 0 |
3545 | hidnplayr | 123 | je .next |
4052 | hidnplayr | 124 | dec [esi + IPv4_FRAGMENT_slot.ttl] |
3545 | hidnplayr | 125 | jz .died |
126 | .next: |
||
4052 | hidnplayr | 127 | add esi, sizeof.IPv4_FRAGMENT_slot |
3545 | hidnplayr | 128 | dec ecx |
129 | jnz .loop |
||
130 | jmp .done |
||
131 | |||
132 | .died: |
||
3556 | hidnplayr | 133 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4 Fragment slot timed-out!\n" |
3545 | hidnplayr | 134 | ;;; TODO: clear all entry's of timed-out slot |
135 | jmp .next |
||
136 | |||
137 | .done: |
||
138 | } |
||
139 | |||
140 | |||
141 | |||
6011 | hidnplayr | 142 | macro ipv4_checksum ptr { |
3545 | hidnplayr | 143 | |
144 | ; This is the fast procedure to create or check an IP header without options |
||
145 | ; To create a new checksum, the checksum field must be set to 0 before computation |
||
146 | ; To check an existing checksum, leave the checksum as is, and it will be 0 after this procedure, if it was correct |
||
147 | |||
148 | push ebx |
||
149 | xor ebx, ebx |
||
150 | add bl, [ptr+1] |
||
151 | adc bh, [ptr+0] |
||
152 | |||
153 | adc bl, [ptr+3] |
||
154 | adc bh, [ptr+2] |
||
155 | |||
156 | adc bl, [ptr+5] |
||
157 | adc bh, [ptr+4] |
||
158 | |||
159 | adc bl, [ptr+7] |
||
160 | adc bh, [ptr+6] |
||
161 | |||
162 | adc bl, [ptr+9] |
||
163 | adc bh, [ptr+8] |
||
164 | |||
165 | ; we skip 11th and 12th byte, they are the checksum bytes and should be 0 for re-calculation |
||
166 | |||
167 | adc bl, [ptr+13] |
||
168 | adc bh, [ptr+12] |
||
169 | |||
170 | adc bl, [ptr+15] |
||
171 | adc bh, [ptr+14] |
||
172 | |||
173 | adc bl, [ptr+17] |
||
174 | adc bh, [ptr+16] |
||
175 | |||
176 | adc bl, [ptr+19] |
||
177 | adc bh, [ptr+18] |
||
178 | |||
179 | adc ebx, 0 |
||
180 | |||
181 | push ecx |
||
182 | mov ecx, ebx |
||
183 | shr ecx, 16 |
||
184 | and ebx, 0xffff |
||
185 | add ebx, ecx |
||
186 | |||
187 | mov ecx, ebx |
||
188 | shr ecx, 16 |
||
189 | add ebx, ecx |
||
190 | |||
191 | not bx |
||
192 | jnz .not_zero |
||
193 | dec bx |
||
194 | .not_zero: |
||
195 | xchg bl, bh |
||
196 | pop ecx |
||
197 | |||
198 | neg word [ptr+10] ; zero will stay zero so we just get the checksum |
||
199 | add word [ptr+10], bx ; , else we will get (new checksum - old checksum) in the end, wich should be 0 :) |
||
200 | pop ebx |
||
201 | |||
202 | } |
||
203 | |||
204 | |||
205 | |||
6011 | hidnplayr | 206 | ;-----------------------------------------------------------------; |
207 | ; ; |
||
208 | ; ipv4_input: Check if IPv4 Packet isnt damaged and call ; |
||
209 | ; appropriate handler. (TCP/UDP/ICMP/..) ; |
||
210 | ; We will also re-construct fragmented packets. ; |
||
211 | ; ; |
||
212 | ; IN: Pointer to buffer in [esp] ; |
||
213 | ; pointer to device struct in ebx ; |
||
214 | ; pointer to IPv4 header in edx ; |
||
215 | ; size of IPv4 packet in ecx ; |
||
216 | ; ; |
||
217 | ; OUT: / ; |
||
218 | ; ; |
||
219 | ;-----------------------------------------------------------------; |
||
3545 | hidnplayr | 220 | align 4 |
6011 | hidnplayr | 22 |