Rev 6413 | Rev 7679 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6413 | Rev 6476 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2016. 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: 6413 $ |
24 | $Revision: 6476 $ |
25 | 25 | ||
26 | uglobal |
26 | uglobal |
27 | net_10ms dd ? |
27 | net_10ms dd ? |
28 | net_tmr_count dw ? |
28 | net_tmr_count dw ? |
29 | endg |
29 | endg |
30 | 30 | ||
31 | DEBUG_NETWORK_ERROR = 1 |
31 | DEBUG_NETWORK_ERROR = 1 |
32 | DEBUG_NETWORK_VERBOSE = 0 |
32 | DEBUG_NETWORK_VERBOSE = 0 |
33 | 33 | ||
34 | NET_DEVICES_MAX = 16 |
34 | NET_DEVICES_MAX = 16 |
35 | NET_BUFFERS = 512 |
35 | NET_BUFFERS = 512 |
36 | NET_BUFFER_SIZE = 2048 |
36 | NET_BUFFER_SIZE = 2048 |
37 | ARP_BLOCK = 1 ; true or false |
37 | ARP_BLOCK = 1 ; true or false |
38 | 38 | ||
39 | EPHEMERAL_PORT_MIN = 49152 |
39 | EPHEMERAL_PORT_MIN = 49152 |
40 | EPHEMERAL_PORT_MAX = 61000 |
40 | EPHEMERAL_PORT_MAX = 61000 |
41 | MIN_EPHEMERAL_PORT_N = 0x00C0 ; same in Network byte order (FIXME) |
41 | MIN_EPHEMERAL_PORT_N = 0x00C0 ; same in Network byte order (FIXME) |
42 | MAX_EPHEMERAL_PORT_N = 0x48EE ; same in Network byte order (FIXME) |
42 | MAX_EPHEMERAL_PORT_N = 0x48EE ; same in Network byte order (FIXME) |
43 | 43 | ||
44 | ; Ethernet protocol numbers |
44 | ; Ethernet protocol numbers |
45 | ETHER_PROTO_ARP = 0x0608 |
45 | ETHER_PROTO_ARP = 0x0608 |
46 | ETHER_PROTO_IPv4 = 0x0008 |
46 | ETHER_PROTO_IPv4 = 0x0008 |
47 | ETHER_PROTO_IPv6 = 0xDD86 |
47 | ETHER_PROTO_IPv6 = 0xDD86 |
48 | ETHER_PROTO_PPP_DISCOVERY = 0x6388 |
48 | ETHER_PROTO_PPP_DISCOVERY = 0x6388 |
49 | ETHER_PROTO_PPP_SESSION = 0x6488 |
49 | ETHER_PROTO_PPP_SESSION = 0x6488 |
50 | 50 | ||
51 | ; Internet protocol numbers |
51 | ; Internet protocol numbers |
52 | IP_PROTO_IP = 0 |
52 | IP_PROTO_IP = 0 |
53 | IP_PROTO_ICMP = 1 |
53 | IP_PROTO_ICMP = 1 |
54 | IP_PROTO_TCP = 6 |
54 | IP_PROTO_TCP = 6 |
55 | IP_PROTO_UDP = 17 |
55 | IP_PROTO_UDP = 17 |
56 | IP_PROTO_RAW = 255 |
56 | IP_PROTO_RAW = 255 |
57 | 57 | ||
58 | ; IP options |
58 | ; IP options |
59 | IP_TOS = 1 |
59 | IP_TOS = 1 |
60 | IP_TTL = 2 |
60 | IP_TTL = 2 |
61 | IP_HDRINCL = 3 |
61 | IP_HDRINCL = 3 |
62 | 62 | ||
63 | ; PPP protocol numbers |
63 | ; PPP protocol numbers |
64 | PPP_PROTO_IPv4 = 0x2100 |
64 | PPP_PROTO_IPv4 = 0x2100 |
65 | PPP_PROTO_IPV6 = 0x5780 |
65 | PPP_PROTO_IPV6 = 0x5780 |
66 | PPP_PROTO_ETHERNET = 666 ; FIXME |
66 | PPP_PROTO_ETHERNET = 666 ; FIXME |
67 | 67 | ||
68 | ;Protocol family |
68 | ;Protocol family |
69 | AF_UNSPEC = 0 |
69 | AF_UNSPEC = 0 |
70 | AF_LOCAL = 1 |
70 | AF_LOCAL = 1 |
71 | AF_INET4 = 2 |
71 | AF_INET4 = 2 |
72 | AF_INET6 = 10 |
72 | AF_INET6 = 10 |
73 | AF_PPP = 777 ; FIXME |
73 | AF_PPP = 777 ; FIXME |
74 | 74 | ||
75 | ; Socket types |
75 | ; Socket types |
76 | SOCK_STREAM = 1 |
76 | SOCK_STREAM = 1 |
77 | SOCK_DGRAM = 2 |
77 | SOCK_DGRAM = 2 |
78 | SOCK_RAW = 3 |
78 | SOCK_RAW = 3 |
79 | 79 | ||
80 | ; Socket level |
80 | ; Socket level |
81 | SOL_SOCKET = 0xffff |
81 | SOL_SOCKET = 0xffff |
82 | 82 | ||
83 | ; Socket options |
83 | ; Socket options |
84 | SO_ACCEPTCON = 1 shl 0 |
84 | SO_ACCEPTCON = 1 shl 0 |
85 | SO_BROADCAST = 1 shl 1 |
85 | SO_BROADCAST = 1 shl 1 |
86 | SO_DEBUG = 1 shl 2 |
86 | SO_DEBUG = 1 shl 2 |
87 | SO_DONTROUTE = 1 shl 3 |
87 | SO_DONTROUTE = 1 shl 3 |
88 | SO_KEEPALIVE = 1 shl 4 |
88 | SO_KEEPALIVE = 1 shl 4 |
89 | SO_OOBINLINE = 1 shl 5 |
89 | SO_OOBINLINE = 1 shl 5 |
90 | SO_REUSEADDR = 1 shl 6 |
90 | SO_REUSEADDR = 1 shl 6 |
91 | SO_REUSEPORT = 1 shl 7 |
91 | SO_REUSEPORT = 1 shl 7 |
92 | SO_USELOOPBACK = 1 shl 8 |
92 | SO_USELOOPBACK = 1 shl 8 |
93 | SO_BINDTODEVICE = 1 shl 9 |
93 | SO_BINDTODEVICE = 1 shl 9 |
- | 94 | SO_LINGER = 1 shl 10 |
|
94 | 95 | ||
95 | SO_NONBLOCK = 1 shl 31 |
96 | SO_NONBLOCK = 1 shl 31 |
96 | 97 | ||
97 | ; Socket flags for user calls |
98 | ; Socket flags for user calls |
98 | MSG_PEEK = 0x02 |
99 | MSG_PEEK = 0x02 |
99 | MSG_DONTWAIT = 0x40 |
100 | MSG_DONTWAIT = 0x40 |
100 | 101 | ||
101 | ; Socket States |
102 | ; Socket States |
102 | SS_NOFDREF = 0x0001 ; no file table ref any more |
103 | SS_NOFDREF = 0x0001 ; no file table ref any more |
103 | SS_ISCONNECTED = 0x0002 ; socket connected to a peer |
104 | SS_ISCONNECTED = 0x0002 ; socket connected to a peer |
104 | SS_ISCONNECTING = 0x0004 ; in process of connecting to peer |
105 | SS_ISCONNECTING = 0x0004 ; in process of connecting to peer |
105 | SS_ISDISCONNECTING = 0x0008 ; in process of disconnecting |
106 | SS_ISDISCONNECTING = 0x0008 ; in process of disconnecting |
106 | SS_CANTSENDMORE = 0x0010 ; can't send more data to peer |
107 | SS_CANTSENDMORE = 0x0010 ; can't send more data to peer |
107 | SS_CANTRCVMORE = 0x0020 ; can't receive more data from peer |
108 | SS_CANTRCVMORE = 0x0020 ; can't receive more data from peer |
108 | SS_RCVATMARK = 0x0040 ; at mark on input |
109 | SS_RCVATMARK = 0x0040 ; at mark on input |
109 | SS_ISABORTING = 0x0080 ; aborting fd references - close() |
110 | SS_ISABORTING = 0x0080 ; aborting fd references - close() |
110 | SS_RESTARTSYS = 0x0100 ; restart blocked system calls |
111 | SS_RESTARTSYS = 0x0100 ; restart blocked system calls |
111 | SS_ISDISCONNECTED = 0x0800 ; socket disconnected from peer |
112 | SS_ISDISCONNECTED = 0x0800 ; socket disconnected from peer |
112 | 113 | ||
113 | SS_ASYNC = 0x1000 ; async i/o notify |
114 | SS_ASYNC = 0x1000 ; async i/o notify |
114 | SS_ISCONFIRMING = 0x2000 ; deciding to accept connection req |
115 | SS_ISCONFIRMING = 0x2000 ; deciding to accept connection req |
115 | SS_MORETOCOME = 0x4000 |
116 | SS_MORETOCOME = 0x4000 |
116 | 117 | ||
117 | SS_BLOCKED = 0x8000 |
118 | SS_BLOCKED = 0x8000 |
118 | 119 | ||
119 | 120 | ||
120 | SOCKET_BUFFER_SIZE = 4096*8 ; must be 4096*(power of 2) where 'power of 2' is at least 8 |
121 | SOCKET_BUFFER_SIZE = 4096*8 ; must be 4096*(power of 2) where 'power of 2' is at least 8 |
121 | MAX_backlog = 20 ; maximum backlog for stream sockets |
122 | MAX_backlog = 20 ; maximum backlog for stream sockets |
122 | 123 | ||
123 | ; Error Codes |
124 | ; Error Codes |
124 | ENOBUFS = 1 |
125 | ENOBUFS = 1 |
125 | EINPROGRESS = 2 |
126 | EINPROGRESS = 2 |
126 | EOPNOTSUPP = 4 |
127 | EOPNOTSUPP = 4 |
127 | EWOULDBLOCK = 6 |
128 | EWOULDBLOCK = 6 |
128 | ENOTCONN = 9 |
129 | ENOTCONN = 9 |
129 | EALREADY = 10 |
130 | EALREADY = 10 |
130 | EINVAL = 11 |
131 | EINVAL = 11 |
131 | EMSGSIZE = 12 |
132 | EMSGSIZE = 12 |
132 | ENOMEM = 18 |
133 | ENOMEM = 18 |
133 | EADDRINUSE = 20 |
134 | EADDRINUSE = 20 |
134 | ECONNREFUSED = 61 |
135 | EADDRNOTAVAIL = 21 |
135 | ECONNRESET = 52 |
136 | ECONNRESET = 52 |
- | 137 | ECONNABORTED = 53 |
|
136 | EISCONN = 56 |
138 | EISCONN = 56 |
137 | ETIMEDOUT = 60 |
139 | ETIMEDOUT = 60 |
138 | ECONNABORTED = 53 |
140 | ECONNREFUSED = 61 |
139 | 141 | ||
140 | ; Api protocol numbers |
142 | ; Api protocol numbers |
141 | API_ETH = 0 |
143 | API_ETH = 0 |
142 | API_IPv4 = 1 |
144 | API_IPv4 = 1 |
143 | API_ICMP = 2 |
145 | API_ICMP = 2 |
144 | API_UDP = 3 |
146 | API_UDP = 3 |
145 | API_TCP = 4 |
147 | API_TCP = 4 |
146 | API_ARP = 5 |
148 | API_ARP = 5 |
147 | API_PPPOE = 6 |
149 | API_PPPOE = 6 |
148 | API_IPv6 = 7 |
150 | API_IPv6 = 7 |
149 | 151 | ||
150 | ; Network device types |
152 | ; Network device types |
151 | NET_DEVICE_LOOPBACK = 0 |
153 | NET_DEVICE_LOOPBACK = 0 |
152 | NET_DEVICE_ETH = 1 |
154 | NET_DEVICE_ETH = 1 |
153 | NET_DEVICE_SLIP = 2 |
155 | NET_DEVICE_SLIP = 2 |
154 | 156 | ||
155 | ; Network link types (link protocols) |
157 | ; Network link types (link protocols) |
156 | NET_LINK_LOOPBACK = 0 |
158 | NET_LINK_LOOPBACK = 0 |
157 | NET_LINK_MAC = 1 ; Media access control (ethernet, isdn, ...) |
159 | NET_LINK_MAC = 1 ; Media access control (ethernet, isdn, ...) |
158 | NET_LINK_PPP = 2 ; Point to Point Protocol (PPPoE, ...) |
160 | NET_LINK_PPP = 2 ; Point to Point Protocol (PPPoE, ...) |
159 | NET_LINK_IEEE802.11 = 3 ; IEEE 802.11 (WiFi) |
161 | NET_LINK_IEEE802.11 = 3 ; IEEE 802.11 (WiFi) |
160 | 162 | ||
161 | ; Hardware acceleration bits |
163 | ; Hardware acceleration bits |
162 | NET_HWACC_TCP_IPv4_IN = 1 shl 0 |
164 | NET_HWACC_TCP_IPv4_IN = 1 shl 0 |
163 | NET_HWACC_TCP_IPv4_OUT = 1 shl 1 |
165 | NET_HWACC_TCP_IPv4_OUT = 1 shl 1 |
164 | 166 | ||
165 | ; Network frame types |
167 | ; Network frame types |
166 | NET_BUFF_LOOPBACK = 0 |
168 | NET_BUFF_LOOPBACK = 0 |
167 | NET_BUFF_ETH = 1 |
169 | NET_BUFF_ETH = 1 |
168 | 170 | ||
169 | struct NET_DEVICE |
171 | struct NET_DEVICE |
170 | 172 | ||
171 | device_type dd ? ; Type field |
173 | device_type dd ? ; Type field |
172 | mtu dd ? ; Maximal Transmission Unit |
174 | mtu dd ? ; Maximal Transmission Unit |
173 | name dd ? ; Ptr to 0 terminated string |
175 | name dd ? ; Ptr to 0 terminated string |
174 | 176 | ||
175 | unload dd ? ; Ptrs to driver functions |
177 | unload dd ? ; Ptrs to driver functions |
176 | reset dd ? ; |
178 | reset dd ? ; |
177 | transmit dd ? ; |
179 | transmit dd ? ; |
178 | 180 | ||
179 | bytes_tx dq ? ; Statistics, updated by the driver |
181 | bytes_tx dq ? ; Statistics, updated by the driver |
180 | bytes_rx dq ? ; |
182 | bytes_rx dq ? ; |
181 | packets_tx dd ? ; |
183 | packets_tx dd ? ; |
182 | packets_rx dd ? ; |
184 | packets_rx dd ? ; |
183 | 185 | ||
184 | link_state dd ? ; link state (0 = no link) |
186 | link_state dd ? ; link state (0 = no link) |
185 | hwacc dd ? ; bitmask stating enabled HW accelerations (offload engines) |
187 | hwacc dd ? ; bitmask stating enabled HW accelerations (offload engines) |
186 | 188 | ||
187 | ends |
189 | ends |
188 | 190 | ||
189 | struct NET_BUFF |
191 | struct NET_BUFF |
190 | 192 | ||
191 | NextPtr dd ? ; pointer to next frame in list |
193 | NextPtr dd ? ; pointer to next frame in list |
192 | PrevPtr dd ? ; pointer to previous frame in list |
194 | PrevPtr dd ? ; pointer to previous frame in list |
193 | device dd ? ; ptr to NET_DEVICE structure |
195 | device dd ? ; ptr to NET_DEVICE structure |
194 | type dd ? ; encapsulation type: e.g. Ethernet |
196 | type dd ? ; encapsulation type: e.g. Ethernet |
195 | length dd ? ; size of encapsulated data |
197 | length dd ? ; size of encapsulated data |
196 | offset dd ? ; offset to actual data (24 bytes for default frame) |
198 | offset dd ? ; offset to actual data (24 bytes for default frame) |
197 | data rb 0 |
199 | data rb 0 |
198 | 200 | ||
199 | ends |
201 | ends |
200 | 202 | ||
201 | 203 | ||
202 | ; Exactly as it says.. |
204 | ; Exactly as it says.. |
203 | macro pseudo_random reg { |
205 | macro pseudo_random reg { |
204 | add reg, [esp] |
206 | add reg, [esp] |
205 | rol reg, 5 |
207 | rol reg, 5 |
206 | xor reg, [timer_ticks] |
208 | xor reg, [timer_ticks] |
207 | ; add reg, [CPU_FREQ] |
209 | ; add reg, [CPU_FREQ] |
208 | imul reg, 214013 |
210 | imul reg, 214013 |
209 | xor reg, 0xdeadbeef |
211 | xor reg, 0xdeadbeef |
210 | rol reg, 9 |
212 | rol reg, 9 |
211 | } |
213 | } |
212 | 214 | ||
213 | ; Network to Hardware byte order (dword) |
215 | ; Network to Hardware byte order (dword) |
214 | macro ntohd reg { |
216 | macro ntohd reg { |
215 | 217 | ||
216 | rol word reg, 8 |
218 | rol word reg, 8 |
217 | rol dword reg, 16 |
219 | rol dword reg, 16 |
218 | rol word reg , 8 |
220 | rol word reg , 8 |
219 | 221 | ||
220 | } |
222 | } |
221 | 223 | ||
222 | ; Network to Hardware byte order (word) |
224 | ; Network to Hardware byte order (word) |
223 | macro ntohw reg { |
225 | macro ntohw reg { |
224 | 226 | ||
225 | rol word reg, 8 |
227 | rol word reg, 8 |
226 | 228 | ||
227 | } |
229 | } |
228 | 230 | ||
229 | 231 | ||
230 | include "queue.inc" |
232 | include "queue.inc" |
231 | 233 | ||
232 | include "loopback.inc" |
234 | include "loopback.inc" |
233 | include "ethernet.inc" |
235 | include "ethernet.inc" |
234 | 236 | ||
235 | include "PPPoE.inc" |
237 | include "PPPoE.inc" |
236 | 238 | ||
237 | include "ARP.inc" |
239 | include "ARP.inc" |
238 | include "IPv4.inc" |
240 | include "IPv4.inc" |
239 | include "IPv6.inc" |
241 | include "IPv6.inc" |
240 | 242 | ||
241 | include "icmp.inc" |
243 | include "icmp.inc" |
242 | include "udp.inc" |
244 | include "udp.inc" |
243 | include "tcp.inc" |
245 | include "tcp.inc" |
244 | 246 | ||
245 | include "socket.inc" |
247 | include "socket.inc" |
246 | 248 | ||
247 | 249 | ||
248 | 250 | ||
249 | uglobal |
251 | uglobal |
250 | align 4 |
252 | align 4 |
251 | 253 | ||
252 | NET_RUNNING dd ? |
254 | NET_RUNNING dd ? |
253 | NET_DRV_LIST rd NET_DEVICES_MAX |
255 | NET_DRV_LIST rd NET_DEVICES_MAX |
254 | 256 | ||
255 | NET_BUFFS_FREE rd NET_BUFFERS |
257 | NET_BUFFS_FREE rd NET_BUFFERS |
256 | .current dd ? |
258 | .current dd ? |
257 | 259 | ||
258 | endg |
260 | endg |
259 | 261 | ||
260 | 262 | ||
261 | ;-----------------------------------------------------------------; |
263 | ;-----------------------------------------------------------------; |
262 | ; ; |
264 | ; ; |
263 | ; stack_init: Initialize all network variables ; |
265 | ; stack_init: Initialize all network variables ; |
264 | ; ; |
266 | ; ; |
265 | ; IN: / ; |
267 | ; IN: / ; |
266 | ; OUT: / ; |
268 | ; OUT: / ; |
267 | ; ; |
269 | ; ; |
268 | ;-----------------------------------------------------------------; |
270 | ;-----------------------------------------------------------------; |
269 | align 4 |
271 | align 4 |
270 | stack_init: |
272 | stack_init: |
271 | 273 | ||
272 | ; allocate network buffers |
274 | ; allocate network buffers |
273 | stdcall kernel_alloc, NET_BUFFER_SIZE*NET_BUFFERS |
275 | stdcall kernel_alloc, NET_BUFFER_SIZE*NET_BUFFERS |
274 | test eax, eax |
276 | test eax, eax |
275 | jz .fail |
277 | jz .fail |
276 | 278 | ||
277 | mov edi, NET_BUFFS_FREE |
279 | mov edi, NET_BUFFS_FREE |
278 | mov ecx, NET_BUFFERS |
280 | mov ecx, NET_BUFFERS |
279 | cld |
281 | cld |
280 | .loop: |
282 | .loop: |
281 | stosd |
283 | stosd |
282 | add eax, NET_BUFFER_SIZE |
284 | add eax, NET_BUFFER_SIZE |
283 | dec ecx |
285 | dec ecx |
284 | jnz .loop |
286 | jnz .loop |
285 | 287 | ||
286 | mov eax, NET_BUFFS_FREE |
288 | mov eax, NET_BUFFS_FREE |
287 | stosd |
289 | stosd |
288 | 290 | ||
289 | ; Init the network drivers list |
291 | ; Init the network drivers list |
290 | xor eax, eax |
292 | xor eax, eax |
291 | mov edi, NET_RUNNING |
293 | mov edi, NET_RUNNING |
292 | mov ecx, (NET_DEVICES_MAX + 1) |
294 | mov ecx, (NET_DEVICES_MAX + 1) |
293 | rep stosd |
295 | rep stosd |
294 | 296 | ||
295 | eth_init |
297 | eth_init |
296 | 298 | ||
297 | pppoe_init |
299 | pppoe_init |
298 | 300 | ||
299 | ipv4_init |
301 | ipv4_init |
300 | ; ipv6_init |
302 | ; ipv6_init |
301 | icmp_init |
303 | icmp_init |
302 | 304 | ||
303 | arp_init |
305 | arp_init |
304 | udp_init |
306 | udp_init |
305 | tcp_init |
307 | tcp_init |
306 | 308 | ||
307 | socket_init |
309 | socket_init |
308 | 310 | ||
309 | loop_init |
311 | loop_init |
310 | 312 | ||
311 | mov [net_tmr_count], 0 |
313 | mov [net_tmr_count], 0 |
312 | ret |
314 | ret |
313 | 315 | ||
314 | .fail: |
316 | .fail: |
315 | DEBUGF DEBUG_NETWORK_ERROR, "Stack init failed!\n" |
317 | DEBUGF DEBUG_NETWORK_ERROR, "Stack init failed!\n" |
316 | ret |
318 | ret |
317 | 319 | ||
318 | 320 | ||
319 | 321 | ||
320 | ; Wakeup every tick. |
322 | ; Wakeup every tick. |
321 | proc stack_handler_has_work? |
323 | proc stack_handler_has_work? |
322 | 324 | ||
323 | mov eax, [timer_ticks] |
325 | mov eax, [timer_ticks] |
324 | cmp eax, [net_10ms] |
326 | cmp eax, [net_10ms] |
325 | 327 | ||
326 | ret |
328 | ret |
327 | endp |
329 | endp |
328 | 330 | ||
329 | 331 | ||
330 | ;-----------------------------------------------------------------; |
332 | ;-----------------------------------------------------------------; |
331 | ; ; |
333 | ; ; |
332 | ; stack_handler: Network handlers called from os_loop. ; |
334 | ; stack_handler: Network handlers called from os_loop. ; |
333 | ; ; |
335 | ; ; |
334 | ; IN: / ; |
336 | ; IN: / ; |
335 | ; OUT: / ; |
337 | ; OUT: / ; |
336 | ; ; |
338 | ; ; |
337 | ;-----------------------------------------------------------------; |
339 | ;-----------------------------------------------------------------; |
338 | align 4 |
340 | align 4 |
339 | stack_handler: |
341 | stack_handler: |
340 | 342 | ||
341 | ; Test for 10ms tick |
343 | ; Test for 10ms tick |
342 | mov eax, [timer_ticks] |
344 | mov eax, [timer_ticks] |
343 | cmp eax, [net_10ms] |
345 | cmp eax, [net_10ms] |
344 | je .exit |
346 | je .exit |
345 | mov [net_10ms], eax |
347 | mov [net_10ms], eax |
346 | 348 | ||
347 | cmp [NET_RUNNING], 0 |
349 | cmp [NET_RUNNING], 0 |
348 | je .exit |
350 | je .exit |
349 | 351 | ||
350 | test [net_10ms], 0x0f ; 160ms |
352 | test [net_10ms], 0x0f ; 160ms |
351 | jnz .exit |
353 | jnz .exit |
352 | 354 | ||
353 | tcp_timer_160ms |
355 | tcp_timer_160ms |
354 | 356 | ||
355 | test [net_10ms], 0x3f ; 640ms |
357 | test [net_10ms], 0x3f ; 640ms |
356 | jnz .exit |
358 | jnz .exit |
357 | 359 | ||
358 | arp_decrease_entry_ttls |
360 | arp_decrease_entry_ttls |
359 | ipv4_decrease_fragment_ttls |
361 | ipv4_decrease_fragment_ttls |
360 | 362 | ||
361 | xor edx, edx |
363 | xor edx, edx |
362 | mov eax, [TCP_timer1_event] |
364 | mov eax, [TCP_timer1_event] |
363 | mov ebx, [eax + EVENT.id] |
365 | mov ebx, [eax + EVENT.id] |
364 | xor esi, esi |
366 | xor esi, esi |
365 | call raise_event |
367 | call raise_event |
366 | 368 | ||
367 | .exit: |
369 | .exit: |
368 | ret |
370 | ret |
369 | 371 | ||
370 | 372 | ||
371 | align 4 |
373 | align 4 |
372 | proc net_buff_alloc stdcall, buffersize |
374 | proc net_buff_alloc stdcall, buffersize |
373 | 375 | ||
374 | cmp [buffersize], NET_BUFFER_SIZE |
376 | cmp [buffersize], NET_BUFFER_SIZE |
375 | ja .too_large |
377 | ja .too_large |
376 | 378 | ||
377 | spin_lock_irqsave |
379 | spin_lock_irqsave |
378 | 380 | ||
379 | mov eax, [NET_BUFFS_FREE.current] |
381 | mov eax, [NET_BUFFS_FREE.current] |
380 | cmp eax, NET_BUFFS_FREE+NET_BUFFERS*4 |
382 | cmp eax, NET_BUFFS_FREE+NET_BUFFERS*4 |
381 | jae .out_of_mem |
383 | jae .out_of_mem |
382 | mov eax, [eax] |
384 | mov eax, [eax] |
383 | add [NET_BUFFS_FREE.current], 4 |
385 | add [NET_BUFFS_FREE.current], 4 |
384 | 386 | ||
385 | spin_unlock_irqrestore |
387 | spin_unlock_irqrestore |
386 | 388 | ||
387 | DEBUGF DEBUG_NETWORK_VERBOSE, "net_buff_alloc: 0x%x\n", eax |
389 | DEBUGF DEBUG_NETWORK_VERBOSE, "net_buff_alloc: 0x%x\n", eax |
388 | ret |
390 | ret |
389 | 391 | ||
390 | .out_of_mem: |
392 | .out_of_mem: |
391 | spin_unlock_irqrestore |
393 | spin_unlock_irqrestore |
392 | 394 | ||
393 | xor eax, eax |
395 | xor eax, eax |
394 | DEBUGF DEBUG_NETWORK_ERROR, "net_buff_alloc: out of mem!\n" |
396 | DEBUGF DEBUG_NETWORK_ERROR, "net_buff_alloc: out of mem!\n" |
395 | ret |
397 | ret |
396 | 398 | ||
397 | .too_large: |
399 | .too_large: |
398 | xor eax, eax |
400 | xor eax, eax |
399 | DEBUGF DEBUG_NETWORK_ERROR, "net_buff_alloc: too large!\n" |
401 | DEBUGF DEBUG_NETWORK_ERROR, "net_buff_alloc: too large!\n" |
400 | ret |
402 | ret |
401 | endp |
403 | endp |
402 | 404 | ||
403 | 405 | ||
404 | align 4 |
406 | align 4 |
405 | proc net_buff_free stdcall, buffer |
407 | proc net_buff_free stdcall, buffer |
406 | 408 | ||
407 | DEBUGF DEBUG_NETWORK_VERBOSE, "net_buff_free: 0x%x\n", [buffer] |
409 | DEBUGF DEBUG_NETWORK_VERBOSE, "net_buff_free: 0x%x\n", [buffer] |
408 | 410 | ||
409 | spin_lock_irqsave |
411 | spin_lock_irqsave |
410 | 412 | ||
411 | sub [NET_BUFFS_FREE.current], 4 |
413 | sub [NET_BUFFS_FREE.current], 4 |
412 | mov eax, [NET_BUFFS_FREE.current] |
414 | mov eax, [NET_BUFFS_FREE.current] |
413 | push [buffer] |
415 | push [buffer] |
414 | pop dword[eax] |
416 | pop dword[eax] |
415 | 417 | ||
416 | spin_unlock_irqrestore |
418 | spin_unlock_irqrestore |
417 | 419 | ||
418 | ret |
420 | ret |
419 | endp |
421 | endp |
420 | 422 | ||
421 | 423 | ||
422 | align 4 |
424 | align 4 |
423 | net_link_changed: |
425 | net_link_changed: |
424 | 426 | ||
425 | DEBUGF DEBUG_NETWORK_VERBOSE, "net_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.link_state] |
427 | DEBUGF DEBUG_NETWORK_VERBOSE, "net_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.link_state] |
426 | 428 | ||
427 | align 4 |
429 | align 4 |
428 | net_send_event: |
430 | net_send_event: |
429 | 431 | ||
430 | DEBUGF DEBUG_NETWORK_VERBOSE, "net_send_event\n" |
432 | DEBUGF DEBUG_NETWORK_VERBOSE, "net_send_event\n" |
431 | 433 | ||
432 | ; Send event to all applications |
434 | ; Send event to all applications |
433 | push edi ecx |
435 | push edi ecx |
434 | mov edi, SLOT_BASE |
436 | mov edi, SLOT_BASE |
435 | mov ecx, [TASK_COUNT] |
437 | mov ecx, [TASK_COUNT] |
436 | .loop: |
438 | .loop: |
437 | add edi, 256 |
439 | add edi, 256 |
438 | or [edi + APPDATA.event_mask], EVENT_NETWORK2 |
440 | or [edi + APPDATA.event_mask], EVENT_NETWORK2 |
439 | loop .loop |
441 | loop .loop |
440 | pop ecx edi |
442 | pop ecx edi |
441 | 443 | ||
442 | ret |
444 | ret |
443 | 445 | ||
444 | 446 | ||
445 | 447 | ||
446 | ;-----------------------------------------------------------------; |
448 | ;-----------------------------------------------------------------; |
447 | ; ; |
449 | ; ; |
448 | ; net_add_device: Called by network driver to register interface. ; |
450 | ; net_add_device: Called by network driver to register interface. ; |
449 | ; ; |
451 | ; ; |
450 | ; IN: ebx = ptr to device structure ; |
452 | ; IN: ebx = ptr to device structure ; |
451 | ; ; |
453 | ; ; |
452 | ; OUT: eax = device num on success ; |
454 | ; OUT: eax = device num on success ; |
453 | ; eax = -1 on error ; |
455 | ; eax = -1 on error ; |
454 | ; ; |
456 | ; ; |
455 | ;-----------------------------------------------------------------; |
457 | ;-----------------------------------------------------------------; |
456 | align 4 |
458 | align 4 |
457 | net_add_device: |
459 | net_add_device: |
458 | 460 | ||
459 | DEBUGF DEBUG_NETWORK_VERBOSE, "net_add_device: %x\n", ebx ;;; TODO: use mutex to lock net device list |
461 | DEBUGF DEBUG_NETWORK_VERBOSE, "net_add_device: %x\n", ebx ;;; TODO: use mutex to lock net device list |
460 | 462 | ||
461 | cmp [NET_RUNNING], NET_DEVICES_MAX |
463 | cmp [NET_RUNNING], NET_DEVICES_MAX |
462 | jae .error |
464 | jae .error |
463 | 465 | ||
464 | ;---------------------------------- |
466 | ;---------------------------------- |
465 | ; Check if device is already listed |
467 | ; Check if device is already listed |
466 | mov eax, ebx |
468 | mov eax, ebx |
467 | mov ecx, NET_DEVICES_MAX ; We need to check whole list because a device may be removed without re-organizing list |
469 | mov ecx, NET_DEVICES_MAX ; We need to check whole list because a device may be removed without re-organizing list |
468 | mov edi, NET_DRV_LIST |
470 | mov edi, NET_DRV_LIST |
469 | 471 | ||
470 | repne scasd ; See if device is already in the list |
472 | repne scasd ; See if device is already in the list |
471 | jz .error |
473 | jz .error |
472 | 474 | ||
473 | ;---------------------------- |
475 | ;---------------------------- |
474 | ; Find empty slot in the list |
476 | ; Find empty slot in the list |
475 | xor eax, eax |
477 | xor eax, eax |
476 | mov ecx, NET_DEVICES_MAX |
478 | mov ecx, NET_DEVICES_MAX |
477 | mov edi, NET_DRV_LIST |
479 | mov edi, NET_DRV_LIST |
478 | 480 | ||
479 | repne scasd |
481 | repne scasd |
480 | jnz .error |
482 | jnz .error |
481 | 483 | ||
482 | sub edi, 4 |
484 | sub edi, 4 |
483 | 485 | ||
484 | ;----------------------------- |
486 | ;----------------------------- |
485 | ; Add device to the found slot |
487 | ; Add device to the found slot |
486 | mov [edi], ebx ; add device to list |
488 | mov [edi], ebx ; add device to list |
487 | 489 | ||
488 | mov eax, edi ; Calculate device number in eax |
490 | mov eax, edi ; Calculate device number in eax |
489 | sub eax, NET_DRV_LIST |
491 | sub eax, NET_DRV_LIST |
490 | shr eax, 2 |
492 | shr eax, 2 |
491 | 493 | ||
492 | inc [NET_RUNNING] ; Indicate that one more network device is up and running |
494 | inc [NET_RUNNING] ; Indicate that one more network device is up and running |
493 | 495 | ||
494 | call net_send_event |
496 | call net_send_event |
495 | 497 | ||
496 | DEBUGF DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax |
498 | DEBUGF DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax |
497 | ret |
499 | ret |
498 | 500 | ||
499 | .error: |
501 | .error: |
500 | or eax, -1 |
502 | or eax, -1 |
501 | DEBUGF DEBUG_NETWORK_ERROR, "Adding network device failed\n" |
503 | DEBUGF DEBUG_NETWORK_ERROR, "Adding network device failed\n" |
502 | ret |
504 | ret |
503 | 505 | ||
504 | 506 | ||
505 | 507 | ||
506 | ;-----------------------------------------------------------------; |
508 | ;-----------------------------------------------------------------; |
507 | ; ; |
509 | ; ; |
508 | ; net_remove_device: Called by network driver to unregister dev. ; |
510 | ; net_remove_device: Called by network driver to unregister dev. ; |
509 | ; ; |
511 | ; ; |
510 | ; IN: ebx = ptr to device ; |
512 | ; IN: ebx = ptr to device ; |
511 | ; ; |
513 | ; ; |
512 | ; OUT: eax: -1 on error ; |
514 | ; OUT: eax: -1 on error ; |
513 | ; ; |
515 | ; ; |
514 | ;-----------------------------------------------------------------; |
516 | ;-----------------------------------------------------------------; |
515 | align 4 |
517 | align 4 |
516 | net_remove_device: |
518 | net_remove_device: |
517 | 519 | ||
518 | cmp [NET_RUNNING], 0 |
520 | cmp [NET_RUNNING], 0 |
519 | je .error |
521 | je .error |
520 | 522 | ||
521 | ;---------------------------- |
523 | ;---------------------------- |
522 | ; Find the driver in the list |
524 | ; Find the driver in the list |
523 | 525 | ||
524 | mov eax, ebx |
526 | mov eax, ebx |
525 | mov ecx, NET_DEVICES_MAX |
527 | mov ecx, NET_DEVICES_MAX |
526 | mov edi, NET_DRV_LIST |
528 | mov edi, NET_DRV_LIST |
527 | 529 | ||
528 | repne scasd |
530 | repne scasd |
529 | jnz .error |
531 | jnz .error |
530 | 532 | ||
531 | ;------------------------ |
533 | ;------------------------ |
532 | ; Remove it from the list |
534 | ; Remove it from the list |
533 | 535 | ||
534 | xor eax, eax |
536 | xor eax, eax |
535 | mov dword [edi-4], eax |
537 | mov dword [edi-4], eax |
536 | dec [NET_RUNNING] |
538 | dec [NET_RUNNING] |
537 | 539 | ||
538 | call net_send_event |
540 | call net_send_event |
539 | 541 | ||
540 | xor eax, eax |
542 | xor eax, eax |
541 | ret |
543 | ret |
542 | 544 | ||
543 | .error: |
545 | .error: |
544 | or eax, -1 |
546 | or eax, -1 |
545 | ret |
547 | ret |
546 | 548 | ||
547 | 549 | ||
548 | 550 | ||
549 | ;-----------------------------------------------------------------; |
551 | ;-----------------------------------------------------------------; |
550 | ; ; |
552 | ; ; |
551 | ; net_ptr_to_num ; |
553 | ; net_ptr_to_num ; |
552 | ; ; |
554 | ; ; |
553 | ; IN: ebx = ptr to device struct ; |
555 | ; IN: ebx = ptr to device struct ; |
554 | ; ; |
556 | ; ; |
555 | ; OUT: edi = device number ; |
557 | ; OUT: edi = device number ; |
556 | ; edi = -1 on error ; |
558 | ; edi = -1 on error ; |
557 | ; ; |
559 | ; ; |
558 | ;-----------------------------------------------------------------; |
560 | ;-----------------------------------------------------------------; |
559 | align 4 |
561 | align 4 |
560 | net_ptr_to_num: |
562 | net_ptr_to_num: |
561 | 563 | ||
562 | call net_ptr_to_num4 |
564 | call net_ptr_to_num4 |
563 | ror edi, 2 ; If -1, stay -1 |
565 | ror edi, 2 ; If -1, stay -1 |
564 | ; valid device numbers have last two bits 0, so do just shr |
566 | ; valid device numbers have last two bits 0, so do just shr |
565 | 567 | ||
566 | ret |
568 | ret |
567 | 569 | ||
568 | align 4 |
570 | align 4 |
569 | net_ptr_to_num4: ; Todo, place number in device structure so we only need to verify? |
571 | net_ptr_to_num4: ; Todo, place number in device structure so we only need to verify? |
570 | 572 | ||
571 | test ebx, ebx |
573 | test ebx, ebx |
572 | jz .fail |
574 | jz .fail |
573 | 575 | ||
574 | push ecx |
576 | push ecx |
575 | mov ecx, NET_DEVICES_MAX |
577 | mov ecx, NET_DEVICES_MAX |
576 | mov edi, NET_DRV_LIST |
578 | mov edi, NET_DRV_LIST |
577 | .loop: |
579 | .loop: |
578 | cmp ebx, [edi] |
580 | cmp ebx, [edi] |
579 | je .found |
581 | je .found |
580 | add edi, 4 |
582 | add edi, 4 |
581 | dec ecx |
583 | dec ecx |
582 | jnz .loop |
584 | jnz .loop |
583 | 585 | ||
584 | pop ecx |
586 | pop ecx |
585 | .fail: |
587 | .fail: |
586 | or edi, -1 |
588 | or edi, -1 |
587 | ret |
589 | ret |
588 | 590 | ||
589 | .found: |
591 | .found: |
590 | sub edi, NET_DRV_LIST |
592 | sub edi, NET_DRV_LIST |
591 | pop ecx |
593 | pop ecx |
592 | ret |
594 | ret |
593 | 595 | ||
594 | ;-----------------------------------------------------------------; |
596 | ;-----------------------------------------------------------------; |
595 | ; ; |
597 | ; ; |
596 | ; checksum_1: Calculate semi-checksum for network packets. ; |
598 | ; checksum_1: Calculate semi-checksum for network packets. ; |
597 | ; ; |
599 | ; ; |
598 | ; IN: edx = start offset for semi-checksum ; |
600 | ; IN: edx = start offset for semi-checksum ; |
599 | ; esi = pointer to data ; |
601 | ; esi = pointer to data ; |
600 | ; ecx = data size ; |
602 | ; ecx = data size ; |
601 | ; ; |
603 | ; ; |
602 | ; OUT: edx = semi-checksum ; |
604 | ; OUT: edx = semi-checksum ; |
603 | ; ; |
605 | ; ; |
604 | ;-----------------------------------------------------------------; |
606 | ;-----------------------------------------------------------------; |
605 | align 4 |
607 | align 4 |
606 | checksum_1: |
608 | checksum_1: |
607 | 609 | ||
608 | shr ecx, 1 |
610 | shr ecx, 1 |
609 | pushf |
611 | pushf |
610 | jz .no_2 |
612 | jz .no_2 |
611 | 613 | ||
612 | shr ecx, 1 |
614 | shr ecx, 1 |
613 | pushf |
615 | pushf |
614 | jz .no_4 |
616 | jz .no_4 |
615 | 617 | ||
616 | shr ecx, 1 |
618 | shr ecx, 1 |
617 | pushf |
619 | pushf |
618 | jz .no_8 |
620 | jz .no_8 |
619 | 621 | ||
620 | .loop: |
622 | .loop: |
621 | add dl, [esi+1] |
623 | add dl, [esi+1] |
622 | adc dh, [esi+0] |
624 | adc dh, [esi+0] |
623 | 625 | ||
624 | adc dl, [esi+3] |
626 | adc dl, [esi+3] |
625 | adc dh, [esi+2] |
627 | adc dh, [esi+2] |
626 | 628 | ||
627 | adc dl, [esi+5] |
629 | adc dl, [esi+5] |
628 | adc dh, [esi+4] |
630 | adc dh, [esi+4] |
629 | 631 | ||
630 | adc dl, [esi+7] |
632 | adc dl, [esi+7] |
631 | adc dh, [esi+6] |
633 | adc dh, [esi+6] |
632 | 634 | ||
633 | adc edx, 0 |
635 | adc edx, 0 |
634 | add esi, 8 |
636 | add esi, 8 |
635 | 637 | ||
636 | dec ecx |
638 | dec ecx |
637 | jnz .loop |
639 | jnz .loop |
638 | 640 | ||
639 | adc edx, 0 |
641 | adc edx, 0 |
640 | 642 | ||
641 | .no_8: |
643 | .no_8: |
642 | popf |
644 | popf |
643 | jnc .no_4 |
645 | jnc .no_4 |
644 | 646 | ||
645 | add dl, [esi+1] |
647 | add dl, [esi+1] |
646 | adc dh, [esi+0] |
648 | adc dh, [esi+0] |
647 | 649 | ||
648 | adc dl, [esi+3] |
650 | adc dl, [esi+3] |
649 | adc dh, [esi+2] |
651 | adc dh, [esi+2] |
650 | 652 | ||
651 | adc edx, 0 |
653 | adc edx, 0 |
652 | add esi, 4 |
654 | add esi, 4 |
653 | 655 | ||
654 | .no_4: |
656 | .no_4: |
655 | popf |
657 | popf |
656 | jnc .no_2 |
658 | jnc .no_2 |
657 | 659 | ||
658 | add dl, [esi+1] |
660 | add dl, [esi+1] |
659 | adc dh, [esi+0] |
661 | adc dh, [esi+0] |
660 | 662 | ||
661 | adc edx, 0 |
663 | adc edx, 0 |
662 | inc esi |
664 | inc esi |
663 | inc esi |
665 | inc esi |
664 | 666 | ||
665 | .no_2: |
667 | .no_2: |
666 | popf |
668 | popf |
667 | jnc .end |
669 | jnc .end |
668 | 670 | ||
669 | add dh, [esi+0] |
671 | add dh, [esi+0] |
670 | adc edx, 0 |
672 | adc edx, 0 |
671 | .end: |
673 | .end: |
672 | ret |
674 | ret |
673 | 675 | ||
674 | ;-----------------------------------------------------------------; |
676 | ;-----------------------------------------------------------------; |
675 | ; ; |
677 | ; ; |
676 | ; checksum_2: Calculate the final ip/tcp/udp checksum. ; |
678 | ; checksum_2: Calculate the final ip/tcp/udp checksum. ; |
677 | ; ; |
679 | ; ; |
678 | ; IN: edx = semi-checksum ; |
680 | ; IN: edx = semi-checksum ; |
679 | ; ; |
681 | ; ; |
680 | ; OUT: dx = checksum (in INET byte order) ; |
682 | ; OUT: dx = checksum (in INET byte order) ; |
681 | ; ; |
683 | ; ; |
682 | ;-----------------------------------------------------------------; |
684 | ;-----------------------------------------------------------------; |
683 | align 4 |
685 | align 4 |
684 | checksum_2: |
686 | checksum_2: |
685 | 687 | ||
686 | mov ecx, edx |
688 | mov ecx, edx |
687 | shr ecx, 16 |
689 | shr ecx, 16 |
688 | and edx, 0xffff |
690 | and edx, 0xffff |
689 | add edx, ecx |
691 | add edx, ecx |
690 | 692 | ||
691 | mov ecx, edx |
693 | mov ecx, edx |
692 | shr ecx, 16 |
694 | shr ecx, 16 |
693 | add dx, cx |
695 | add dx, cx |
694 | test dx, dx ; it seems that ZF is not set when CF is set :( |
696 | test dx, dx ; it seems that ZF is not set when CF is set :( |
695 | not dx |
697 | not dx |
696 | jnz .not_zero |
698 | jnz .not_zero |
697 | dec dx |
699 | dec dx |
698 | .not_zero: |
700 | .not_zero: |
699 | xchg dl, dh |
701 | xchg dl, dh |
700 | 702 | ||
701 | DEBUGF DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx |
703 | DEBUGF DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx |
702 | 704 | ||
703 | ret |
705 | ret |
704 | 706 | ||
705 | 707 | ||
706 | 708 | ||
707 | ;-----------------------------------------------------------------; |
709 | ;-----------------------------------------------------------------; |
708 | ; ; |
710 | ; ; |
709 | ; System function 74: Low level access to network devices. ; |
711 | ; System function 74: Low level access to network devices. ; |
710 | ; ; |
712 | ; ; |
711 | ;-----------------------------------------------------------------; |
713 | ;-----------------------------------------------------------------; |
712 | align 4 |
714 | align 4 |
713 | sys_network: |
715 | sys_network: |
714 | 716 | ||
715 | cmp bl, 255 |
717 | cmp bl, 255 |
716 | jne @f |
718 | jne @f |
717 | 719 | ||
718 | mov eax, [NET_RUNNING] |
720 | mov eax, [NET_RUNNING] |
719 | mov [esp+32], eax |
721 | mov [esp+32], eax |
720 | ret |
722 | ret |
721 | 723 | ||
722 | @@: |
724 | @@: |
723 | cmp bh, NET_DEVICES_MAX ; Check if device number exists |
725 | cmp bh, NET_DEVICES_MAX ; Check if device number exists |
724 | jae .doesnt_exist |
726 | jae .doesnt_exist |
725 | 727 | ||
726 | mov esi, ebx |
728 | mov esi, ebx |
727 | and esi, 0x0000ff00 |
729 | and esi, 0x0000ff00 |
728 | shr esi, 6 |
730 | shr esi, 6 |
729 | 731 | ||
730 | cmp dword[esi + NET_DRV_LIST], 0 ; check if driver is running |
732 | cmp dword[esi + NET_DRV_LIST], 0 ; check if driver is running |
731 | je .doesnt_exist |
733 | je .doesnt_exist |
732 | 734 | ||
733 | mov eax, [esi + NET_DRV_LIST] |
735 | mov eax, [esi + NET_DRV_LIST] |
734 | 736 | ||
735 | and ebx, 0x000000ff |
737 | and ebx, 0x000000ff |
736 | cmp ebx, .number |
738 | cmp ebx, .number |
737 | ja .doesnt_exist |
739 | ja .doesnt_exist |
738 | jmp dword [.table + 4*ebx] |
740 | jmp dword [.table + 4*ebx] |
739 | 741 | ||
740 | .table: |
742 | .table: |
741 | dd .get_type ; 0 |
743 | dd .get_type ; 0 |
742 | dd .get_dev_name ; 1 |
744 | dd .get_dev_name ; 1 |
743 | dd .reset ; 2 |
745 | dd .reset ; 2 |
744 | dd .stop ; 3 |
746 | dd .stop ; 3 |
745 | dd .get_ptr ; 4 |
747 | dd .get_ptr ; 4 |
746 | dd .get_drv_name ; 5 |
748 | dd .get_drv_name ; 5 |
747 | 749 | ||
748 | dd .packets_tx ; 6 |
750 | dd .packets_tx ; 6 |
749 | dd .packets_rx ; 7 |
751 | dd .packets_rx ; 7 |
750 | dd .bytes_tx ; 8 |
752 | dd .bytes_tx ; 8 |
751 | dd .bytes_rx ; 9 |
753 | dd .bytes_rx ; 9 |
752 | dd .state ; 10 |
754 | dd .state ; 10 |
753 | .number = ($ - .table) / 4 - 1 |
755 | .number = ($ - .table) / 4 - 1 |
754 | 756 | ||
755 | .get_type: |
757 | .get_type: |
756 | mov eax, [eax + NET_DEVICE.device_type] |
758 | mov eax, [eax + NET_DEVICE.device_type] |
757 | mov [esp+32], eax |
759 | mov [esp+32], eax |
758 | ret |
760 | ret |
759 | 761 | ||
760 | .get_dev_name: |
762 | .get_dev_name: |
761 | mov esi, [eax + NET_DEVICE.name] |
763 | mov esi, [eax + NET_DEVICE.name] |
762 | mov edi, ecx |
764 | mov edi, ecx |
763 | 765 | ||
764 | mov ecx, 64/4 ; max length |
766 | mov ecx, 64/4 ; max length |
765 | rep movsd |
767 | rep movsd |
766 | 768 | ||
767 | xor eax, eax |
769 | xor eax, eax |
768 | mov [esp+32], eax |
770 | mov [esp+32], eax |
769 | ret |
771 | ret |
770 | 772 | ||
771 | .reset: |
773 | .reset: |
772 | call [eax + NET_DEVICE.reset] |
774 | call [eax + NET_DEVICE.reset] |
773 | mov [esp+32], eax |
775 | mov [esp+32], eax |
774 | ret |
776 | ret |
775 | 777 | ||
776 | .stop: |
778 | .stop: |
777 | call [eax + NET_DEVICE.unload] |
779 | call [eax + NET_DEVICE.unload] |
778 | mov [esp+32], eax |
780 | mov [esp+32], eax |
779 | ret |
781 | ret |
780 | 782 | ||
781 | 783 | ||
782 | .get_ptr: |
784 | .get_ptr: |
783 | mov [esp+32], eax |
785 | mov [esp+32], eax |
784 | ret |
786 | ret |
785 | 787 | ||
786 | 788 | ||
787 | .get_drv_name: |
789 | .get_drv_name: |
788 | xor eax, eax |
790 | xor eax, eax |
789 | mov [esp+32], eax |
791 | mov [esp+32], eax |
790 | ret |
792 | ret |
791 | 793 | ||
792 | .packets_tx: |
794 | .packets_tx: |
793 | mov eax, [eax + NET_DEVICE.packets_tx] |
795 | mov eax, [eax + NET_DEVICE.packets_tx] |
794 | mov [esp+32], eax |
796 | mov [esp+32], eax |
795 | ret |
797 | ret |
796 | 798 | ||
797 | .packets_rx: |
799 | .packets_rx: |
798 | mov eax, [eax + NET_DEVICE.packets_rx] |
800 | mov eax, [eax + NET_DEVICE.packets_rx] |
799 | mov [esp+32], eax |
801 | mov [esp+32], eax |
800 | ret |
802 | ret |
801 | 803 | ||
802 | .bytes_tx: |
804 | .bytes_tx: |
803 | mov ebx, dword[eax + NET_DEVICE.bytes_tx + 4] |
805 | mov ebx, dword[eax + NET_DEVICE.bytes_tx + 4] |
804 | mov [esp+20], ebx |
806 | mov [esp+20], ebx |
805 | mov eax, dword[eax + NET_DEVICE.bytes_tx] |
807 | mov eax, dword[eax + NET_DEVICE.bytes_tx] |
806 | mov [esp+32], eax |
808 | mov [esp+32], eax |
807 | ret |
809 | ret |
808 | 810 | ||
809 | .bytes_rx: |
811 | .bytes_rx: |
810 | mov ebx, dword[eax + NET_DEVICE.bytes_rx + 4] |
812 | mov ebx, dword[eax + NET_DEVICE.bytes_rx + 4] |
811 | mov [esp+20], ebx |
813 | mov [esp+20], ebx |
812 | mov eax, dword[eax + NET_DEVICE.bytes_rx] |
814 | mov eax, dword[eax + NET_DEVICE.bytes_rx] |
813 | mov [esp+32], eax |
815 | mov [esp+32], eax |
814 | ret |
816 | ret |
815 | 817 | ||
816 | .state: |
818 | .state: |
817 | mov eax, [eax + NET_DEVICE.link_state] |
819 | mov eax, [eax + NET_DEVICE.link_state] |
818 | mov [esp+32], eax |
820 | mov [esp+32], eax |
819 | ret |
821 | ret |
820 | 822 | ||
821 | 823 | ||
822 | .doesnt_exist: |
824 | .doesnt_exist: |
823 | mov dword[esp+32], -1 |
825 | mov dword[esp+32], -1 |
824 | ret |
826 | ret |
825 | 827 | ||
826 | 828 | ||
827 | 829 | ||
828 | ;-----------------------------------------------------------------; |
830 | ;-----------------------------------------------------------------; |
829 | ; ; |
831 | ; ; |
830 | ; System function 76: Low level access to protocol handlers. ; |
832 | ; System function 76: Low level access to protocol handlers. ; |
831 | ; ; |
833 | ; ; |
832 | ;-----------------------------------------------------------------; |
834 | ;-----------------------------------------------------------------; |
833 | align 4 |
835 | align 4 |
834 | sys_protocols: |
836 | sys_protocols: |
835 | cmp bh, NET_DEVICES_MAX ; Check if device number exists |
837 | cmp bh, NET_DEVICES_MAX ; Check if device number exists |
836 | jae .doesnt_exist |
838 | jae .doesnt_exist |
837 | 839 | ||
838 | mov esi, ebx |
840 | mov esi, ebx |
839 | and esi, 0x0000ff00 |
841 | and esi, 0x0000ff00 |
840 | shr esi, 6 ; now we have the device num * 4 in esi |
842 | shr esi, 6 ; now we have the device num * 4 in esi |
841 | cmp [esi + NET_DRV_LIST], 0 ; check if driver is running |
843 | cmp [esi + NET_DRV_LIST], 0 ; check if driver is running |
842 | je .doesnt_exist |
844 | je .doesnt_exist |
843 | 845 | ||
844 | push .return ; return address (we will be using jumps instead of calls) |
846 | push .return ; return address (we will be using jumps instead of calls) |
845 | 847 | ||
846 | mov eax, ebx ; set ax to protocol number |
848 | mov eax, ebx ; set ax to protocol number |
847 | shr eax, 16 ; |
849 | shr eax, 16 ; |
848 | 850 | ||
849 | cmp ax, API_ETH |
851 | cmp ax, API_ETH |
850 | je eth_api |
852 | je eth_api |
851 | 853 | ||
852 | cmp ax, API_IPv4 |
854 | cmp ax, API_IPv4 |
853 | je ipv4_api |
855 | je ipv4_api |
854 | 856 | ||
855 | cmp ax, API_ICMP |
857 | cmp ax, API_ICMP |
856 | je icmp_api |
858 | je icmp_api |
857 | 859 | ||
858 | cmp ax, API_UDP |
860 | cmp ax, API_UDP |
859 | je udp_api |
861 | je udp_api |
860 | 862 | ||
861 | cmp ax, API_TCP |
863 | cmp ax, API_TCP |
862 | je tcp_api |
864 | je tcp_api |
863 | 865 | ||
864 | cmp ax, API_ARP |
866 | cmp ax, API_ARP |
865 | je arp_api |
867 | je arp_api |
866 | 868 | ||
867 | cmp ax, API_PPPOE |
869 | cmp ax, API_PPPOE |
868 | je pppoe_api |
870 | je pppoe_api |
869 | 871 | ||
870 | cmp ax, API_IPv6 |
872 | cmp ax, API_IPv6 |
871 | je ipv6_api |
873 | je ipv6_api |
872 | 874 | ||
873 | add esp, 4 ; if we reached here, no function was called, so we need to balance stack |
875 | add esp, 4 ; if we reached here, no function was called, so we need to balance stack |
874 | 876 | ||
875 | .doesnt_exist: |
877 | .doesnt_exist: |
876 | mov eax, -1 |
878 | mov eax, -1 |
877 | 879 | ||
878 | .return: |
880 | .return: |
879 | mov [esp+28+4], eax ; return eax value to the program |
881 | mov [esp+28+4], eax ; return eax value to the program |
880 | ret |
882 | ret |