Rev 2914 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2914 | Rev 2924 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2012. 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 | ;; STACK.INC ;; |
6 | ;; STACK.INC ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; TCP/IP stack for KolibriOS ;; |
8 | ;; TCP/IP stack for KolibriOS ;; |
9 | ;; ;; |
9 | ;; ;; |
10 | ;; Written by hidnplayr@kolibrios.org ;; |
10 | ;; Written by hidnplayr@kolibrios.org ;; |
11 | ;; ;; |
11 | ;; ;; |
12 | ;; Some parts of code are based on the work of: ;; |
12 | ;; Some parts of code are based on the work of: ;; |
13 | ;; Mike Hibbett (menuetos network stack) ;; |
13 | ;; Mike Hibbett (menuetos network stack) ;; |
14 | ;; Eugen Brasoveanu (solar os network stack and drivers) ;; |
14 | ;; Eugen Brasoveanu (solar os network stack and drivers) ;; |
15 | ;; mike.dld (kolibrios socket code) ;; |
15 | ;; mike.dld (kolibrios socket code) ;; |
16 | ;; ;; |
16 | ;; ;; |
17 | ;; TCP part is based on 4.4BSD ;; |
17 | ;; TCP part is based on 4.4BSD ;; |
18 | ;; ;; |
18 | ;; ;; |
19 | ;; GNU GENERAL PUBLIC LICENSE ;; |
19 | ;; GNU GENERAL PUBLIC LICENSE ;; |
20 | ;; Version 2, June 1991 ;; |
20 | ;; Version 2, June 1991 ;; |
21 | ;; ;; |
21 | ;; ;; |
22 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
22 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
23 | 23 | ||
24 | $Revision: 2914 $ |
24 | $Revision: 2924 $ |
25 | 25 | ||
26 | __DEBUG_LEVEL_OLD__ equ __DEBUG_LEVEL__ ; use seperate debug level for network part of kernel |
26 | __DEBUG_LEVEL_OLD__ equ __DEBUG_LEVEL__ ; use seperate debug level for network part of kernel |
27 | __DEBUG_LEVEL__ equ 1 |
27 | __DEBUG_LEVEL__ equ 1 |
28 | 28 | ||
29 | uglobal |
29 | uglobal |
30 | net_10ms dd ? |
30 | net_10ms dd ? |
31 | net_tmr_count dw ? |
31 | net_tmr_count dw ? |
32 | endg |
32 | endg |
33 | 33 | ||
34 | MAX_NET_DEVICES = 16 |
34 | MAX_NET_DEVICES = 16 |
35 | 35 | ||
36 | MIN_EPHEMERAL_PORT = 49152 |
36 | MIN_EPHEMERAL_PORT = 49152 |
37 | MAX_EPHEMERAL_PORT = 61000 |
37 | MAX_EPHEMERAL_PORT = 61000 |
38 | 38 | ||
39 | ; Ethernet protocol numbers |
39 | ; Ethernet protocol numbers |
40 | ETHER_ARP = 0x0608 |
40 | ETHER_ARP = 0x0608 |
41 | ETHER_IPv4 = 0x0008 |
41 | ETHER_IPv4 = 0x0008 |
42 | ETHER_IPv6 = 0xDD86 |
42 | ETHER_IPv6 = 0xDD86 |
43 | ETHER_PPP_DISCOVERY = 0x6388 |
43 | ETHER_PPP_DISCOVERY = 0x6388 |
44 | ETHER_PPP_SESSION = 0x6488 |
44 | ETHER_PPP_SESSION = 0x6488 |
45 | 45 | ||
46 | ;Protocol family |
46 | ;Protocol family |
47 | AF_UNSPEC = 0 |
47 | AF_UNSPEC = 0 |
48 | AF_UNIX = 1 |
48 | AF_UNIX = 1 |
49 | AF_INET4 = 2 |
49 | AF_INET4 = 2 |
50 | AF_INET6 = 10 |
50 | AF_INET6 = 10 |
51 | 51 | ||
52 | ; Internet protocol numbers |
52 | ; Internet protocol numbers |
53 | IP_PROTO_IP = 0 |
53 | IP_PROTO_IP = 0 |
54 | IP_PROTO_ICMP = 1 |
54 | IP_PROTO_ICMP = 1 |
55 | IP_PROTO_TCP = 6 |
55 | IP_PROTO_TCP = 6 |
56 | IP_PROTO_UDP = 17 |
56 | IP_PROTO_UDP = 17 |
57 | 57 | ||
58 | ; Socket types |
58 | ; Socket types |
59 | SOCK_STREAM = 1 |
59 | SOCK_STREAM = 1 |
60 | SOCK_DGRAM = 2 |
60 | SOCK_DGRAM = 2 |
61 | SOCK_RAW = 3 |
61 | SOCK_RAW = 3 |
62 | 62 | ||
63 | ; Socket options |
63 | ; Socket options |
64 | SO_ACCEPTCON = 1 shl 0 |
64 | SO_ACCEPTCON = 1 shl 0 |
65 | SO_BROADCAST = 1 shl 1 |
65 | SO_BROADCAST = 1 shl 1 |
66 | SO_DEBUG = 1 shl 2 |
66 | SO_DEBUG = 1 shl 2 |
67 | SO_DONTROUTE = 1 shl 3 |
67 | SO_DONTROUTE = 1 shl 3 |
68 | SO_KEEPALIVE = 1 shl 4 |
68 | SO_KEEPALIVE = 1 shl 4 |
69 | SO_OOBINLINE = 1 shl 5 |
69 | SO_OOBINLINE = 1 shl 5 |
70 | SO_REUSEADDR = 1 shl 6 |
70 | SO_REUSEADDR = 1 shl 6 |
71 | SO_REUSEPORT = 1 shl 7 |
71 | SO_REUSEPORT = 1 shl 7 |
72 | SO_USELOOPBACK = 1 shl 8 |
72 | SO_USELOOPBACK = 1 shl 8 |
73 | SO_BINDTODEVICE = 1 shl 9 |
73 | SO_BINDTODEVICE = 1 shl 9 |
74 | 74 | ||
75 | ; Socket level |
75 | ; Socket level |
76 | SOL_SOCKET = 0 |
76 | SOL_SOCKET = 0 |
77 | 77 | ||
78 | 78 | ||
79 | ; Socket States |
79 | ; Socket States |
80 | SS_NOFDREF = 0x001 ; no file table ref any more |
80 | SS_NOFDREF = 0x001 ; no file table ref any more |
81 | SS_ISCONNECTED = 0x002 ; socket connected to a peer |
81 | SS_ISCONNECTED = 0x002 ; socket connected to a peer |
82 | SS_ISCONNECTING = 0x004 ; in process of connecting to peer |
82 | SS_ISCONNECTING = 0x004 ; in process of connecting to peer |
83 | SS_ISDISCONNECTING = 0x008 ; in process of disconnecting |
83 | SS_ISDISCONNECTING = 0x008 ; in process of disconnecting |
84 | SS_CANTSENDMORE = 0x010 ; can't send more data to peer |
84 | SS_CANTSENDMORE = 0x010 ; can't send more data to peer |
85 | SS_CANTRCVMORE = 0x020 ; can't receive more data from peer |
85 | SS_CANTRCVMORE = 0x020 ; can't receive more data from peer |
86 | SS_RCVATMARK = 0x040 ; at mark on input |
86 | SS_RCVATMARK = 0x040 ; at mark on input |
87 | SS_ISABORTING = 0x080 ; aborting fd references - close() |
87 | SS_ISABORTING = 0x080 ; aborting fd references - close() |
88 | SS_RESTARTSYS = 0x100 ; restart blocked system calls |
88 | SS_RESTARTSYS = 0x100 ; restart blocked system calls |
89 | SS_ISDISCONNECTED = 0x800 ; socket disconnected from peer |
89 | SS_ISDISCONNECTED = 0x800 ; socket disconnected from peer |
90 | 90 | ||
91 | SS_ASYNC = 0x100 ; async i/o notify |
91 | SS_ASYNC = 0x100 ; async i/o notify |
92 | SS_ISCONFIRMING = 0x200 ; deciding to accept connection req |
92 | SS_ISCONFIRMING = 0x200 ; deciding to accept connection req |
93 | SS_MORETOCOME = 0x400 |
93 | SS_MORETOCOME = 0x400 |
94 | 94 | ||
95 | 95 | ||
96 | SOCKET_MAXDATA = 4096*32 ; must be 4096*(power of 2) where 'power of 2' is at least 8 |
96 | SOCKET_MAXDATA = 4096*32 ; must be 4096*(power of 2) where 'power of 2' is at least 8 |
97 | 97 | ||
98 | ; Network driver types |
98 | ; Network driver types |
99 | NET_TYPE_LOOPBACK = 0 |
99 | NET_TYPE_LOOPBACK = 0 |
100 | NET_TYPE_ETH = 1 |
100 | NET_TYPE_ETH = 1 |
101 | NET_TYPE_SLIP = 2 |
101 | NET_TYPE_SLIP = 2 |
102 | 102 | ||
103 | MAX_backlog = 20 ; maximum backlog for stream sockets |
103 | MAX_backlog = 20 ; maximum backlog for stream sockets |
104 | 104 | ||
105 | ; Error Codes |
105 | ; Error Codes |
106 | ENOBUFS = 55 |
106 | ENOBUFS = 55 |
107 | ECONNREFUSED = 61 |
107 | ECONNREFUSED = 61 |
108 | ECONNRESET = 52 |
108 | ECONNRESET = 52 |
109 | ETIMEDOUT = 60 |
109 | ETIMEDOUT = 60 |
110 | ECONNABORTED = 53 |
110 | ECONNABORTED = 53 |
111 | 111 | ||
112 | ; Api protocol numbers |
112 | ; Api protocol numbers |
113 | API_ETH = 0 |
113 | API_ETH = 0 |
114 | API_IPv4 = 1 |
114 | API_IPv4 = 1 |
115 | API_ICMP = 2 |
115 | API_ICMP = 2 |
116 | API_UDP = 3 |
116 | API_UDP = 3 |
117 | API_TCP = 4 |
117 | API_TCP = 4 |
118 | API_ARP = 5 |
118 | API_ARP = 5 |
119 | API_PPPOE = 6 |
119 | API_PPPOE = 6 |
- | 120 | ||
- | 121 | HWACC_TCP_IPv4 = 1 shl 0 |
|
120 | 122 | ||
121 | struct NET_DEVICE |
123 | struct NET_DEVICE |
122 | 124 | ||
123 | type dd ? ; Type field |
125 | type dd ? ; Type field |
124 | mtu dd ? ; Maximal Transmission Unit |
126 | mtu dd ? ; Maximal Transmission Unit |
125 | name dd ? ; Ptr to 0 terminated string |
127 | name dd ? ; Ptr to 0 terminated string |
126 | 128 | ||
127 | unload dd ? ; Ptrs to driver functions |
129 | unload dd ? ; Ptrs to driver functions |
128 | reset dd ? ; |
130 | reset dd ? ; |
129 | transmit dd ? ; |
131 | transmit dd ? ; |
130 | 132 | ||
131 | bytes_tx dq ? ; Statistics, updated by the driver |
133 | bytes_tx dq ? ; Statistics, updated by the driver |
132 | bytes_rx dq ? ; |
134 | bytes_rx dq ? ; |
133 | packets_tx dd ? ; |
135 | packets_tx dd ? ; |
134 | packets_rx dd ? ; |
136 | packets_rx dd ? ; |
135 | 137 | ||
136 | ; hwacc dd ? ; bitmask stating available hardware accelerations (offload engines) |
138 | ; hwacc dd ? ; bitmask stating available hardware accelerations (offload engines) |
137 | 139 | ||
138 | ends |
140 | ends |
139 | 141 | ||
140 | 142 | ||
141 | ; Exactly as it says.. |
143 | ; Exactly as it says.. |
142 | macro pseudo_random reg { |
144 | macro pseudo_random reg { |
143 | add reg, [esp] |
145 | add reg, [esp] |
144 | rol reg, 5 |
146 | rol reg, 5 |
145 | xor reg, [timer_ticks] |
147 | xor reg, [timer_ticks] |
146 | add reg, [CPU_FREQ] |
148 | add reg, [CPU_FREQ] |
147 | imul reg, 214013 |
149 | imul reg, 214013 |
148 | xor reg, 0xdeadbeef |
150 | xor reg, 0xdeadbeef |
149 | rol reg, 9 |
151 | rol reg, 9 |
150 | } |
152 | } |
151 | 153 | ||
152 | macro ntohd reg { |
154 | macro ntohd reg { |
153 | 155 | ||
154 | rol word reg, 8 |
156 | rol word reg, 8 |
155 | rol dword reg, 16 |
157 | rol dword reg, 16 |
156 | rol word reg , 8 |
158 | rol word reg , 8 |
157 | 159 | ||
158 | } |
160 | } |
159 | 161 | ||
160 | macro ntohw reg { |
162 | macro ntohw reg { |
161 | 163 | ||
162 | rol word reg, 8 |
164 | rol word reg, 8 |
163 | 165 | ||
164 | } |
166 | } |
165 | 167 | ||
166 | 168 | ||
167 | include "queue.inc" |
169 | include "queue.inc" |
168 | 170 | ||
169 | include "loopback.inc" |
171 | include "loopback.inc" |
170 | include "ethernet.inc" |
172 | include "ethernet.inc" |
171 | 173 | ||
172 | ;include "PPPoE.inc" |
174 | ;include "PPPoE.inc" |
173 | 175 | ||
174 | include "ARP.inc" |
176 | include "ARP.inc" |
175 | include "IPv4.inc" |
177 | include "IPv4.inc" |
176 | ;include "IPv6.inc" |
178 | ;include "IPv6.inc" |
177 | 179 | ||
178 | include "icmp.inc" |
180 | include "icmp.inc" |
179 | include "udp.inc" |
181 | include "udp.inc" |
180 | include "tcp.inc" |
182 | include "tcp.inc" |
181 | 183 | ||
182 | include "socket.inc" |
184 | include "socket.inc" |
183 | 185 | ||
184 | 186 | ||
185 | 187 | ||
186 | align 4 |
188 | align 4 |
187 | uglobal |
189 | uglobal |
188 | 190 | ||
189 | NET_RUNNING dd ? |
191 | NET_RUNNING dd ? |
190 | NET_DEFAULT dd ? |
192 | NET_DEFAULT dd ? |
191 | NET_DRV_LIST rd MAX_NET_DEVICES |
193 | NET_DRV_LIST rd MAX_NET_DEVICES |
192 | 194 | ||
193 | endg |
195 | endg |
194 | 196 | ||
195 | 197 | ||
196 | ;----------------------------------------------------------------- |
198 | ;----------------------------------------------------------------- |
197 | ; |
199 | ; |
198 | ; stack_init |
200 | ; stack_init |
199 | ; |
201 | ; |
200 | ; This function calls all network init procedures |
202 | ; This function calls all network init procedures |
201 | ; |
203 | ; |
202 | ; IN: / |
204 | ; IN: / |
203 | ; OUT: / |
205 | ; OUT: / |
204 | ; |
206 | ; |
205 | ;----------------------------------------------------------------- |
207 | ;----------------------------------------------------------------- |
206 | align 4 |
208 | align 4 |
207 | stack_init: |
209 | stack_init: |
208 | 210 | ||
209 | ; Init the network drivers list |
211 | ; Init the network drivers list |
210 | xor eax, eax |
212 | xor eax, eax |
211 | mov edi, NET_RUNNING |
213 | mov edi, NET_RUNNING |
212 | mov ecx, (MAX_NET_DEVICES + 2) |
214 | mov ecx, (MAX_NET_DEVICES + 2) |
213 | rep stosd |
215 | rep stosd |
214 | 216 | ||
215 | ; PPPOE_init |
217 | ; PPPOE_init |
216 | 218 | ||
217 | IPv4_init |
219 | IPv4_init |
218 | ; IPv6_init |
220 | ; IPv6_init |
219 | ICMP_init |
221 | ICMP_init |
220 | 222 | ||
221 | ARP_init |
223 | ARP_init |
222 | UDP_init |
224 | UDP_init |
223 | TCP_init |
225 | TCP_init |
224 | 226 | ||
225 | SOCKET_init |
227 | SOCKET_init |
226 | 228 | ||
227 | mov [net_tmr_count], 0 |
229 | mov [net_tmr_count], 0 |
228 | 230 | ||
229 | ret |
231 | ret |
230 | 232 | ||
231 | 233 | ||
232 | ;----------------------------------------------------------------- |
234 | ;----------------------------------------------------------------- |
233 | ; |
235 | ; |
234 | ; stack_handler |
236 | ; stack_handler |
235 | ; |
237 | ; |
236 | ; This function is called in kernel loop |
238 | ; This function is called in kernel loop |
237 | ; |
239 | ; |
238 | ; IN: / |
240 | ; IN: / |
239 | ; OUT: / |
241 | ; OUT: / |
240 | ; |
242 | ; |
241 | ;----------------------------------------------------------------- |
243 | ;----------------------------------------------------------------- |
242 | align 4 |
244 | align 4 |
243 | stack_handler: |
245 | stack_handler: |
244 | 246 | ||
245 | cmp [NET_RUNNING], 0 |
247 | cmp [NET_RUNNING], 0 |
246 | je .exit |
248 | je .exit |
247 | 249 | ||
248 | ; Test for 10ms tick |
250 | ; Test for 10ms tick |
249 | mov eax, [timer_ticks] |
251 | mov eax, [timer_ticks] |
250 | cmp eax, [net_10ms] |
252 | cmp eax, [net_10ms] |
251 | je .exit |
253 | je .exit |
252 | mov [net_10ms], eax |
254 | mov [net_10ms], eax |
253 | 255 | ||
254 | test [net_10ms], 0x0f ; 160ms |
256 | test [net_10ms], 0x0f ; 160ms |
255 | jnz .exit |
257 | jnz .exit |
256 | 258 | ||
257 | TCP_timer_160ms |
259 | TCP_timer_160ms |
258 | 260 | ||
259 | test [net_10ms], 0x3f ; 640ms |
261 | test [net_10ms], 0x3f ; 640ms |
260 | jnz .exit |
262 | jnz .exit |
261 | 263 | ||
262 | TCP_timer_640ms |
264 | TCP_timer_640ms |
263 | ARP_decrease_entry_ttls |
265 | ARP_decrease_entry_ttls |
264 | IPv4_decrease_fragment_ttls |
266 | IPv4_decrease_fragment_ttls |
265 | 267 | ||
266 | .exit: |
268 | .exit: |
267 | ret |
269 | ret |
268 | 270 | ||
269 | 271 | ||
270 | 272 | ||
271 | ;----------------------------------------------------------------- |
273 | ;----------------------------------------------------------------- |
272 | ; |
274 | ; |
273 | ; NET_add_device: |
275 | ; NET_add_device: |
274 | ; |
276 | ; |
275 | ; This function is called by the network drivers, |
277 | ; This function is called by the network drivers, |
276 | ; to register each running NIC to the kernel |
278 | ; to register each running NIC to the kernel |
277 | ; |
279 | ; |
278 | ; IN: Pointer to device structure in ebx |
280 | ; IN: Pointer to device structure in ebx |
279 | ; OUT: Device num in eax, -1 on error |
281 | ; OUT: Device num in eax, -1 on error |
280 | ; |
282 | ; |
281 | ;----------------------------------------------------------------- |
283 | ;----------------------------------------------------------------- |
282 | align 4 |
284 | align 4 |
283 | NET_add_device: |
285 | NET_add_device: |
284 | 286 | ||
285 | DEBUGF 1,"NET_Add_Device: %x\n", ebx ;;; TODO: use mutex to lock net device list |
287 | DEBUGF 1,"NET_Add_Device: %x\n", ebx ;;; TODO: use mutex to lock net device list |
286 | 288 | ||
287 | mov eax, [NET_RUNNING] |
289 | mov eax, [NET_RUNNING] |
288 | cmp eax, MAX_NET_DEVICES |
290 | cmp eax, MAX_NET_DEVICES |
289 | jae .error |
291 | jae .error |
290 | 292 | ||
291 | ;---------------------------------- |
293 | ;---------------------------------- |
292 | ; Check if device is already listed |
294 | ; Check if device is already listed |
293 | mov eax, ebx |
295 | mov eax, ebx |
294 | mov ecx, MAX_NET_DEVICES ; We need to check whole list because a device may be removed without re-organizing list |
296 | mov ecx, MAX_NET_DEVICES ; We need to check whole list because a device may be removed without re-organizing list |
295 | mov edi, NET_DRV_LIST |
297 | mov edi, NET_DRV_LIST |
296 | 298 | ||
297 | repne scasd ; See if device is already in the list |
299 | repne scasd ; See if device is already in the list |
298 | jz .error |
300 | jz .error |
299 | 301 | ||
300 | ;---------------------------- |
302 | ;---------------------------- |
301 | ; Find empty slot in the list |
303 | ; Find empty slot in the list |
302 | xor eax, eax |
304 | xor eax, eax |
303 | mov ecx, MAX_NET_DEVICES |
305 | mov ecx, MAX_NET_DEVICES |
304 | mov edi, NET_DRV_LIST |
306 | mov edi, NET_DRV_LIST |
305 | 307 | ||
306 | repne scasd |
308 | repne scasd |
307 | jnz .error |
309 | jnz .error |
308 | 310 | ||
309 | sub edi, 4 |
311 | sub edi, 4 |
310 | 312 | ||
311 | ;----------------------------- |
313 | ;----------------------------- |
312 | ; Add device to the found slot |
314 | ; Add device to the found slot |
313 | mov [edi], ebx ; add device to list |
315 | mov [edi], ebx ; add device to list |
314 | 316 | ||
315 | mov eax, edi ; Calculate device number in eax |
317 | mov eax, edi ; Calculate device number in eax |
316 | sub eax, NET_DRV_LIST |
318 | sub eax, NET_DRV_LIST |
317 | shr eax, 2 |
319 | shr eax, 2 |
318 | 320 | ||
319 | inc [NET_RUNNING] ; Indicate that one more network device is up and running |
321 | inc [NET_RUNNING] ; Indicate that one more network device is up and running |
320 | 322 | ||
321 | cmp eax, 1 ; If it's the first network device, try to set it as default |
323 | cmp eax, 1 ; If it's the first network device, try to set it as default |
322 | jne @f |
324 | jne @f |
323 | push eax |
325 | push eax |
324 | call NET_set_default |
326 | call NET_set_default |
325 | pop eax |
327 | pop eax |
326 | @@: |
328 | @@: |
327 | 329 | ||
328 | DEBUGF 1,"Device number: %u\n", eax |
330 | DEBUGF 1,"Device number: %u\n", eax |
329 | ret |
331 | ret |
330 | 332 | ||
331 | .error: |
333 | .error: |
332 | or eax, -1 |
334 | or eax, -1 |
333 | DEBUGF 2,"Adding network device failed\n" |
335 | DEBUGF 2,"Adding network device failed\n" |
334 | ret |
336 | ret |
335 | 337 | ||
336 | 338 | ||
337 | 339 | ||
338 | ;----------------------------------------------------------------- |
340 | ;----------------------------------------------------------------- |
339 | ; |
341 | ; |
340 | ; NET_set_default |
342 | ; NET_set_default |
341 | ; |
343 | ; |
342 | ; API to set the default interface |
344 | ; API to set the default interface |
343 | ; |
345 | ; |
344 | ; IN: Device num in eax |
346 | ; IN: Device num in eax |
345 | ; OUT: Device num in eax, -1 on error |
347 | ; OUT: Device num in eax, -1 on error |
346 | ; |
348 | ; |
347 | ;----------------------------------------------------------------- |
349 | ;----------------------------------------------------------------- |
348 | align 4 |
350 | align 4 |
349 | NET_set_default: |
351 | NET_set_default: |
350 | 352 | ||
351 | DEBUGF 1,"NET_set_default: device=%x\n", eax |
353 | DEBUGF 1,"NET_set_default: device=%x\n", eax |
352 | 354 | ||
353 | cmp eax, MAX_NET_DEVICES |
355 | cmp eax, MAX_NET_DEVICES |
354 | jae .error |
356 | jae .error |
355 | 357 | ||
356 | cmp [NET_DRV_LIST+eax*4], 0 |
358 | cmp [NET_DRV_LIST+eax*4], 0 |
357 | je .error |
359 | je .error |
358 | 360 | ||
359 | mov [NET_DEFAULT], eax |
361 | mov [NET_DEFAULT], eax |
360 | 362 | ||
361 | DEBUGF 1,"NET_set_default: succes\n" |
363 | DEBUGF 1,"NET_set_default: succes\n" |
362 | ret |
364 | ret |
363 | 365 | ||
364 | .error: |
366 | .error: |
365 | or eax, -1 |
367 | or eax, -1 |
366 | DEBUGF 1,"NET_set_default: failed\n" |
368 | DEBUGF 1,"NET_set_default: failed\n" |
367 | ret |
369 | ret |
368 | 370 | ||
369 | 371 | ||
370 | ;----------------------------------------------------------------- |
372 | ;----------------------------------------------------------------- |
371 | ; |
373 | ; |
372 | ; NET_Remove_Device: |
374 | ; NET_Remove_Device: |
373 | ; |
375 | ; |
374 | ; This function is called by etwork drivers, |
376 | ; This function is called by etwork drivers, |
375 | ; to unregister network devices from the kernel |
377 | ; to unregister network devices from the kernel |
376 | ; |
378 | ; |
377 | ; IN: Pointer to device structure in ebx |
379 | ; IN: Pointer to device structure in ebx |
378 | ; OUT: eax: -1 on error |
380 | ; OUT: eax: -1 on error |
379 | ; |
381 | ; |
380 | ;----------------------------------------------------------------- |
382 | ;----------------------------------------------------------------- |
381 | align 4 |
383 | align 4 |
382 | NET_remove_device: |
384 | NET_remove_device: |
383 | 385 | ||
384 | cmp [NET_RUNNING], 0 |
386 | cmp [NET_RUNNING], 0 |
385 | je .error |
387 | je .error |
386 | 388 | ||
387 | cmp [NET_DRV_LIST], ebx |
389 | cmp [NET_DRV_LIST], ebx |
388 | jne @f |
390 | jne @f |
389 | mov [NET_DRV_LIST], 0 |
391 | mov [NET_DRV_LIST], 0 |
390 | cmp [NET_RUNNING], 1 |
392 | cmp [NET_RUNNING], 1 |
391 | je @f |
393 | je @f |
392 | ; there are still active devices, find one and make it default |
394 | ; there are still active devices, find one and make it default |
393 | xor eax, eax |
395 | xor eax, eax |
394 | mov ecx, MAX_NET_DEVICES |
396 | mov ecx, MAX_NET_DEVICES |
395 | mov edi, NET_DRV_LIST |
397 | mov edi, NET_DRV_LIST |
396 | repe scasd |
398 | repe scasd |
397 | je @f |
399 | je @f |
398 | shr edi, 2 |
400 | shr edi, 2 |
399 | dec edi |
401 | dec edi |
400 | mov [NET_DEFAULT], edi |
402 | mov [NET_DEFAULT], edi |
401 | @@: |
403 | @@: |
402 | 404 | ||
403 | ;---------------------------- |
405 | ;---------------------------- |
404 | ; Find the driver in the list |
406 | ; Find the driver in the list |
405 | 407 | ||
406 | mov eax, ebx |
408 | mov eax, ebx |
407 | mov ecx, MAX_NET_DEVICES |
409 | mov ecx, MAX_NET_DEVICES |
408 | mov edi, NET_DRV_LIST+4 |
410 | mov edi, NET_DRV_LIST+4 |
409 | 411 | ||
410 | repne scasd |
412 | repne scasd |
411 | jnz .error |
413 | jnz .error |
412 | 414 | ||
413 | ;------------------------ |
415 | ;------------------------ |
414 | ; Remove it from the list |
416 | ; Remove it from the list |
415 | 417 | ||
416 | xor eax, eax |
418 | xor eax, eax |
417 | mov dword [edi-4], eax |
419 | mov dword [edi-4], eax |
418 | 420 | ||
419 | dec [NET_RUNNING] |
421 | dec [NET_RUNNING] |
420 | ret |
422 | ret |
421 | 423 | ||
422 | .error: |
424 | .error: |
423 | or eax, -1 |
425 | or eax, -1 |
424 | ret |
426 | ret |
425 | 427 | ||
426 | 428 | ||
427 | 429 | ||
428 | ;----------------------------------------------------------------- |
430 | ;----------------------------------------------------------------- |
429 | ; |
431 | ; |
430 | ; NET_ptr_to_num |
432 | ; NET_ptr_to_num |
431 | ; |
433 | ; |
432 | ; IN: ebx = ptr to device struct |
434 | ; IN: ebx = ptr to device struct |
433 | ; OUT: edi = -1 on error, device number otherwise |
435 | ; OUT: edi = -1 on error, device number otherwise |
434 | ; |
436 | ; |
435 | ;----------------------------------------------------------------- |
437 | ;----------------------------------------------------------------- |
436 | align 4 |
438 | align 4 |
437 | NET_ptr_to_num: |
439 | NET_ptr_to_num: |
438 | push ecx |
440 | push ecx |
439 | 441 | ||
440 | mov ecx, MAX_NET_DEVICES |
442 | mov ecx, MAX_NET_DEVICES |
441 | mov edi, NET_DRV_LIST |
443 | mov edi, NET_DRV_LIST |
442 | 444 | ||
443 | .loop: |
445 | .loop: |
444 | cmp ebx, [edi] |
446 | cmp ebx, [edi] |
445 | jz .found |
447 | jz .found |
446 | add edi, 4 |
448 | add edi, 4 |
447 | dec ecx |
449 | dec ecx |
448 | jnz .loop |
450 | jnz .loop |
449 | 451 | ||
450 | ; repnz scasd could work too if eax is used instead of ebx! |
452 | ; repnz scasd could work too if eax is used instead of ebx! |
451 | 453 | ||
452 | or edi, -1 |
454 | or edi, -1 |
453 | 455 | ||
454 | pop ecx |
456 | pop ecx |
455 | ret |
457 | ret |
456 | 458 | ||
457 | .found: |
459 | .found: |
458 | sub edi, NET_DRV_LIST |
460 | sub edi, NET_DRV_LIST |
459 | shr edi, 2 |
461 | shr edi, 2 |
460 | 462 | ||
461 | pop ecx |
463 | pop ecx |
462 | ret |
464 | ret |
463 | 465 | ||
464 | ;----------------------------------------------------------------- |
466 | ;----------------------------------------------------------------- |
465 | ; |
467 | ; |
466 | ; checksum_1 |
468 | ; checksum_1 |
467 | ; |
469 | ; |
468 | ; This is the first of two functions needed to calculate a checksum. |
470 | ; This is the first of two functions needed to calculate a checksum. |
469 | ; |
471 | ; |
470 | ; IN: edx = start offset for semi-checksum |
472 | ; IN: edx = start offset for semi-checksum |
471 | ; esi = pointer to data |
473 | ; esi = pointer to data |
472 | ; ecx = data size |
474 | ; ecx = data size |
473 | ; OUT: edx = semi-checksum |
475 | ; OUT: edx = semi-checksum |
474 | ; |
476 | ; |
475 | ; |
477 | ; |
476 | ; Code was optimized by diamond |
478 | ; Code was optimized by diamond |
477 | ; |
479 | ; |
478 | ;----------------------------------------------------------------- |
480 | ;----------------------------------------------------------------- |
479 | align 4 |
481 | align 4 |
480 | checksum_1: |
482 | checksum_1: |
481 | 483 | ||
482 | shr ecx, 1 |
484 | shr ecx, 1 |
483 | pushf |
485 | pushf |
484 | jz .no_2 |
486 | jz .no_2 |
485 | 487 | ||
486 | shr ecx, 1 |
488 | shr ecx, 1 |
487 | pushf |
489 | pushf |
488 | jz .no_4 |
490 | jz .no_4 |
489 | 491 | ||
490 | shr ecx, 1 |
492 | shr ecx, 1 |
491 | pushf |
493 | pushf |
492 | jz .no_8 |
494 | jz .no_8 |
493 | 495 | ||
494 | .loop: |
496 | .loop: |
495 | add dl, [esi+1] |
497 | add dl, [esi+1] |
496 | adc dh, [esi+0] |
498 | adc dh, [esi+0] |
497 | 499 | ||
498 | adc dl, [esi+3] |
500 | adc dl, [esi+3] |
499 | adc dh, [esi+2] |
501 | adc dh, [esi+2] |
500 | 502 | ||
501 | adc dl, [esi+5] |
503 | adc dl, [esi+5] |
502 | adc dh, [esi+4] |
504 | adc dh, [esi+4] |
503 | 505 | ||
504 | adc dl, [esi+7] |
506 | adc dl, [esi+7] |
505 | adc dh, [esi+6] |
507 | adc dh, [esi+6] |
506 | 508 | ||
507 | adc edx, 0 |
509 | adc edx, 0 |
508 | add esi, 8 |
510 | add esi, 8 |
509 | 511 | ||
510 | dec ecx |
512 | dec ecx |
511 | jnz .loop |
513 | jnz .loop |
512 | 514 | ||
513 | adc edx, 0 |
515 | adc edx, 0 |
514 | 516 | ||
515 | .no_8: |
517 | .no_8: |
516 | popf |
518 | popf |
517 | jnc .no_4 |
519 | jnc .no_4 |
518 | 520 | ||
519 | add dl, [esi+1] |
521 | add dl, [esi+1] |
520 | adc dh, [esi+0] |
522 | adc dh, [esi+0] |
521 | 523 | ||
522 | adc dl, [esi+3] |
524 | adc dl, [esi+3] |
523 | adc dh, [esi+2] |
525 | adc dh, [esi+2] |
524 | 526 | ||
525 | adc edx, 0 |
527 | adc edx, 0 |
526 | add esi, 4 |
528 | add esi, 4 |
527 | 529 | ||
528 | .no_4: |
530 | .no_4: |
529 | popf |
531 | popf |
530 | jnc .no_2 |
532 | jnc .no_2 |
531 | 533 | ||
532 | add dl, [esi+1] |
534 | add dl, [esi+1] |
533 | adc dh, [esi+0] |
535 | adc dh, [esi+0] |
534 | 536 | ||
535 | adc edx, 0 |
537 | adc edx, 0 |
536 | inc esi |
538 | inc esi |
537 | inc esi |
539 | inc esi |
538 | 540 | ||
539 | .no_2: |
541 | .no_2: |
540 | popf |
542 | popf |
541 | jnc .end |
543 | jnc .end |
542 | 544 | ||
543 | add dh, [esi+0] |
545 | add dh, [esi+0] |
544 | adc edx, 0 |
546 | adc edx, 0 |
545 | .end: |
547 | .end: |
546 | ret |
548 | ret |
547 | 549 | ||
548 | ;----------------------------------------------------------------- |
550 | ;----------------------------------------------------------------- |
549 | ; |
551 | ; |
550 | ; checksum_2 |
552 | ; checksum_2 |
551 | ; |
553 | ; |
552 | ; This function calculates the final ip/tcp/udp checksum for you |
554 | ; This function calculates the final ip/tcp/udp checksum for you |
553 | ; |
555 | ; |
554 | ; IN: edx = semi-checksum |
556 | ; IN: edx = semi-checksum |
555 | ; OUT: dx = checksum (in INET byte order) |
557 | ; OUT: dx = checksum (in INET byte order) |
556 | ; |
558 | ; |
557 | ;----------------------------------------------------------------- |
559 | ;----------------------------------------------------------------- |
558 | align 4 |
560 | align 4 |
559 | checksum_2: |
561 | checksum_2: |
560 | 562 | ||
561 | mov ecx, edx |
563 | mov ecx, edx |
562 | shr ecx, 16 |
564 | shr ecx, 16 |
563 | and edx, 0xffff |
565 | and edx, 0xffff |
564 | add edx, ecx |
566 | add edx, ecx |
565 | 567 | ||
566 | mov ecx, edx |
568 | mov ecx, edx |
567 | shr ecx, 16 |
569 | shr ecx, 16 |
568 | add dx, cx |
570 | add dx, cx |
569 | test dx, dx ; it seems that ZF is not set when CF is set :( |
571 | test dx, dx ; it seems that ZF is not set when CF is set :( |
570 | not dx |
572 | not dx |
571 | jnz .not_zero |
573 | jnz .not_zero |
572 | dec dx |
574 | dec dx |
573 | .not_zero: |
575 | .not_zero: |
574 | xchg dl, dh |
576 | xchg dl, dh |
575 | 577 | ||
576 | DEBUGF 1,"Checksum: %x\n", dx |
578 | DEBUGF 1,"Checksum: %x\n", dx |
577 | 579 | ||
578 | ret |
580 | ret |
579 | 581 | ||
580 | 582 | ||
581 | 583 | ||
582 | ;---------------------------------------------------------------- |
584 | ;---------------------------------------------------------------- |
583 | ; |
585 | ; |
584 | ; System function to work with network devices (73) |
586 | ; System function to work with network devices (73) |
585 | ; |
587 | ; |
586 | ;---------------------------------------------------------------- |
588 | ;---------------------------------------------------------------- |
587 | align 4 |
589 | align 4 |
588 | sys_network: ; FIXME: make default device easily accessible |
590 | sys_network: ; FIXME: make default device easily accessible |
589 | 591 | ||
590 | cmp ebx, -1 |
592 | cmp ebx, -1 |
591 | jne @f |
593 | jne @f |
592 | 594 | ||
593 | mov eax, [NET_RUNNING] |
595 | mov eax, [NET_RUNNING] |
594 | jmp .return |
596 | jmp .return |
595 | 597 | ||
596 | @@: |
598 | @@: |
597 | cmp bh, MAX_NET_DEVICES ; Check if device number exists |
599 | cmp bh, MAX_NET_DEVICES ; Check if device number exists |
598 | jae .doesnt_exist |
600 | jae .doesnt_exist |
599 | 601 | ||
600 | mov esi, ebx |
602 | mov esi, ebx |
601 | and esi, 0x0000ff00 |
603 | and esi, 0x0000ff00 |
602 | shr esi, 6 |
604 | shr esi, 6 |
603 | 605 | ||
604 | cmp dword [esi + NET_DRV_LIST], 0 ; check if driver is running |
606 | cmp dword [esi + NET_DRV_LIST], 0 ; check if driver is running |
605 | je .doesnt_exist |
607 | je .doesnt_exist |
606 | 608 | ||
607 | mov eax, [esi + NET_DRV_LIST] |
609 | mov eax, [esi + NET_DRV_LIST] |
608 | 610 | ||
609 | and ebx, 0x000000ff |
611 | and ebx, 0x000000ff |
610 | cmp ebx, .number |
612 | cmp ebx, .number |
611 | ja .doesnt_exist |
613 | ja .doesnt_exist |
612 | jmp dword [.table + 4*ebx] |
614 | jmp dword [.table + 4*ebx] |
613 | 615 | ||
614 | .table: |
616 | .table: |
615 | dd .get_type ; 0 |
617 | dd .get_type ; 0 |
616 | dd .get_dev_name ; 1 |
618 | dd .get_dev_name ; 1 |
617 | dd .reset ; 2 |
619 | dd .reset ; 2 |
618 | dd .stop ; 3 |
620 | dd .stop ; 3 |
619 | dd .get_ptr ; 4 |
621 | dd .get_ptr ; 4 |
620 | dd .get_drv_name ; 5 |
622 | dd .get_drv_name ; 5 |
621 | dd .set_default ; 6 |
623 | dd .set_default ; 6 |
622 | .number = ($ - .table) / 4 - 1 |
624 | .number = ($ - .table) / 4 - 1 |
623 | 625 | ||
624 | .get_type: ; 0 = Get device type (ethernet/token ring/...) |
626 | .get_type: ; 0 = Get device type (ethernet/token ring/...) |
625 | 627 | ||
626 | mov eax, [eax + NET_DEVICE.type] |
628 | mov eax, [eax + NET_DEVICE.type] |
627 | jmp .return |
629 | jmp .return |
628 | 630 | ||
629 | 631 | ||
630 | .get_dev_name: ; 1 = Get device name |
632 | .get_dev_name: ; 1 = Get device name |
631 | 633 | ||
632 | mov esi, [eax + NET_DEVICE.name] |
634 | mov esi, [eax + NET_DEVICE.name] |
633 | mov edi, ecx |
635 | mov edi, ecx |
634 | 636 | ||
635 | mov ecx, 64/4 ; max length |
637 | mov ecx, 64/4 ; max length |
636 | rep movsd |
638 | rep movsd |
637 | 639 | ||
638 | xor eax, eax |
640 | xor eax, eax |
639 | jmp .return |
641 | jmp .return |
640 | 642 | ||
641 | .reset: ; 2 = Reset the device |
643 | .reset: ; 2 = Reset the device |
642 | 644 | ||
643 | call [eax + NET_DEVICE.reset] |
645 | call [eax + NET_DEVICE.reset] |
644 | jmp .return |
646 | jmp .return |
645 | 647 | ||
646 | .stop: ; 3 = Stop driver for this device |
648 | .stop: ; 3 = Stop driver for this device |
647 | 649 | ||
648 | call [eax + NET_DEVICE.unload] |
650 | call [eax + NET_DEVICE.unload] |
649 | jmp .return |
651 | jmp .return |
650 | 652 | ||
651 | 653 | ||
652 | .get_ptr: ; 4 = Get driver pointer |
654 | .get_ptr: ; 4 = Get driver pointer |
653 | 655 | ||
654 | jmp .return |
656 | jmp .return |
655 | 657 | ||
656 | 658 | ||
657 | .get_drv_name: ; 5 = Get driver name |
659 | .get_drv_name: ; 5 = Get driver name |
658 | 660 | ||
659 | xor eax, eax |
661 | xor eax, eax |
660 | jmp .return |
662 | jmp .return |
661 | 663 | ||
662 | 664 | ||
663 | .set_default: ; 6 = Set default device |
665 | .set_default: ; 6 = Set default device |
664 | 666 | ||
665 | call NET_set_default |
667 | call NET_set_default |
666 | jmp .return |
668 | jmp .return |
667 | 669 | ||
668 | .doesnt_exist: |
670 | .doesnt_exist: |
669 | mov eax, -1 |
671 | mov eax, -1 |
670 | 672 | ||
671 | .return: |
673 | .return: |
672 | mov [esp+32], eax |
674 | mov [esp+32], eax |
673 | ret |
675 | ret |
674 | 676 | ||
675 | 677 | ||
676 | ;---------------------------------------------------------------- |
678 | ;---------------------------------------------------------------- |
677 | ; |
679 | ; |
678 | ; System function to work with protocols (76) |
680 | ; System function to work with protocols (76) |
679 | ; |
681 | ; |
680 | ;---------------------------------------------------------------- |
682 | ;---------------------------------------------------------------- |
681 | align 4 |
683 | align 4 |
682 | sys_protocols: |
684 | sys_protocols: |
683 | cmp bh, MAX_NET_DEVICES ; Check if device number exists |
685 | cmp bh, MAX_NET_DEVICES ; Check if device number exists |
684 | jae .doesnt_exist |
686 | jae .doesnt_exist |
685 | 687 | ||
686 | mov esi, ebx |
688 | mov esi, ebx |
687 | and esi, 0x0000ff00 |
689 | and esi, 0x0000ff00 |
688 | shr esi, 6 ; now we have the device num * 4 in esi |
690 | shr esi, 6 ; now we have the device num * 4 in esi |
689 | cmp [esi + NET_DRV_LIST], 0 ; check if driver is running |
691 | cmp [esi + NET_DRV_LIST], 0 ; check if driver is running |
690 | je .doesnt_exist |
692 | je .doesnt_exist |
691 | 693 | ||
692 | push .return ; return address (we will be using jumps instead of calls) |
694 | push .return ; return address (we will be using jumps instead of calls) |
693 | 695 | ||
694 | mov eax, ebx ; set ax to protocol number |
696 | mov eax, ebx ; set ax to protocol number |
695 | shr eax, 16 ; |
697 | shr eax, 16 ; |
696 | 698 | ||
697 | cmp ax, API_ETH |
699 | cmp ax, API_ETH |
698 | je ETH_api |
700 | je ETH_api |
699 | 701 | ||
700 | cmp ax, API_IPv4 |
702 | cmp ax, API_IPv4 |
701 | je IPv4_api |
703 | je IPv4_api |
702 | 704 | ||
703 | cmp ax, API_ICMP |
705 | cmp ax, API_ICMP |
704 | je ICMP_api |
706 | je ICMP_api |
705 | 707 | ||
706 | cmp ax, API_UDP |
708 | cmp ax, API_UDP |
707 | je UDP_api |
709 | je UDP_api |
708 | 710 | ||
709 | cmp ax, API_TCP |
711 | cmp ax, API_TCP |
710 | je TCP_api |
712 | je TCP_api |
711 | 713 | ||
712 | cmp ax, API_ARP |
714 | cmp ax, API_ARP |
713 | je ARP_api |
715 | je ARP_api |
714 | 716 | ||
715 | ; cmp ax, API_PPPOE |
717 | ; cmp ax, API_PPPOE |
716 | ; je PPPoE_api |
718 | ; je PPPoE_api |
717 | 719 | ||
718 | add esp, 4 ; if we reached here, no function was called, so we need to balance stack |
720 | add esp, 4 ; if we reached here, no function was called, so we need to balance stack |
719 | 721 | ||
720 | .doesnt_exist: |
722 | .doesnt_exist: |
721 | mov eax, -1 |
723 | mov eax, -1 |
722 | 724 | ||
723 | .return: |
725 | .return: |
724 | mov [esp+28+4], eax ; return eax value to the program |
726 | mov [esp+28+4], eax ; return eax value to the program |
725 | ret |
727 | ret |
726 | 728 | ||
727 | 729 | ||
728 | __DEBUG_LEVEL__ equ __DEBUG_LEVEL_OLD__ |
730 | __DEBUG_LEVEL__ equ __DEBUG_LEVEL_OLD__ |