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