Rev 1259 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1171 | hidnplayr | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
3 | ;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
||
4 | ;; Distributed under terms of the GNU General Public License ;; |
||
5 | ;; ;; |
||
6 | ;; STACK.INC ;; |
||
7 | ;; ;; |
||
8 | ;; BASIC TCP/IP stack for KolibriOS ;; |
||
9 | ;; ;; |
||
10 | ;; Written by hidnplayr@kolibrios.org ;; |
||
11 | ;; ;; |
||
12 | ;; based on the work of Mike Hibbett, mikeh@oceanfree.net ;; |
||
13 | ;; but also Paolo Franchetti ;; |
||
14 | ;; ;; |
||
15 | ;; GNU GENERAL PUBLIC LICENSE ;; |
||
16 | ;; Version 2, June 1991 ;; |
||
17 | ;; ;; |
||
18 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1159 | hidnplayr | 19 | |
1206 | hidnplayr | 20 | $Revision: 1318 $ |
1159 | hidnplayr | 21 | |
22 | uglobal |
||
23 | last_1sTick db ? |
||
24 | last_1hsTick dd ? |
||
25 | endg |
||
26 | |||
1259 | hidnplayr | 27 | MAX_NET_DEVICES equ 16 |
28 | QUEUE_BEFORE_SENDING equ 1 ; 1 or 0 (enable or disable) currently only affects ethernet |
||
1159 | hidnplayr | 29 | |
1185 | hidnplayr | 30 | MIN_EPHEMERAL_PORT equ 49152 |
31 | MAX_EPHEMERAL_PORT equ 61000 |
||
1159 | hidnplayr | 32 | |
1257 | hidnplayr | 33 | ETHER equ 1337 ; TODO: find another value for this (how does it work in posix ?) |
1185 | hidnplayr | 34 | ETHER_ARP equ 0x0608 |
35 | |||
1254 | hidnplayr | 36 | AF_UNSPEC equ 0 |
1249 | hidnplayr | 37 | AF_UNIX equ 1 |
1159 | hidnplayr | 38 | AF_INET4 equ 2 |
39 | ;AF_AX25 equ 3 |
||
40 | ;AF_IPX equ 4 |
||
41 | ;AF_APPLETALK equ 5 |
||
42 | ;AF_NETROM equ 6 |
||
43 | ;AF_BRIDGE equ 7 |
||
44 | ;AF_AAL5 equ 8 |
||
45 | ;AF_X25 equ 9 |
||
46 | ;AF_INET6 equ 10 |
||
47 | ;AF_MAX equ 12 |
||
48 | |||
49 | IP_PROTO_IP equ 0 |
||
50 | IP_PROTO_ICMP equ 1 |
||
51 | IP_PROTO_TCP equ 6 |
||
52 | IP_PROTO_UDP equ 17 |
||
53 | |||
1200 | hidnplayr | 54 | ; Socket types |
55 | SOCK_STREAM = 1 |
||
56 | SOCK_DGRAM = 2 |
||
57 | SOCK_RAW = 3 |
||
58 | |||
1254 | hidnplayr | 59 | TCB_LISTEN equ 1 |
60 | TCB_SYN_SENT equ 2 |
||
61 | TCB_SYN_RECEIVED equ 3 |
||
62 | TCB_ESTABLISHED equ 4 |
||
63 | TCB_FIN_WAIT_1 equ 5 |
||
64 | TCB_FIN_WAIT_2 equ 6 |
||
65 | TCB_CLOSE_WAIT equ 7 |
||
66 | TCB_CLOSING equ 8 |
||
67 | TCB_LAST_ACK equ 9 |
||
68 | TCB_TIMED_WAIT equ 10 |
||
69 | TCB_CLOSED equ 11 |
||
1159 | hidnplayr | 70 | |
1254 | hidnplayr | 71 | TH_FIN equ 1 shl 0 |
72 | TH_SYN equ 1 shl 1 |
||
73 | TH_RST equ 1 shl 2 |
||
74 | TH_PUSH equ 1 shl 3 |
||
75 | TH_ACK equ 1 shl 4 |
||
76 | TH_URG equ 1 shl 5 |
||
77 | |||
78 | |||
79 | macro inc_INET reg { |
||
80 | |||
1256 | clevermous | 81 | add byte [reg + 3], 1 |
1254 | hidnplayr | 82 | adc byte [reg + 2], 0 |
83 | adc byte [reg + 1], 0 |
||
1256 | clevermous | 84 | adc byte [reg], 0 |
1254 | hidnplayr | 85 | |
86 | } |
||
87 | |||
88 | |||
89 | macro add_INET reg { |
||
1256 | clevermous | 90 | add byte [reg + 3], cl |
91 | adc byte [reg + 2], ch |
||
92 | adc byte [reg + 1], 0 |
||
93 | adc byte [reg], 0 |
||
1254 | hidnplayr | 94 | rol ecx, 16 |
1256 | clevermous | 95 | add byte [reg + 1], cl |
96 | adc byte [reg], ch |
||
1254 | hidnplayr | 97 | rol ecx, 16 |
98 | } |
||
99 | |||
1318 | hidnplayr | 100 | |
101 | macro pseudo_random reg { |
||
102 | |||
103 | add reg, [esp] |
||
104 | rol reg, 5 |
||
105 | xor reg, [timer_ticks] |
||
106 | imul reg, 214013 |
||
107 | xor reg, 0xdeadbeef |
||
108 | rol reg, 9 |
||
109 | |||
110 | pushd reg |
||
111 | mov word [esp], 0x8080 ; kernel heap start addr (os_stack) |
||
112 | xor reg, [esp] |
||
113 | add esp, 4 |
||
114 | |||
115 | } |
||
116 | |||
1159 | hidnplayr | 117 | include "queue.inc" |
1187 | hidnplayr | 118 | include "ARP.inc" |
119 | include "IPv4.inc" |
||
1159 | hidnplayr | 120 | include "ethernet.inc" |
121 | include "socket.inc" |
||
1249 | hidnplayr | 122 | include "tcp.inc" |
1185 | hidnplayr | 123 | include "udp.inc" |
124 | include "icmp.inc" |
||
1159 | hidnplayr | 125 | |
1257 | hidnplayr | 126 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 127 | ; |
128 | ; stack_init |
||
129 | ; |
||
130 | ; This function calls all network init procedures |
||
131 | ; |
||
132 | ; IN: / |
||
133 | ; OUT: / |
||
134 | ; |
||
1257 | hidnplayr | 135 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 136 | align 4 |
137 | stack_init: |
||
138 | |||
139 | call ETH_init |
||
140 | call IPv4_init |
||
141 | call ARP_init |
||
142 | call UDP_init |
||
1249 | hidnplayr | 143 | call TCP_init |
1159 | hidnplayr | 144 | call ICMP_init |
145 | call socket_init |
||
146 | |||
1254 | hidnplayr | 147 | mov al, 0 ; set up 1s timer |
1159 | hidnplayr | 148 | out 0x70, al |
149 | in al, 0x71 |
||
150 | mov [last_1sTick], al |
||
151 | |||
152 | ret |
||
153 | |||
154 | |||
155 | |||
1257 | hidnplayr | 156 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 157 | ; |
158 | ; stack_handler |
||
159 | ; |
||
160 | ; This function calls all network init procedures |
||
161 | ; |
||
162 | ; IN: / |
||
163 | ; OUT: / |
||
164 | ; |
||
1257 | hidnplayr | 165 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 166 | align 4 |
167 | stack_handler: |
||
168 | |||
1257 | hidnplayr | 169 | cmp [ETH_RUNNING], 0 |
170 | je .exit |
||
1159 | hidnplayr | 171 | |
1318 | hidnplayr | 172 | ; Test for 10ms tick |
1257 | hidnplayr | 173 | mov eax, [timer_ticks] |
174 | cmp eax, [last_1hsTick] |
||
175 | je .exit |
||
1159 | hidnplayr | 176 | |
1257 | hidnplayr | 177 | mov [last_1hsTick], eax |
1159 | hidnplayr | 178 | |
1257 | hidnplayr | 179 | call ETH_handler ; handle all queued ethernet packets |
1259 | hidnplayr | 180 | if QUEUE_BEFORE_SENDING |
1257 | hidnplayr | 181 | call ETH_send_queued |
1259 | hidnplayr | 182 | end if |
1257 | hidnplayr | 183 | call TCP_send_queued |
1249 | hidnplayr | 184 | |
1159 | hidnplayr | 185 | .sec_tick: |
186 | |||
1257 | hidnplayr | 187 | ; Test for 1 second tick |
188 | mov al, 0 |
||
189 | out 0x70, al |
||
190 | in al, 0x71 |
||
191 | cmp al, [last_1sTick] |
||
192 | je .exit |
||
1159 | hidnplayr | 193 | |
1257 | hidnplayr | 194 | mov [last_1sTick], al |
1159 | hidnplayr | 195 | |
1257 | hidnplayr | 196 | call ARP_decrease_entry_ttls |
197 | call IPv4_decrease_fragment_ttls |
||
198 | call TCP_decrease_socket_ttls |
||
1159 | hidnplayr | 199 | |
200 | .exit: |
||
1257 | hidnplayr | 201 | ret |
1159 | hidnplayr | 202 | |
203 | |||
1249 | hidnplayr | 204 | ;----------------------------------------------------------------- |
205 | ; |
||
206 | ; checksum_1 |
||
207 | ; |
||
208 | ; This is the first of two functions needed to calculate the TCP checksum. |
||
209 | ; |
||
210 | ; IN: edx = start offeset for semi-checksum |
||
211 | ; esi = pointer to data |
||
212 | ; ecx = data size |
||
213 | ; OUT: edx = semi-checksum |
||
214 | ; |
||
215 | ;----------------------------------------------------------------- |
||
216 | align 4 |
||
217 | checksum_1: |
||
1159 | hidnplayr | 218 | |
1249 | hidnplayr | 219 | xor eax, eax |
220 | shr ecx, 1 |
||
221 | pushf |
||
222 | .loop: |
||
223 | lodsw |
||
224 | xchg al, ah |
||
225 | add edx, eax |
||
226 | loop .loop |
||
1159 | hidnplayr | 227 | |
1249 | hidnplayr | 228 | popf |
229 | jnc .end |
||
1159 | hidnplayr | 230 | |
1251 | clevermous | 231 | add dh, [esi] |
232 | adc edx, 0 |
||
1159 | hidnplayr | 233 | |
1249 | hidnplayr | 234 | .end: |
235 | |||
236 | ret |
||
237 | |||
238 | |||
239 | ;----------------------------------------------------------------- |
||
240 | ; |
||
241 | ; checksum_2 |
||
242 | ; |
||
243 | ; This function calculates the final ip/tcp/udp checksum for you |
||
244 | ; |
||
245 | ; IN: edx = semi-checksum |
||
246 | ; OUT: dx = checksum (in INET byte order) |
||
247 | ; |
||
248 | ;----------------------------------------------------------------- |
||
249 | align 4 |
||
250 | checksum_2: |
||
251 | |||
252 | mov ecx, edx |
||
253 | shr ecx, 16 |
||
254 | and edx, 0xffff |
||
255 | add edx, ecx |
||
256 | mov eax, edx |
||
257 | shr eax, 16 |
||
258 | add edx, eax |
||
259 | |||
260 | not dx |
||
261 | jnz .not_zero |
||
262 | dec dx |
||
263 | .not_zero: |
||
264 | xchg dl, dh |
||
265 | |||
266 | DEBUGF 1,"Checksum: %x\n",dx |
||
267 | |||
268 | ret |
||
269 | |||
270 | |||
271 | |||
1159 | hidnplayr | 272 | ;---------------------------------------------------------------- |
273 | ; |
||
1171 | hidnplayr | 274 | ; System function to work with network devices (73) |
1159 | hidnplayr | 275 | ; |
276 | ;---------------------------------------------------------------- |
||
277 | align 4 |
||
278 | sys_network: |
||
279 | |||
1196 | hidnplayr | 280 | cmp ebx, -1 |
281 | jne @f |
||
282 | |||
283 | mov eax, [ETH_RUNNING] |
||
284 | jmp .return |
||
285 | |||
286 | @@: |
||
1159 | hidnplayr | 287 | cmp bh, MAX_NET_DEVICES ; Check if device number exists |
288 | jge .doesnt_exist |
||
289 | |||
290 | mov esi, ebx |
||
291 | and esi, 0x0000ff00 |
||
292 | shr esi, 6 |
||
293 | |||
294 | cmp dword [esi + ETH_DRV_LIST], 0 ; check if driver is running |
||
295 | je .doesnt_exist |
||
296 | |||
297 | test bl, bl ; 0 = Get device type (ethernet/token ring/...) |
||
298 | jnz @f |
||
1196 | hidnplayr | 299 | ; todo |
1192 | hidnplayr | 300 | xor eax, eax |
301 | jmp .return |
||
1159 | hidnplayr | 302 | |
303 | |||
304 | @@: |
||
305 | dec bl ; 1 = Get device name |
||
306 | jnz @f |
||
307 | |||
308 | mov esi, [esi + ETH_DRV_LIST] |
||
309 | mov esi, [esi + ETH_DEVICE.name] |
||
310 | mov edi, ecx |
||
311 | |||
312 | mov ecx, 64 ; max length |
||
313 | repnz movsb |
||
314 | |||
1192 | hidnplayr | 315 | xor eax, eax |
316 | jmp .return |
||
1159 | hidnplayr | 317 | |
1192 | hidnplayr | 318 | @@: |
1159 | hidnplayr | 319 | |
1192 | hidnplayr | 320 | dec bl ; 2 = Reset the device |
321 | jnz @f |
||
322 | |||
323 | mov esi, [esi + ETH_DRV_LIST] |
||
324 | call [esi + ETH_DEVICE.reset] |
||
325 | jmp .return |
||
326 | |||
1159 | hidnplayr | 327 | @@: |
1192 | hidnplayr | 328 | |
329 | dec bl ; 3 = Stop driver for this device |
||
330 | jnz @f |
||
331 | |||
332 | mov esi, [esi + ETH_DRV_LIST] |
||
333 | call [esi + ETH_DEVICE.unload] |
||
334 | jmp .return |
||
335 | |||
336 | @@: |
||
1249 | hidnplayr | 337 | dec bl ; 4 = Get driver pointer |
338 | jnz @f |
||
1192 | hidnplayr | 339 | |
1249 | hidnplayr | 340 | ; ..; |
341 | |||
342 | |||
343 | @@: |
||
344 | ; ... ; 5 Get driver name |
||
345 | |||
1159 | hidnplayr | 346 | .doesnt_exist: |
347 | DEBUGF 1,"sys_network: invalid device/function specified!\n" |
||
348 | mov eax, -1 |
||
349 | |||
1192 | hidnplayr | 350 | .return: |
351 | mov [esp+28+4], eax |
||
1159 | hidnplayr | 352 | ret |
353 | |||
354 | |||
355 | ;---------------------------------------------------------------- |
||
356 | ; |
||
1171 | hidnplayr | 357 | ; System Function To work with Protocols (75) |
1159 | hidnplayr | 358 | ; |
359 | ;---------------------------------------------------------------- |
||
360 | align 4 |
||
361 | sys_protocols: |
||
362 | cmp bh, MAX_NET_DEVICES ; Check if device number exists |
||
363 | jge .doesnt_exist |
||
364 | |||
365 | mov esi, ebx |
||
366 | and esi, 0x0000ff00 |
||
367 | shr esi, 6 |
||
1171 | hidnplayr | 368 | cmp dword [esi + ETH_DRV_LIST], 0 ; check if driver is running TODO: check other lists too |
1159 | hidnplayr | 369 | je .doesnt_exist |
370 | |||
371 | push .return ; return address (we will be using jumps instead of calls) |
||
372 | |||
373 | mov eax, ebx ; set ax to protocol number |
||
374 | shr eax, 16 ; |
||
375 | |||
376 | cmp ax , IP_PROTO_IP |
||
377 | je IPv4_API |
||
378 | |||
379 | cmp ax , IP_PROTO_ICMP |
||
380 | je ICMP_API |
||
381 | |||
382 | cmp ax , IP_PROTO_UDP |
||
383 | je UDP_API |
||
384 | |||
1171 | hidnplayr | 385 | cmp ax , IP_PROTO_TCP |
1254 | hidnplayr | 386 | je TCP_API |
1159 | hidnplayr | 387 | |
1171 | hidnplayr | 388 | cmp ax , ETHER_ARP |
1159 | hidnplayr | 389 | je ARP_API |
390 | |||
1185 | hidnplayr | 391 | cmp ax , ETHER |
1159 | hidnplayr | 392 | je ETH_API |
393 | |||
1171 | hidnplayr | 394 | add esp, 4 ; if we reached here, no function was called, so we need to balance stack |
1159 | hidnplayr | 395 | |
396 | .doesnt_exist: |
||
1171 | hidnplayr | 397 | DEBUGF 1,"sys_protocols: protocol %u doesnt exist on device %u!\n",ax, bh |
1159 | hidnplayr | 398 | mov eax, -1 |
399 | |||
400 | .return: |
||
1171 | hidnplayr | 401 | mov [esp+28+4], eax |
1257 | hidnplayr | 402 | ret |