Rev 2993 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2993 | Rev 2994 | ||
---|---|---|---|
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 | ;; Part of the tcp/ip network stack for KolibriOS ;; |
6 | ;; Part of the tcp/ip network stack for KolibriOS ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; Written by hidnplayr@kolibrios.org, ;; |
8 | ;; Written by hidnplayr@kolibrios.org, ;; |
9 | ;; and Clevermouse. ;; |
9 | ;; and Clevermouse. ;; |
10 | ;; ;; |
10 | ;; ;; |
11 | ;; Based on code by mike.dld ;; |
11 | ;; Based on code by mike.dld ;; |
12 | ;; ;; |
12 | ;; ;; |
13 | ;; GNU GENERAL PUBLIC LICENSE ;; |
13 | ;; GNU GENERAL PUBLIC LICENSE ;; |
14 | ;; Version 2, June 1991 ;; |
14 | ;; Version 2, June 1991 ;; |
15 | ;; ;; |
15 | ;; ;; |
16 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
16 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
17 | 17 | ||
18 | $Revision: 2993 $ |
18 | $Revision: 2994 $ |
19 | 19 | ||
20 | 20 | ||
21 | struct SOCKET |
21 | struct SOCKET |
22 | 22 | ||
23 | NextPtr dd ? ; pointer to next socket in list |
23 | NextPtr dd ? ; pointer to next socket in list |
24 | PrevPtr dd ? ; pointer to previous socket in list |
24 | PrevPtr dd ? ; pointer to previous socket in list |
25 | Number dd ? ; socket number |
25 | Number dd ? ; socket number |
26 | 26 | ||
27 | mutex MUTEX |
27 | mutex MUTEX |
28 | 28 | ||
29 | PID dd ? ; application process id |
29 | PID dd ? ; application process id |
30 | Domain dd ? ; INET/UNIX/.. |
30 | Domain dd ? ; INET/UNIX/.. |
31 | Type dd ? ; RAW/STREAM/DGRAP |
31 | Type dd ? ; RAW/STREAM/DGRAP |
32 | Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP |
32 | Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP |
33 | errorcode dd ? |
33 | errorcode dd ? |
34 | device dd ? |
34 | device dd ? |
35 | 35 | ||
36 | options dd ? |
36 | options dd ? |
37 | state dd ? |
37 | state dd ? |
38 | backlog dw ? ; how many incomming connections that can be queued |
38 | backlog dw ? ; how many incomming connections that can be queued |
39 | 39 | ||
40 | snd_proc dd ? |
40 | snd_proc dd ? |
41 | rcv_proc dd ? |
41 | rcv_proc dd ? |
42 | 42 | ||
43 | ends |
43 | ends |
44 | 44 | ||
45 | struct IP_SOCKET SOCKET |
45 | struct IP_SOCKET SOCKET |
46 | 46 | ||
47 | LocalIP rd 4 |
47 | LocalIP rd 4 |
48 | RemoteIP rd 4 |
48 | RemoteIP rd 4 |
49 | 49 | ||
50 | ends |
50 | ends |
51 | 51 | ||
52 | struct TCP_SOCKET IP_SOCKET |
52 | struct TCP_SOCKET IP_SOCKET |
53 | 53 | ||
54 | LocalPort dw ? |
54 | LocalPort dw ? |
55 | RemotePort dw ? |
55 | RemotePort dw ? |
56 | 56 | ||
57 | t_state dd ? ; TCB state |
57 | t_state dd ? ; TCB state |
58 | t_rxtshift db ? |
58 | t_rxtshift db ? |
59 | rb 3 ; align |
59 | rb 3 ; align |
60 | t_rxtcur dd ? |
60 | t_rxtcur dd ? |
61 | t_dupacks dd ? |
61 | t_dupacks dd ? |
62 | t_maxseg dd ? |
62 | t_maxseg dd ? |
63 | t_force dd ? |
63 | t_force dd ? |
64 | t_flags dd ? |
64 | t_flags dd ? |
65 | 65 | ||
66 | ;--------------- |
66 | ;--------------- |
67 | ; RFC783 page 21 |
67 | ; RFC783 page 21 |
68 | 68 | ||
69 | ; send sequence |
69 | ; send sequence |
70 | SND_UNA dd ? ; sequence number of unack'ed sent Packets |
70 | SND_UNA dd ? ; sequence number of unack'ed sent Packets |
71 | SND_NXT dd ? ; next send sequence number to use |
71 | SND_NXT dd ? ; next send sequence number to use |
72 | SND_UP dd ? ; urgent pointer |
72 | SND_UP dd ? ; urgent pointer |
73 | SND_WL1 dd ? ; window minus one |
73 | SND_WL1 dd ? ; window minus one |
74 | SND_WL2 dd ? ; |
74 | SND_WL2 dd ? ; |
75 | ISS dd ? ; initial send sequence number |
75 | ISS dd ? ; initial send sequence number |
76 | SND_WND dd ? ; send window |
76 | SND_WND dd ? ; send window |
77 | 77 | ||
78 | ; receive sequence |
78 | ; receive sequence |
79 | RCV_WND dd ? ; receive window |
79 | RCV_WND dd ? ; receive window |
80 | RCV_NXT dd ? ; next receive sequence number to use |
80 | RCV_NXT dd ? ; next receive sequence number to use |
81 | RCV_UP dd ? ; urgent pointer |
81 | RCV_UP dd ? ; urgent pointer |
82 | IRS dd ? ; initial receive sequence number |
82 | IRS dd ? ; initial receive sequence number |
83 | 83 | ||
84 | ;--------------------- |
84 | ;--------------------- |
85 | ; Additional variables |
85 | ; Additional variables |
86 | 86 | ||
87 | ; receive variables |
87 | ; receive variables |
88 | RCV_ADV dd ? |
88 | RCV_ADV dd ? |
89 | 89 | ||
90 | ; retransmit variables |
90 | ; retransmit variables |
91 | SND_MAX dd ? |
91 | SND_MAX dd ? |
92 | 92 | ||
93 | ; congestion control |
93 | ; congestion control |
94 | SND_CWND dd ? |
94 | SND_CWND dd ? |
95 | SND_SSTHRESH dd ? |
95 | SND_SSTHRESH dd ? |
96 | 96 | ||
97 | ;---------------------- |
97 | ;---------------------- |
98 | ; Transmit timing stuff |
98 | ; Transmit timing stuff |
99 | t_idle dd ? |
99 | t_idle dd ? |
100 | t_rtt dd ? |
100 | t_rtt dd ? |
101 | t_rtseq dd ? |
101 | t_rtseq dd ? |
102 | t_srtt dd ? |
102 | t_srtt dd ? |
103 | t_rttvar dd ? |
103 | t_rttvar dd ? |
104 | t_rttmin dd ? |
104 | t_rttmin dd ? |
105 | max_sndwnd dd ? |
105 | max_sndwnd dd ? |
106 | 106 | ||
107 | ;----------------- |
107 | ;----------------- |
108 | ; Out-of-band data |
108 | ; Out-of-band data |
109 | t_oobflags dd ? |
109 | t_oobflags dd ? |
110 | t_iobc dd ? |
110 | t_iobc dd ? |
111 | t_softerror dd ? |
111 | t_softerror dd ? |
112 | 112 | ||
113 | 113 | ||
114 | ;--------- |
114 | ;--------- |
115 | ; RFC 1323 ; the order of next 4 elements may not change |
115 | ; RFC 1323 ; the order of next 4 elements may not change |
116 | 116 | ||
117 | SND_SCALE db ? |
117 | SND_SCALE db ? |
118 | RCV_SCALE db ? |
118 | RCV_SCALE db ? |
119 | requested_s_scale db ? |
119 | requested_s_scale db ? |
120 | request_r_scale db ? |
120 | request_r_scale db ? |
121 | 121 | ||
122 | ts_recent dd ? ; a copy of the most-recent valid timestamp from the other end |
122 | ts_recent dd ? ; a copy of the most-recent valid timestamp from the other end |
123 | ts_recent_age dd ? |
123 | ts_recent_age dd ? |
124 | last_ack_sent dd ? |
124 | last_ack_sent dd ? |
125 | 125 | ||
126 | 126 | ||
127 | ;------- |
127 | ;------- |
128 | ; Timers |
128 | ; Timers |
129 | timer_retransmission dd ? ; rexmt |
129 | timer_retransmission dd ? ; rexmt |
130 | timer_persist dd ? |
130 | timer_persist dd ? |
131 | timer_keepalive dd ? ; keepalive/syn timeout |
131 | timer_keepalive dd ? ; keepalive/syn timeout |
132 | timer_timed_wait dd ? ; also used as 2msl timer |
132 | timer_timed_wait dd ? ; also used as 2msl timer |
133 | 133 | ||
134 | ; extra |
134 | ; extra |
135 | 135 | ||
136 | ts_ecr dd ? ; timestamp echo reply |
136 | ts_ecr dd ? ; timestamp echo reply |
137 | ts_val dd ? |
137 | ts_val dd ? |
138 | temp_bits db ? |
138 | temp_bits db ? |
139 | 139 | ||
140 | ends |
140 | ends |
141 | 141 | ||
142 | struct UDP_SOCKET IP_SOCKET |
142 | struct UDP_SOCKET IP_SOCKET |
143 | 143 | ||
144 | LocalPort dw ? |
144 | LocalPort dw ? |
145 | RemotePort dw ? |
145 | RemotePort dw ? |
146 | firstpacket db ? |
146 | firstpacket db ? |
147 | 147 | ||
148 | ends |
148 | ends |
149 | 149 | ||
150 | 150 | ||
151 | struct ICMP_SOCKET IP_SOCKET |
151 | struct ICMP_SOCKET IP_SOCKET |
152 | 152 | ||
153 | Identifier dw ? |
153 | Identifier dw ? |
154 | 154 | ||
155 | ends |
155 | ends |
156 | 156 | ||
157 | 157 | ||
158 | struct RING_BUFFER |
158 | struct RING_BUFFER |
159 | 159 | ||
160 | start_ptr dd ? ; Pointer to start of buffer |
160 | start_ptr dd ? ; Pointer to start of buffer |
161 | end_ptr dd ? ; pointer to end of buffer |
161 | end_ptr dd ? ; pointer to end of buffer |
162 | read_ptr dd ? ; Read pointer |
162 | read_ptr dd ? ; Read pointer |
163 | write_ptr dd ? ; Write pointer |
163 | write_ptr dd ? ; Write pointer |
164 | size dd ? ; Number of bytes buffered |
164 | size dd ? ; Number of bytes buffered |
165 | 165 | ||
166 | ends |
166 | ends |
167 | 167 | ||
168 | struct STREAM_SOCKET TCP_SOCKET |
168 | struct STREAM_SOCKET TCP_SOCKET |
169 | 169 | ||
170 | rcv RING_BUFFER |
170 | rcv RING_BUFFER |
171 | snd RING_BUFFER |
171 | snd RING_BUFFER |
172 | 172 | ||
173 | ends |
173 | ends |
174 | 174 | ||
175 | struct socket_queue_entry |
175 | struct socket_queue_entry |
176 | 176 | ||
177 | data_ptr dd ? |
177 | data_ptr dd ? |
178 | buf_ptr dd ? |
178 | buf_ptr dd ? |
179 | data_size dd ? |
179 | data_size dd ? |
180 | 180 | ||
181 | ends |
181 | ends |
182 | 182 | ||
183 | 183 | ||
184 | SOCKETBUFFSIZE = 4096 ; in bytes |
184 | SOCKETBUFFSIZE = 4096 ; in bytes |
185 | 185 | ||
186 | SOCKET_QUEUE_SIZE = 10 ; maximum number ofincoming packets queued for 1 socket |
186 | SOCKET_QUEUE_SIZE = 10 ; maximum number ofincoming packets queued for 1 socket |
187 | ; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start |
187 | ; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start |
188 | SOCKET_QUEUE_LOCATION = (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*sizeof.socket_queue_entry - sizeof.queue) |
188 | SOCKET_QUEUE_LOCATION = (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*sizeof.socket_queue_entry - sizeof.queue) |
189 | 189 | ||
190 | uglobal |
190 | uglobal |
191 | net_sockets rd 4 |
191 | net_sockets rd 4 |
192 | last_socket_num dd ? |
192 | last_socket_num dd ? |
193 | last_UDP_port dw ? ; These values give the number of the last used ephemeral port |
193 | last_UDP_port dw ? ; These values give the number of the last used ephemeral port |
194 | last_TCP_port dw ? ; |
194 | last_TCP_port dw ? ; |
195 | endg |
195 | endg |
196 | 196 | ||
197 | 197 | ||
198 | ;----------------------------------------------------------------- |
198 | ;----------------------------------------------------------------- |
199 | ; |
199 | ; |
200 | ; SOCKET_init |
200 | ; SOCKET_init |
201 | ; |
201 | ; |
202 | ;----------------------------------------------------------------- |
202 | ;----------------------------------------------------------------- |
203 | macro SOCKET_init { |
203 | macro SOCKET_init { |
204 | 204 | ||
205 | xor eax, eax |
205 | xor eax, eax |
206 | mov edi, net_sockets |
206 | mov edi, net_sockets |
207 | mov ecx, 5 |
207 | mov ecx, 5 |
208 | rep stosd |
208 | rep stosd |
209 | 209 | ||
210 | @@: |
210 | @@: |
211 | pseudo_random eax |
211 | pseudo_random eax |
212 | cmp ax, MIN_EPHEMERAL_PORT |
212 | cmp ax, MIN_EPHEMERAL_PORT |
213 | jb @r |
213 | jb @r |
214 | cmp ax, MAX_EPHEMERAL_PORT |
214 | cmp ax, MAX_EPHEMERAL_PORT |
215 | ja @r |
215 | ja @r |
216 | mov [last_UDP_port], ax |
216 | mov [last_UDP_port], ax |
217 | 217 | ||
218 | @@: |
218 | @@: |
219 | pseudo_random eax |
219 | pseudo_random eax |
220 | cmp ax, MIN_EPHEMERAL_PORT |
220 | cmp ax, MIN_EPHEMERAL_PORT |
221 | jb @r |
221 | jb @r |
222 | cmp ax, MAX_EPHEMERAL_PORT |
222 | cmp ax, MAX_EPHEMERAL_PORT |
223 | ja @r |
223 | ja @r |
224 | mov [last_TCP_port], ax |
224 | mov [last_TCP_port], ax |
225 | 225 | ||
226 | } |
226 | } |
227 | 227 | ||
228 | 228 | ||
229 | ;----------------------------------------------------------------- |
229 | ;----------------------------------------------------------------- |
230 | ; |
230 | ; |
- | 231 | ; SOCKET_block |
|
- | 232 | ; |
|
- | 233 | ;----------------------------------------------------------------- |
|
- | 234 | macro SOCKET_block socket, loop, done { |
|
- | 235 | ||
- | 236 | test [socket + SOCKET.options], SO_BLOCK ; Is this a blocking socket? |
|
- | 237 | jz done ; No, return immediately |
|
- | 238 | ||
- | 239 | push esi |
|
- | 240 | mov esi, 5 ; yes, wait for event |
|
- | 241 | call delay_ms |
|
- | 242 | pop esi |
|
- | 243 | ||
- | 244 | jmp loop |
|
- | 245 | ||
- | 246 | } |
|
- | 247 | ||
- | 248 | ||
- | 249 | ;----------------------------------------------------------------- |
|
- | 250 | ; |
|
231 | ; Socket API (function 74) |
251 | ; Socket API (function 74) |
232 | ; |
252 | ; |
233 | ;----------------------------------------------------------------- |
253 | ;----------------------------------------------------------------- |
234 | align 4 |
254 | align 4 |
235 | sys_socket: |
255 | sys_socket: |
236 | 256 | ||
237 | cmp ebx, 255 |
257 | cmp ebx, 255 |
238 | jz SOCKET_debug |
258 | jz SOCKET_debug |
239 | 259 | ||
240 | cmp ebx, .number |
260 | cmp ebx, .number |
241 | ja s_error |
261 | ja s_error |
242 | jmp dword [.table + 4*ebx] |
262 | jmp dword [.table + 4*ebx] |
243 | 263 | ||
244 | .table: |
264 | .table: |
245 | dd SOCKET_open ; 0 |
265 | dd SOCKET_open ; 0 |
246 | dd SOCKET_close ; 1 |
266 | dd SOCKET_close ; 1 |
247 | dd SOCKET_bind ; 2 |
267 | dd SOCKET_bind ; 2 |
248 | dd SOCKET_listen ; 3 |
268 | dd SOCKET_listen ; 3 |
249 | dd SOCKET_connect ; 4 |
269 | dd SOCKET_connect ; 4 |
250 | dd SOCKET_accept ; 5 |
270 | dd SOCKET_accept ; 5 |
251 | dd SOCKET_send ; 6 |
271 | dd SOCKET_send ; 6 |
252 | dd SOCKET_receive ; 7 |
272 | dd SOCKET_receive ; 7 |
253 | dd SOCKET_set_opt ; 8 |
273 | dd SOCKET_set_opt ; 8 |
254 | dd SOCKET_get_opt ; 9 |
274 | dd SOCKET_get_opt ; 9 |
255 | .number = ($ - .table) / 4 - 1 |
275 | .number = ($ - .table) / 4 - 1 |
256 | 276 | ||
257 | s_error: |
277 | s_error: |
258 | DEBUGF 1,"socket error\n" |
278 | DEBUGF 1,"socket error\n" |
259 | mov dword [esp+32], -1 |
279 | mov dword [esp+32], -1 |
260 | 280 | ||
261 | ret |
281 | ret |
262 | 282 | ||
263 | 283 | ||
264 | 284 | ||
265 | ;----------------------------------------------------------------- |
285 | ;----------------------------------------------------------------- |
266 | ; |
286 | ; |
267 | ; SOCKET_open |
287 | ; SOCKET_open |
268 | ; |
288 | ; |
269 | ; IN: domain in ecx |
289 | ; IN: domain in ecx |
270 | ; type in edx |
290 | ; type in edx |
271 | ; protocol in esi |
291 | ; protocol in esi |
272 | ; OUT: eax is socket num, -1 on error |
292 | ; OUT: eax is socket num, -1 on error |
273 | ; |
293 | ; |
274 | ;----------------------------------------------------------------- |
294 | ;----------------------------------------------------------------- |
275 | align 4 |
295 | align 4 |
276 | SOCKET_open: |
296 | SOCKET_open: |
277 | 297 | ||
278 | DEBUGF 1,"SOCKET_open: domain=%u type=%u protocol=%x\n", ecx, edx, esi |
298 | DEBUGF 1,"SOCKET_open: domain=%u type=%u protocol=%x\n", ecx, edx, esi |
279 | 299 | ||
280 | push ecx edx esi |
300 | push ecx edx esi |
281 | call SOCKET_alloc |
301 | call SOCKET_alloc |
282 | pop esi edx ecx |
302 | pop esi edx ecx |
283 | jz s_error |
303 | jz s_error |
284 | 304 | ||
285 | mov [esp+32], edi ; return socketnumber |
305 | mov [esp+32], edi ; return socketnumber |
286 | 306 | ||
287 | mov [eax + SOCKET.Domain], ecx |
307 | mov [eax + SOCKET.Domain], ecx |
288 | mov [eax + SOCKET.Type], edx |
308 | mov [eax + SOCKET.Type], edx |
289 | mov [eax + SOCKET.Protocol], esi |
309 | mov [eax + SOCKET.Protocol], esi |
290 | 310 | ||
291 | cmp ecx, AF_INET4 |
311 | cmp ecx, AF_INET4 |
292 | jne .no_inet4 |
312 | jne .no_inet4 |
293 | 313 | ||
294 | cmp edx, SOCK_DGRAM |
314 | cmp edx, SOCK_DGRAM |
295 | je .udp |
315 | je .udp |
296 | 316 | ||
297 | cmp edx, SOCK_STREAM |
317 | cmp edx, SOCK_STREAM |
298 | je .tcp |
318 | je .tcp |
299 | 319 | ||
300 | cmp edx, SOCK_RAW |
320 | cmp edx, SOCK_RAW |
301 | je .raw |
321 | je .raw |
302 | 322 | ||
303 | .no_inet4: |
323 | .no_inet4: |
304 | cmp ecx, AF_PPP |
324 | cmp ecx, AF_PPP |
305 | jne .no_ppp |
325 | jne .no_ppp |
306 | 326 | ||
307 | cmp esi, PPP_PROTO_ETHERNET |
327 | cmp esi, PPP_PROTO_ETHERNET |
308 | je .pppoe |
328 | je .pppoe |
309 | 329 | ||
310 | .no_ppp: |
330 | .no_ppp: |
311 | ret |
331 | ret |
312 | 332 | ||
313 | align 4 |
333 | align 4 |
314 | .raw: |
334 | .raw: |
315 | test esi, esi ; IP_PROTO_IP |
335 | test esi, esi ; IP_PROTO_IP |
316 | jz .ip |
336 | jz .ip |
317 | 337 | ||
318 | cmp esi, IP_PROTO_ICMP |
338 | cmp esi, IP_PROTO_ICMP |
319 | je .icmp |
339 | je .icmp |
320 | 340 | ||
321 | cmp esi, IP_PROTO_UDP |
341 | cmp esi, IP_PROTO_UDP |
322 | je .udp |
342 | je .udp |
323 | 343 | ||
324 | cmp esi, IP_PROTO_TCP |
344 | cmp esi, IP_PROTO_TCP |
325 | je .tcp |
345 | je .tcp |
326 | 346 | ||
327 | ret |
347 | ret |
328 | 348 | ||
329 | align 4 |
349 | align 4 |
330 | .udp: |
350 | .udp: |
331 | mov [eax + SOCKET.Protocol], IP_PROTO_UDP |
351 | mov [eax + SOCKET.Protocol], IP_PROTO_UDP |
332 | mov [eax + SOCKET.snd_proc], SOCKET_send_udp |
352 | mov [eax + SOCKET.snd_proc], SOCKET_send_udp |
333 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
353 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
334 | ret |
354 | ret |
335 | 355 | ||
336 | align 4 |
356 | align 4 |
337 | .tcp: |
357 | .tcp: |
338 | mov [eax + SOCKET.Protocol], IP_PROTO_TCP |
358 | mov [eax + SOCKET.Protocol], IP_PROTO_TCP |
339 | mov [eax + SOCKET.snd_proc], SOCKET_send_tcp |
359 | mov [eax + SOCKET.snd_proc], SOCKET_send_tcp |
340 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_tcp |
360 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_tcp |
341 | 361 | ||
342 | TCP_init_socket eax |
362 | TCP_init_socket eax |
343 | ret |
363 | ret |
344 | 364 | ||
345 | 365 | ||
346 | align 4 |
366 | align 4 |
347 | .ip: |
367 | .ip: |
348 | mov [eax + SOCKET.snd_proc], SOCKET_send_ip |
368 | mov [eax + SOCKET.snd_proc], SOCKET_send_ip |
349 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
369 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
350 | ret |
370 | ret |
351 | 371 | ||
352 | 372 | ||
353 | align 4 |
373 | align 4 |
354 | .icmp: |
374 | .icmp: |
355 | mov [eax + SOCKET.snd_proc], SOCKET_send_icmp |
375 | mov [eax + SOCKET.snd_proc], SOCKET_send_icmp |
356 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
376 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
357 | ret |
377 | ret |
358 | 378 | ||
359 | align 4 |
379 | align 4 |
360 | .pppoe: |
380 | .pppoe: |
361 | push eax |
381 | push eax |
362 | init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue |
382 | init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue |
363 | pop eax |
383 | pop eax |
364 | 384 | ||
365 | mov [eax + SOCKET.snd_proc], SOCKET_send_pppoe |
385 | mov [eax + SOCKET.snd_proc], SOCKET_send_pppoe |
366 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
386 | mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
367 | ret |
387 | ret |
368 | 388 | ||
369 | 389 | ||
370 | ;----------------------------------------------------------------- |
390 | ;----------------------------------------------------------------- |
371 | ; |
391 | ; |
372 | ; SOCKET_bind |
392 | ; SOCKET_bind |
373 | ; |
393 | ; |
374 | ; IN: socket number in ecx |
394 | ; IN: socket number in ecx |
375 | ; pointer to sockaddr struct in edx |
395 | ; pointer to sockaddr struct in edx |
376 | ; length of that struct in esi |
396 | ; length of that struct in esi |
377 | ; OUT: 0 on success |
397 | ; OUT: 0 on success |
378 | ; |
398 | ; |
379 | ;----------------------------------------------------------------- |
399 | ;----------------------------------------------------------------- |
380 | align 4 |
400 | align 4 |
381 | SOCKET_bind: |
401 | SOCKET_bind: |
382 | 402 | ||
383 | DEBUGF 1,"SOCKET_bind: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi |
403 | DEBUGF 1,"SOCKET_bind: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi |
384 | 404 | ||
385 | call SOCKET_num_to_ptr |
405 | call SOCKET_num_to_ptr |
386 | jz s_error |
406 | jz s_error |
387 | 407 | ||
388 | cmp esi, 2 |
408 | cmp esi, 2 |
389 | jb s_error |
409 | jb s_error |
390 | 410 | ||
391 | cmp word [edx], AF_INET4 |
411 | cmp word [edx], AF_INET4 |
392 | je .af_inet4 |
412 | je .af_inet4 |
393 | 413 | ||
394 | cmp word [edx], AF_UNIX |
414 | cmp word [edx], AF_UNIX |
395 | je .af_unix |
415 | je .af_unix |
396 | 416 | ||
397 | jmp s_error |
417 | jmp s_error |
398 | 418 | ||
399 | .af_unix: |
419 | .af_unix: |
400 | ; TODO: write code here |
420 | ; TODO: write code here |
401 | 421 | ||
402 | mov dword [esp+32], 0 |
422 | mov dword [esp+32], 0 |
403 | ret |
423 | ret |
404 | 424 | ||
405 | .af_inet4: |
425 | .af_inet4: |
406 | 426 | ||
407 | cmp esi, 6 |
427 | cmp esi, 6 |
408 | jb s_error |
428 | jb s_error |
409 | 429 | ||
410 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
430 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
411 | je .udp |
431 | je .udp |
412 | 432 | ||
413 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
433 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
414 | je .tcp |
434 | je .tcp |
415 | 435 | ||
416 | jmp s_error |
436 | jmp s_error |
417 | 437 | ||
418 | .tcp: |
438 | .tcp: |
419 | .udp: |
439 | .udp: |
420 | 440 | ||
421 | mov ebx, [edx + 4] ; First, fill in the IP |
441 | mov ebx, [edx + 4] ; First, fill in the IP |
422 | test ebx, ebx ; If IP is 0, use default |
442 | test ebx, ebx ; If IP is 0, use default |
423 | jnz @f |
443 | jnz @f |
424 | mov ebx, [NET_DEFAULT] |
444 | mov ebx, [NET_DEFAULT] |
425 | mov ebx, [IP_LIST + 4*ebx] |
445 | mov ebx, [IP_LIST + 4*ebx] |
426 | @@: |
446 | @@: |
427 | mov [eax + IP_SOCKET.LocalIP], ebx |
447 | mov [eax + IP_SOCKET.LocalIP], ebx |
428 | 448 | ||
429 | mov bx, [edx + 2] ; Now fill in the port if it's still available |
449 | mov bx, [edx + 2] ; Now fill in the port if it's still available |
430 | call SOCKET_check_port |
450 | call SOCKET_check_port |
431 | jz s_error ; ZF is set by socket_check_port, on error |
451 | jz s_error ; ZF is set by socket_check_port, on error |
432 | 452 | ||
433 | DEBUGF 1,"SOCKET_bind: local ip=%u.%u.%u.%u\n",\ |
453 | DEBUGF 1,"SOCKET_bind: local ip=%u.%u.%u.%u\n",\ |
434 | [eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\ |
454 | [eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\ |
435 | [eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1 |
455 | [eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1 |
436 | 456 | ||
437 | mov dword [esp+32], 0 |
457 | mov dword [esp+32], 0 |
438 | ret |
458 | ret |
439 | 459 | ||
440 | 460 | ||
441 | 461 | ||
442 | 462 | ||
443 | ;----------------------------------------------------------------- |
463 | ;----------------------------------------------------------------- |
444 | ; |
464 | ; |
445 | ; SOCKET_connect |
465 | ; SOCKET_connect |
446 | ; |
466 | ; |
447 | ; IN: socket number in ecx |
467 | ; IN: socket number in ecx |
448 | ; pointer to sockaddr struct in edx |
468 | ; pointer to sockaddr struct in edx |
449 | ; length of that struct in esi |
469 | ; length of that struct in esi |
450 | ; OUT: 0 on success |
470 | ; OUT: 0 on success |
451 | ; |
471 | ; |
452 | ;----------------------------------------------------------------- |
472 | ;----------------------------------------------------------------- |
453 | align 4 |
473 | align 4 |
454 | SOCKET_connect: |
474 | SOCKET_connect: |
455 | 475 | ||
456 | DEBUGF 1,"SOCKET_connect: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi |
476 | DEBUGF 1,"SOCKET_connect: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi |
457 | 477 | ||
458 | call SOCKET_num_to_ptr |
478 | call SOCKET_num_to_ptr |
459 | jz s_error |
479 | jz s_error |
460 | 480 | ||
461 | cmp esi, 8 |
481 | cmp esi, 8 |
462 | jb s_error |
482 | jb s_error |
463 | 483 | ||
464 | cmp word [edx], AF_INET4 |
484 | cmp word [edx], AF_INET4 |
465 | je .af_inet4 |
485 | je .af_inet4 |
466 | 486 | ||
467 | jmp s_error |
487 | jmp s_error |
468 | 488 | ||
469 | .af_inet4: |
489 | .af_inet4: |
470 | cmp [eax + IP_SOCKET.LocalIP], 0 |
490 | cmp [eax + IP_SOCKET.LocalIP], 0 |
471 | jne @f |
491 | jne @f |
472 | push [IP_LIST] |
492 | push [IP_LIST] |
473 | pop [eax + IP_SOCKET.LocalIP] |
493 | pop [eax + IP_SOCKET.LocalIP] |
474 | @@: |
494 | @@: |
475 | 495 | ||
476 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
496 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
477 | je .udp |
497 | je .udp |
478 | 498 | ||
479 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
499 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
480 | je .tcp |
500 | je .tcp |
481 | 501 | ||
482 | cmp [eax + SOCKET.Protocol], IP_PROTO_IP |
502 | cmp [eax + SOCKET.Protocol], IP_PROTO_IP |
483 | je .ip |
503 | je .ip |
484 | 504 | ||
485 | cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP |
505 | cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP |
486 | je .ip |
506 | je .ip |
487 | 507 | ||
488 | jmp s_error |
508 | jmp s_error |
489 | 509 | ||
490 | align 4 |
510 | align 4 |
491 | .udp: |
511 | .udp: |
492 | pusha |
512 | pusha |
493 | lea ecx, [eax + SOCKET.mutex] |
513 | lea ecx, [eax + SOCKET.mutex] |
494 | call mutex_lock |
514 | call mutex_lock |
495 | popa |
515 | popa |
496 | 516 | ||
497 | pushw [edx + 2] |
517 | pushw [edx + 2] |
498 | pop [eax + UDP_SOCKET.RemotePort] |
518 | pop [eax + UDP_SOCKET.RemotePort] |
499 | 519 | ||
500 | pushd [edx + 4] |
520 | pushd [edx + 4] |
501 | pop [eax + IP_SOCKET.RemoteIP] |
521 | pop [eax + IP_SOCKET.RemoteIP] |
502 | 522 | ||
503 | cmp [eax + UDP_SOCKET.LocalPort], 0 |
523 | cmp [eax + UDP_SOCKET.LocalPort], 0 |
504 | jne @f |
524 | jne @f |
505 | call SOCKET_find_port |
525 | call SOCKET_find_port |
506 | @@: |
526 | @@: |
507 | 527 | ||
508 | mov [eax + UDP_SOCKET.firstpacket], 0 |
528 | mov [eax + UDP_SOCKET.firstpacket], 0 |
509 | 529 | ||
510 | push eax |
530 | push eax |
511 | init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue |
531 | init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue |
512 | pop eax |
532 | pop eax |
513 | 533 | ||
514 | lea ecx, [eax + SOCKET.mutex] |
534 | lea ecx, [eax + SOCKET.mutex] |
515 | call mutex_unlock |
535 | call mutex_unlock |
516 | 536 | ||
517 | mov dword [esp+32], 0 |
537 | mov dword [esp+32], 0 |
518 | ret |
538 | ret |
519 | 539 | ||
520 | align 4 |
540 | align 4 |
521 | .tcp: |
541 | .tcp: |
522 | pusha |
542 | pusha |
523 | lea ecx, [eax + SOCKET.mutex] |
543 | lea ecx, [eax + SOCKET.mutex] |
524 | call mutex_lock |
544 | call mutex_lock |
525 | popa |
545 | popa |
526 | 546 | ||
527 | pushw [edx + 2] |
547 | pushw [edx + 2] |
528 | pop [eax + TCP_SOCKET.RemotePort] |
548 | pop [eax + TCP_SOCKET.RemotePort] |
529 | 549 | ||
530 | pushd [edx + 4] |
550 | pushd [edx + 4] |
531 | pop [eax + IP_SOCKET.RemoteIP] |
551 | pop [eax + IP_SOCKET.RemoteIP] |
532 | 552 | ||
533 | cmp [eax + TCP_SOCKET.LocalPort], 0 |
553 | cmp [eax + TCP_SOCKET.LocalPort], 0 |
534 | jne @f |
554 | jne @f |
535 | call SOCKET_find_port |
555 | call SOCKET_find_port |
536 | @@: |
556 | @@: |
537 | 557 | ||
538 | mov [eax + TCP_SOCKET.timer_persist], 0 |
558 | mov [eax + TCP_SOCKET.timer_persist], 0 |
539 | mov [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT |
559 | mov [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT |
540 | 560 | ||
541 | push [TCP_sequence_num] |
561 | push [TCP_sequence_num] |
542 | add [TCP_sequence_num], 6400 |
562 | add [TCP_sequence_num], 6400 |
543 | pop [eax + TCP_SOCKET.ISS] |
563 | pop [eax + TCP_SOCKET.ISS] |
544 | mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init |
564 | mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init |
545 | 565 | ||
546 | 566 | ||
547 | TCP_sendseqinit eax |
567 | TCP_sendseqinit eax |
548 | 568 | ||
549 | ; mov [ebx + TCP_SOCKET.timer_retransmission], ;; todo: create macro to set retransmission timer |
569 | ; mov [ebx + TCP_SOCKET.timer_retransmission], ;; todo: create macro to set retransmission timer |
550 | 570 | ||
551 | mov ebx, eax |
571 | mov ebx, eax |
552 | 572 | ||
553 | lea eax, [ebx + STREAM_SOCKET.snd] |
573 | lea eax, [ebx + STREAM_SOCKET.snd] |
554 | call SOCKET_ring_create |
574 | call SOCKET_ring_create |
555 | 575 | ||
556 | lea eax, [ebx + STREAM_SOCKET.rcv] |
576 | lea eax, [ebx + STREAM_SOCKET.rcv] |
557 | call SOCKET_ring_create |
577 | call SOCKET_ring_create |
558 | 578 | ||
559 | pusha |
579 | pusha |
560 | lea ecx, [ebx + SOCKET.mutex] |
580 | lea ecx, [ebx + SOCKET.mutex] |
561 | call mutex_unlock |
581 | call mutex_unlock |
562 | popa |
582 | popa |
563 | 583 | ||
564 | mov eax, ebx |
584 | mov eax, ebx |
565 | call TCP_output |
585 | call TCP_output |
- | 586 | ||
- | 587 | ;;; TODO: wait for successfull connection if blocking socket |
|
566 | 588 | ||
567 | mov dword [esp+32], 0 |
589 | mov dword [esp+32], 0 |
568 | ret |
590 | ret |
569 | 591 | ||
570 | align 4 |
592 | align 4 |
571 | .ip: |
593 | .ip: |
572 | pusha |
594 | pusha |
573 | lea ecx, [eax + SOCKET.mutex] |
595 | lea ecx, [eax + SOCKET.mutex] |
574 | call mutex_lock |
596 | call mutex_lock |
575 | popa |
597 | popa |
576 | 598 | ||
577 | pushd [edx + 4] |
599 | pushd [edx + 4] |
578 | pop [eax + IP_SOCKET.RemoteIP] |
600 | pop [eax + IP_SOCKET.RemoteIP] |
579 | 601 | ||
580 | push eax |
602 | push eax |
581 | init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue |
603 | init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue |
582 | pop eax |
604 | pop eax |
583 | 605 | ||
584 | lea ecx, [eax + SOCKET.mutex] |
606 | lea ecx, [eax + SOCKET.mutex] |
585 | call mutex_unlock |
607 | call mutex_unlock |
586 | 608 | ||
587 | mov dword [esp+32], 0 |
609 | mov dword [esp+32], 0 |
588 | ret |
610 | ret |
589 | 611 | ||
590 | 612 | ||
591 | ;----------------------------------------------------------------- |
613 | ;----------------------------------------------------------------- |
592 | ; |
614 | ; |
593 | ; SOCKET_listen |
615 | ; SOCKET_listen |
594 | ; |
616 | ; |
595 | ; IN: socket number in ecx |
617 | ; IN: socket number in ecx |
596 | ; backlog in edx |
618 | ; backlog in edx |
597 | ; OUT: eax is socket num, -1 on error |
619 | ; OUT: eax is socket num, -1 on error |
598 | ; |
620 | ; |
599 | ;----------------------------------------------------------------- |
621 | ;----------------------------------------------------------------- |
600 | align 4 |
622 | align 4 |
601 | SOCKET_listen: |
623 | SOCKET_listen: |
602 | 624 | ||
603 | DEBUGF 1,"SOCKET_listen: socknum=%u backlog=%u\n", ecx, edx |
625 | DEBUGF 1,"SOCKET_listen: socknum=%u backlog=%u\n", ecx, edx |
604 | 626 | ||
605 | call SOCKET_num_to_ptr |
627 | call SOCKET_num_to_ptr |
606 | jz s_error |
628 | jz s_error |
607 | 629 | ||
608 | cmp [eax + SOCKET.Domain], AF_INET4 |
630 | cmp [eax + SOCKET.Domain], AF_INET4 |
609 | jne s_error |
631 | jne s_error |
610 | 632 | ||
611 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
633 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
612 | jne s_error |
634 | jne s_error |
613 | 635 | ||
614 | cmp [eax + TCP_SOCKET.LocalPort], 0 |
636 | cmp [eax + TCP_SOCKET.LocalPort], 0 |
615 | je s_error |
637 | je s_error |
616 | 638 | ||
617 | cmp [eax + IP_SOCKET.LocalIP], 0 |
639 | cmp [eax + IP_SOCKET.LocalIP], 0 |
618 | jne @f |
640 | jne @f |
619 | push [IP_LIST] |
641 | push [IP_LIST] |
620 | pop [eax + IP_SOCKET.LocalIP] |
642 | pop [eax + IP_SOCKET.LocalIP] |
621 | @@: |
643 | @@: |
622 | 644 | ||
623 | cmp edx, MAX_backlog |
645 | cmp edx, MAX_backlog |
624 | jbe @f |
646 | jbe @f |
625 | mov edx, MAX_backlog |
647 | mov edx, MAX_backlog |
626 | @@: |
648 | @@: |
627 | 649 | ||
628 | mov [eax + SOCKET.backlog], dx |
650 | mov [eax + SOCKET.backlog], dx |
629 | or [eax + SOCKET.options], SO_ACCEPTCON |
651 | or [eax + SOCKET.options], SO_ACCEPTCON |
630 | mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN |
652 | mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN |
631 | mov [eax + TCP_SOCKET.timer_keepalive], 0 ; disable keepalive timer |
653 | mov [eax + TCP_SOCKET.timer_keepalive], 0 ; disable keepalive timer |
632 | 654 | ||
633 | push eax |
655 | push eax |
634 | init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up sockets queue |
656 | init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up sockets queue |
635 | pop eax |
657 | pop eax |
636 | 658 | ||
637 | mov dword [esp+32], 0 |
659 | mov dword [esp+32], 0 |
638 | 660 | ||
639 | ret |
661 | ret |
640 | 662 | ||
641 | 663 | ||
642 | ;----------------------------------------------------------------- |
664 | ;----------------------------------------------------------------- |
643 | ; |
665 | ; |
644 | ; SOCKET_accept |
666 | ; SOCKET_accept |
645 | ; |
667 | ; |
646 | ; IN: socket number in ecx |
668 | ; IN: socket number in ecx |
647 | ; addr in edx |
669 | ; addr in edx |
648 | ; addrlen in esi |
670 | ; addrlen in esi |
649 | ; OUT: eax is socket num, -1 on error |
671 | ; OUT: eax is socket num, -1 on error |
650 | ; |
672 | ; |
651 | ;----------------------------------------------------------------- |
673 | ;----------------------------------------------------------------- |
652 | align 4 |
674 | align 4 |
653 | SOCKET_accept: |
675 | SOCKET_accept: |
654 | 676 | ||
655 | DEBUGF 1,"SOCKET_accept: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi |
677 | DEBUGF 1,"SOCKET_accept: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi |
656 | 678 | ||
657 | call SOCKET_num_to_ptr |
679 | call SOCKET_num_to_ptr |
658 | jz s_error |
680 | jz s_error |
659 | 681 | ||
660 | test [eax + SOCKET.options], SO_ACCEPTCON |
682 | test [eax + SOCKET.options], SO_ACCEPTCON |
661 | jz s_error |
683 | jz s_error |
662 | 684 | ||
663 | cmp [eax + SOCKET.Domain], AF_INET4 |
685 | cmp [eax + SOCKET.Domain], AF_INET4 |
664 | jne s_error |
686 | jne s_error |
665 | 687 | ||
666 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
688 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
667 | jne s_error |
689 | jne s_error |
- | 690 | ||
668 | 691 | .loop: |
|
- | 692 | get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .block |
|
- | 693 | ||
669 | get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, s_error |
694 | ; Ok, we got a socket ptr |
670 | mov eax, [esi] |
695 | mov eax, [esi] |
671 | 696 | ||
672 | ; Change PID to that of the current process |
697 | ; Change PID to that of the current process |
673 | mov ebx, [TASK_BASE] |
698 | mov ebx, [TASK_BASE] |
674 | mov ebx, [ebx + TASKDATA.pid] |
699 | mov ebx, [ebx + TASKDATA.pid] |
675 | mov [eax + SOCKET.PID], ebx |
700 | mov [eax + SOCKET.PID], ebx |
- | 701 | ||
676 | 702 | ; Convert it to a socket number |
|
677 | call SOCKET_ptr_to_num |
703 | call SOCKET_ptr_to_num |
- | 704 | jz s_error |
|
678 | jz s_error |
705 | ; and return it to caller |
679 | mov [esp+32], eax |
706 | mov [esp+32], eax |
680 | ret |
707 | ret |
- | 708 | ||
- | 709 | .block: |
|
681 | 710 | SOCKET_block eax, .loop, s_error |
|
682 | 711 | ||
683 | ;----------------------------------------------------------------- |
712 | ;----------------------------------------------------------------- |
684 | ; |
713 | ; |
685 | ; SOCKET_close |
714 | ; SOCKET_close |
686 | ; |
715 | ; |
687 | ; IN: socket number in ecx |
716 | ; IN: socket number in ecx |
688 | ; OUT: eax is socket num, -1 on error |
717 | ; OUT: eax is socket num, -1 on error |
689 | ; |
718 | ; |
690 | ;----------------------------------------------------------------- |
719 | ;----------------------------------------------------------------- |
691 | align 4 |
720 | align 4 |
692 | SOCKET_close: |
721 | SOCKET_close: |
693 | 722 | ||
694 | DEBUGF 1,"SOCKET_close: %u\n", ecx |
723 | DEBUGF 1,"SOCKET_close: %u\n", ecx |
695 | 724 | ||
696 | call SOCKET_num_to_ptr |
725 | call SOCKET_num_to_ptr |
697 | jz s_error |
726 | jz s_error |
698 | 727 | ||
699 | cmp [eax + SOCKET.Domain], AF_INET4 |
728 | cmp [eax + SOCKET.Domain], AF_INET4 |
700 | jne s_error |
729 | jne s_error |
701 | 730 | ||
702 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
731 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
703 | je .free |
732 | je .free |
704 | 733 | ||
705 | cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP |
734 | cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP |
706 | je .free |
735 | je .free |
707 | 736 | ||
708 | cmp [eax + SOCKET.Protocol], IP_PROTO_IP |
737 | cmp [eax + SOCKET.Protocol], IP_PROTO_IP |
709 | je .free |
738 | je .free |
710 | 739 | ||
711 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
740 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
712 | je .tcp |
741 | je .tcp |
713 | 742 | ||
714 | jmp s_error |
743 | jmp s_error |
715 | 744 | ||
716 | .tcp: |
745 | .tcp: |
717 | cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED ; state must be LISTEN, SYN_SENT or CLOSED |
746 | cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED ; state must be LISTEN, SYN_SENT or CLOSED |
718 | jb .free |
747 | jb .free |
719 | 748 | ||
720 | call TCP_usrclosed |
749 | call TCP_usrclosed |
721 | call TCP_output ;;;; Fixme: is this nescessary?? |
750 | call TCP_output ;;;; Fixme: is this nescessary?? |
- | 751 | ||
- | 752 | ;;; TODO: wait for successfull termination if blocking socket |
|
722 | mov dword [esp+32], 0 |
753 | mov dword [esp+32], 0 |
723 | 754 | ||
724 | ret |
755 | ret |
725 | 756 | ||
726 | .free: |
757 | .free: |
727 | call SOCKET_free |
758 | call SOCKET_free |
728 | mov dword [esp+32], 0 |
759 | mov dword [esp+32], 0 |
729 | 760 | ||
730 | ret |
761 | ret |
731 | 762 | ||
732 | 763 | ||
733 | ;----------------------------------------------------------------- |
764 | ;----------------------------------------------------------------- |
734 | ; |
765 | ; |
735 | ; SOCKET_receive |
766 | ; SOCKET_receive |
736 | ; |
767 | ; |
737 | ; IN: socket number in ecx |
768 | ; IN: socket number in ecx |
738 | ; addr to buffer in edx |
769 | ; addr to buffer in edx |
739 | ; length of buffer in esi |
770 | ; length of buffer in esi |
740 | ; flags in edi |
771 | ; flags in edi |
741 | ; OUT: eax is number of bytes copied, -1 on error |
772 | ; OUT: eax is number of bytes copied, -1 on error |
742 | ; |
773 | ; |
743 | ;----------------------------------------------------------------- |
774 | ;----------------------------------------------------------------- |
744 | align 4 |
775 | align 4 |
745 | SOCKET_receive: |
776 | SOCKET_receive: |
746 | 777 | ||
747 | DEBUGF 1,"SOCKET_receive: socknum=%u bufaddr=%x buflength=%u flags=%x\n", ecx, edx, esi, edi |
778 | DEBUGF 1,"SOCKET_receive: socknum=%u bufaddr=%x buflength=%u flags=%x\n", ecx, edx, esi, edi |
748 | 779 | ||
749 | call SOCKET_num_to_ptr |
780 | call SOCKET_num_to_ptr |
750 | jz s_error |
781 | jz s_error |
751 | 782 | ||
752 | jmp [eax + SOCKET.rcv_proc] |
783 | jmp [eax + SOCKET.rcv_proc] |
753 | 784 | ||
754 | 785 | ||
755 | align 4 |
786 | align 4 |
756 | SOCKET_receive_dgram: |
787 | SOCKET_receive_dgram: |
757 | 788 | ||
758 | DEBUGF 1,"SOCKET_receive: DGRAM\n" |
789 | DEBUGF 1,"SOCKET_receive: DGRAM\n" |
759 | 790 | ||
760 | mov ebx, esi |
791 | mov ebx, esi |
761 | mov edi, edx ; addr to buffer |
792 | mov edi, edx ; addr to buffer |
- | 793 | ||
762 | 794 | .loop: |
|
763 | get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, s_error ; destroys esi and ecx |
795 | get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, .block ; destroys esi and ecx |
764 | 796 | ||
765 | mov ecx, [esi + socket_queue_entry.data_size] |
797 | mov ecx, [esi + socket_queue_entry.data_size] |
766 | DEBUGF 1,"SOCKET_receive: %u bytes data\n", ecx |
798 | DEBUGF 1,"SOCKET_receive: %u bytes data\n", ecx |
767 | 799 | ||
768 | cmp ecx, ebx |
800 | cmp ecx, ebx |
769 | ja .too_small |
801 | ja .too_small |
770 | 802 | ||
771 | push [esi + socket_queue_entry.buf_ptr] ; save the buffer addr so we can clear it later |
803 | push [esi + socket_queue_entry.buf_ptr] ; save the buffer addr so we can clear it later |
772 | mov esi, [esi + socket_queue_entry.data_ptr] |
804 | mov esi, [esi + socket_queue_entry.data_ptr] |
773 | DEBUGF 1,"SOCKET_receive: Source buffer=%x real addr=%x\n", [esp], esi |
805 | DEBUGF 1,"SOCKET_receive: Source buffer=%x real addr=%x\n", [esp], esi |
774 | mov [esp+32+4], ecx ; return number of bytes copied |
806 | mov [esp+32+4], ecx ; return number of bytes copied |
775 | 807 | ||
776 | ; copy the data |
808 | ; copy the data |
777 | shr ecx, 1 |
809 | shr ecx, 1 |
778 | jnc .nb |
810 | jnc .nb |
779 | movsb |
811 | movsb |
780 | .nb: |
812 | .nb: |
781 | shr ecx, 1 |
813 | shr ecx, 1 |
782 | jnc .nw |
814 | jnc .nw |
783 | movsw |
815 | movsw |
784 | .nw: |
816 | .nw: |
785 | test ecx, ecx |
817 | test ecx, ecx |
786 | jz .nd |
818 | jz .nd |
787 | rep movsd |
819 | rep movsd |
788 | .nd: |
820 | .nd: |
789 | 821 | ||
790 | call kernel_free ; remove the packet |
822 | call kernel_free ; remove the packet |
791 | ret |
823 | ret |
792 | 824 | ||
793 | .too_small: |
825 | .too_small: |
794 | 826 | ||
795 | DEBUGF 1,"SOCKET_receive: Buffer too small\n" |
827 | DEBUGF 1,"SOCKET_receive: Buffer too small\n" |
796 | jmp s_error |
828 | jmp s_error |
- | 829 | ||
- | 830 | .block: |
|
- | 831 | SOCKET_block eax, .loop, s_error |
|
- | 832 | ||
797 | 833 | ||
798 | align 4 |
834 | align 4 |
799 | SOCKET_receive_tcp: |
835 | SOCKET_receive_tcp: |
800 | 836 | ||
801 | DEBUGF 1,"SOCKET_receive: TCP\n" |
837 | DEBUGF 1,"SOCKET_receive: TCP\n" |
802 | 838 | ||
803 | mov ecx, esi |
839 | mov ecx, esi |
804 | mov edi, edx |
840 | mov edi, edx |
805 | add eax, STREAM_SOCKET.rcv |
- | |
806 | xor edx, edx |
841 | xor edx, edx |
- | 842 | add eax, STREAM_SOCKET.rcv |
|
- | 843 | .loop: ;;;; FIXME: ecx! |
|
807 | call SOCKET_ring_read |
844 | call SOCKET_ring_read |
- | 845 | test ecx, ecx |
|
- | 846 | jz .block |
|
808 | call SOCKET_ring_free |
847 | call SOCKET_ring_free |
809 | 848 | ||
810 | mov [esp+32], ecx ; return number of bytes copied |
849 | mov [esp+32], ecx ; return number of bytes copied |
811 | - | ||
812 | ret |
850 | ret |
- | 851 | ||
- | 852 | .block: |
|
- | 853 | SOCKET_block (eax - STREAM_SOCKET.rcv), .loop, s_error |
|
813 | 854 | ||
814 | 855 | ||
815 | ;----------------------------------------------------------------- |
856 | ;----------------------------------------------------------------- |
816 | ; |
857 | ; |
817 | ; SOCKET_send |
858 | ; SOCKET_send |
818 | ; |
859 | ; |
819 | ; |
860 | ; |
820 | ; IN: socket number in ecx |
861 | ; IN: socket number in ecx |
821 | ; pointer to data in edx |
862 | ; pointer to data in edx |
822 | ; datalength in esi |
863 | ; datalength in esi |
823 | ; flags in edi |
864 | ; flags in edi |
824 | ; OUT: -1 on error |
865 | ; OUT: -1 on error |
825 | ; |
866 | ; |
826 | ;----------------------------------------------------------------- |
867 | ;----------------------------------------------------------------- |
827 | align 4 |
868 | align 4 |
828 | SOCKET_send: |
869 | SOCKET_send: |
829 | 870 | ||
830 | DEBUGF 1,"SOCKET_send: socknum=%u data ptr=%x length=%u flags=%x\n", ecx, edx, esi, edi |
871 | DEBUGF 1,"SOCKET_send: socknum=%u data ptr=%x length=%u flags=%x\n", ecx, edx, esi, edi |
831 | 872 | ||
832 | call SOCKET_num_to_ptr |
873 | call SOCKET_num_to_ptr |
833 | jz s_error |
874 | jz s_error |
834 | 875 | ||
835 | mov ecx, esi |
876 | mov ecx, esi |
836 | mov esi, edx |
877 | mov esi, edx |
837 | 878 | ||
838 | jmp [eax + SOCKET.snd_proc] |
879 | jmp [eax + SOCKET.snd_proc] |
839 | 880 | ||
840 | 881 | ||
841 | align 4 |
882 | align 4 |
842 | SOCKET_send_udp: |
883 | SOCKET_send_udp: |
843 | 884 | ||
844 | DEBUGF 1,"SOCKET_send: UDP\n" |
885 | DEBUGF 1,"SOCKET_send: UDP\n" |
845 | 886 | ||
846 | mov [esp+32], ecx |
887 | mov [esp+32], ecx |
847 | call UDP_output |
888 | call UDP_output |
848 | cmp eax, -1 |
889 | cmp eax, -1 |
849 | je s_error |
890 | je s_error |
850 | ret |
891 | ret |
851 | 892 | ||
852 | 893 | ||
853 | align 4 |
894 | align 4 |
854 | SOCKET_send_tcp: |
895 | SOCKET_send_tcp: |
855 | 896 | ||
856 | DEBUGF 1,"SOCKET_send: TCP\n" |
897 | DEBUGF 1,"SOCKET_send: TCP\n" |
857 | 898 | ||
858 | push eax |
899 | push eax |
859 | add eax, STREAM_SOCKET.snd |
900 | add eax, STREAM_SOCKET.snd |
860 | call SOCKET_ring_write |
901 | call SOCKET_ring_write |
861 | pop eax |
902 | pop eax |
862 | 903 | ||
863 | mov [esp+32], ecx |
904 | mov [esp+32], ecx |
864 | 905 | ||
865 | call TCP_output |
906 | call TCP_output |
866 | ret |
907 | ret |
867 | 908 | ||
868 | 909 | ||
869 | align 4 |
910 | align 4 |
870 | SOCKET_send_ip: |
911 | SOCKET_send_ip: |
871 | 912 | ||
872 | DEBUGF 1,"SOCKET_send: IPv4\n" |
913 | DEBUGF 1,"SOCKET_send: IPv4\n" |
873 | 914 | ||
874 | mov [esp+32], ecx |
915 | mov [esp+32], ecx |
875 | call IPv4_output_raw |
916 | call IPv4_output_raw |
876 | cmp eax, -1 |
917 | cmp eax, -1 |
877 | je s_error |
918 | je s_error |
878 | ret |
919 | ret |
879 | 920 | ||
880 | 921 | ||
881 | align 4 |
922 | align 4 |
882 | SOCKET_send_icmp: |
923 | SOCKET_send_icmp: |
883 | 924 | ||
884 | DEBUGF 1,"SOCKET_send: ICMP\n" |
925 | DEBUGF 1,"SOCKET_send: ICMP\n" |
885 | 926 | ||
886 | mov [esp+32], ecx |
927 | mov [esp+32], ecx |
887 | call ICMP_output_raw |
928 | call ICMP_output_raw |
888 | cmp eax, -1 |
929 | cmp eax, -1 |
889 | je s_error |
930 | je s_error |
890 | ret |
931 | ret |
891 | 932 | ||
892 | 933 | ||
893 | align 4 |
934 | align 4 |
894 | SOCKET_send_pppoe: |
935 | SOCKET_send_pppoe: |
895 | 936 | ||
896 | DEBUGF 1,"SOCKET_send: PPPoE\n" |
937 | DEBUGF 1,"SOCKET_send: PPPoE\n" |
897 | 938 | ||
898 | mov [esp+32], ecx |
939 | mov [esp+32], ecx |
899 | mov ebx, [eax + SOCKET.device] |
940 | mov ebx, [eax + SOCKET.device] |
900 | 941 | ||
901 | call PPPoE_discovery_output |
942 | call PPPoE_discovery_output |
902 | cmp eax, -1 |
943 | cmp eax, -1 |
903 | je s_error |
944 | je s_error |
904 | ret |
945 | ret |
905 | 946 | ||
906 | 947 | ||
907 | 948 | ||
908 | 949 | ||
909 | ;----------------------------------------------------------------- |
950 | ;----------------------------------------------------------------- |
910 | ; |
951 | ; |
911 | ; SOCKET_get_options |
952 | ; SOCKET_get_options |
912 | ; |
953 | ; |
913 | ; IN: ecx = socket number |
954 | ; IN: ecx = socket number |
914 | ; edx = pointer to the options: |
955 | ; edx = pointer to the options: |
915 | ; dd level, optname, optval, optlen |
956 | ; dd level, optname, optval, optlen |
916 | ; OUT: -1 on error |
957 | ; OUT: -1 on error |
917 | ; |
958 | ; |
918 | ; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP. |
959 | ; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP. |
919 | ; TODO: find best way to notify that send()'ed data were acknowledged |
960 | ; TODO: find best way to notify that send()'ed data were acknowledged |
920 | ; Also pseudo-optname -3 is valid and returns socket state, one of TCPS_*. |
961 | ; Also pseudo-optname -3 is valid and returns socket state, one of TCPS_*. |
921 | ; |
962 | ; |
922 | ;----------------------------------------------------------------- |
963 | ;----------------------------------------------------------------- |
923 | align 4 |
964 | align 4 |
924 | SOCKET_get_opt: |
965 | SOCKET_get_opt: |
925 | 966 | ||
926 | DEBUGF 1,"SOCKET_get_opt\n" |
967 | DEBUGF 1,"SOCKET_get_opt\n" |
927 | 968 | ||
928 | call SOCKET_num_to_ptr |
969 | call SOCKET_num_to_ptr |
929 | jz s_error |
970 | jz s_error |
930 | 971 | ||
931 | cmp dword [edx], IP_PROTO_TCP |
972 | cmp dword [edx], IP_PROTO_TCP |
932 | jne s_error |
973 | jne s_error |
933 | cmp dword [edx+4], -2 |
974 | cmp dword [edx+4], -2 |
934 | je @f |
975 | je @f |
935 | cmp dword [edx+4], -3 |
976 | cmp dword [edx+4], -3 |
936 | jne s_error |
977 | jne s_error |
937 | @@: |
978 | @@: |
938 | ; mov eax, [edx+12] |
979 | ; mov eax, [edx+12] |
939 | ; test eax, eax |
980 | ; test eax, eax |
940 | ; jz .fail |
981 | ; jz .fail |
941 | ; cmp dword [eax], 4 |
982 | ; cmp dword [eax], 4 |
942 | ; mov dword [eax], 4 |
983 | ; mov dword [eax], 4 |
943 | ; jb .fail |
984 | ; jb .fail |
944 | ; stdcall net_socket_num_to_addr, ecx |
985 | ; stdcall net_socket_num_to_addr, ecx |
945 | ; test eax, eax |
986 | ; test eax, eax |
946 | ; jz .fail |
987 | ; jz .fail |
947 | ; ; todo: check that eax is really TCP socket |
988 | ; ; todo: check that eax is really TCP socket |
948 | ; mov ecx, [eax + TCP_SOCKET.last_ack_number] |
989 | ; mov ecx, [eax + TCP_SOCKET.last_ack_number] |
949 | ; cmp dword [edx+4], -2 |
990 | ; cmp dword [edx+4], -2 |
950 | ; jz @f |
991 | ; jz @f |
951 | ; mov ecx, [eax + TCP_SOCKET.state] |
992 | ; mov ecx, [eax + TCP_SOCKET.state] |
952 | @@: |
993 | @@: |
953 | mov eax, [edx+8] |
994 | mov eax, [edx+8] |
954 | test eax, eax |
995 | test eax, eax |
955 | jz @f |
996 | jz @f |
956 | mov [eax], ecx |
997 | mov [eax], ecx |
957 | @@: |
998 | @@: |
958 | mov dword [esp+32], 0 |
999 | mov dword [esp+32], 0 |
959 | ret |
1000 | ret |
960 | 1001 | ||
961 | 1002 | ||
962 | 1003 | ||
963 | ;----------------------------------------------------------------- |
1004 | ;----------------------------------------------------------------- |
964 | ; |
1005 | ; |
965 | ; SOCKET_set_options |
1006 | ; SOCKET_set_options |
966 | ; |
1007 | ; |
967 | ; IN: ecx = socket number |
1008 | ; IN: ecx = socket number |
968 | ; edx = pointer to the options: |
1009 | ; edx = pointer to the options: |
969 | ; dd level, optname, optlen, optval |
1010 | ; dd level, optname, optlen, optval |
970 | ; OUT: -1 on error |
1011 | ; OUT: -1 on error |
971 | ; |
1012 | ; |
972 | ;----------------------------------------------------------------- |
1013 | ;----------------------------------------------------------------- |
973 | align 4 |
1014 | align 4 |
974 | SOCKET_set_opt: |
1015 | SOCKET_set_opt: |
975 | 1016 | ||
976 | DEBUGF 1,"SOCKET_set_opt\n" |
1017 | DEBUGF 1,"SOCKET_set_opt\n" |
977 | 1018 | ||
978 | call SOCKET_num_to_ptr |
1019 | call SOCKET_num_to_ptr |
979 | jz s_error |
1020 | jz s_error |
980 | 1021 | ||
981 | cmp dword [edx], SOL_SOCKET |
1022 | cmp dword [edx], SOL_SOCKET |
982 | jne s_error |
1023 | jne s_error |
983 | 1024 | ||
984 | cmp dword [edx+4], SO_BINDTODEVICE |
1025 | cmp dword [edx+4], SO_BINDTODEVICE |
985 | je .bind |
1026 | je .bind |
986 | 1027 | ||
987 | jmp s_error |
1028 | jmp s_error |
988 | 1029 | ||
989 | .bind: |
1030 | .bind: |
990 | cmp dword [edx+8], 0 |
1031 | cmp dword [edx+8], 0 |
991 | je .unbind |
1032 | je .unbind |
992 | 1033 | ||
993 | movzx edx, byte [edx + 9] |
1034 | movzx edx, byte [edx + 9] |
994 | cmp edx, MAX_NET_DEVICES |
1035 | cmp edx, MAX_NET_DEVICES |
995 | ja s_error |
1036 | ja s_error |
996 | 1037 | ||
997 | mov edx, [NET_DRV_LIST + 4*edx] |
1038 | mov edx, [NET_DRV_LIST + 4*edx] |
998 | test edx, edx |
1039 | test edx, edx |
999 | jz s_error |
1040 | jz s_error |
1000 | mov [eax + SOCKET.device], edx |
1041 | mov [eax + SOCKET.device], edx |
1001 | 1042 | ||
1002 | DEBUGF 1,"SOCKET_set_opt: Bound socket %x to device %x\n",eax, edx |
1043 | DEBUGF 1,"SOCKET_set_opt: Bound socket %x to device %x\n",eax, edx |
1003 | 1044 | ||
1004 | mov dword [esp+32], 0 ; success! |
1045 | mov dword [esp+32], 0 ; success! |
1005 | ret |
1046 | ret |
1006 | 1047 | ||
1007 | .unbind: |
1048 | .unbind: |
1008 | mov [eax + SOCKET.device], 0 |
1049 | mov [eax + SOCKET.device], 0 |
1009 | 1050 | ||
1010 | mov dword [esp+32], 0 ; success! |
1051 | mov dword [esp+32], 0 ; success! |
1011 | ret |
1052 | ret |
1012 | 1053 | ||
1013 | 1054 | ||
1014 | 1055 | ||
1015 | ;----------------------------------------------------------------- |
1056 | ;----------------------------------------------------------------- |
1016 | ; |
1057 | ; |
1017 | ; SOCKET_debug |
1058 | ; SOCKET_debug |
1018 | ; |
1059 | ; |
1019 | ; Copies socket variables to application buffer |
1060 | ; Copies socket variables to application buffer |
1020 | ; |
1061 | ; |
1021 | ; IN: ecx = socket number |
1062 | ; IN: ecx = socket number |
1022 | ; edx = pointer to buffer |
1063 | ; edx = pointer to buffer |
1023 | ; |
1064 | ; |
1024 | ; OUT: -1 on error |
1065 | ; OUT: -1 on error |
1025 | ;----------------------------------------------------------------- |
1066 | ;----------------------------------------------------------------- |
1026 | align 4 |
1067 | align 4 |
1027 | SOCKET_debug: |
1068 | SOCKET_debug: |
1028 | 1069 | ||
1029 | DEBUGF 1,"SOCKET_debug\n" |
1070 | DEBUGF 1,"SOCKET_debug\n" |
1030 | 1071 | ||
1031 | call SOCKET_num_to_ptr |
1072 | call SOCKET_num_to_ptr |
1032 | jz s_error |
1073 | jz s_error |
1033 | 1074 | ||
1034 | mov esi, eax |
1075 | mov esi, eax |
1035 | mov edi, edx |
1076 | mov edi, edx |
1036 | mov ecx, SOCKETBUFFSIZE/4 |
1077 | mov ecx, SOCKETBUFFSIZE/4 |
1037 | rep movsd |
1078 | rep movsd |
1038 | 1079 | ||
1039 | mov dword [esp+32], 0 |
1080 | mov dword [esp+32], 0 |
1040 | ret |
1081 | ret |
1041 | 1082 | ||
1042 | 1083 | ||
1043 | ;----------------------------------------------------------------- |
1084 | ;----------------------------------------------------------------- |
1044 | ; |
1085 | ; |
1045 | ; SOCKET_find_port |
1086 | ; SOCKET_find_port |
1046 | ; |
1087 | ; |
1047 | ; Fills in the local port number for TCP and UDP sockets |
1088 | ; Fills in the local port number for TCP and UDP sockets |
1048 | ; This procedure always works because the number of sockets is |
1089 | ; This procedure always works because the number of sockets is |
1049 | ; limited to a smaller number then the number of possible ports |
1090 | ; limited to a smaller number then the number of possible ports |
1050 | ; |
1091 | ; |
1051 | ; IN: eax = socket pointer |
1092 | ; IN: eax = socket pointer |
1052 | ; OUT: / |
1093 | ; OUT: / |
1053 | ; |
1094 | ; |
1054 | ;----------------------------------------------------------------- |
1095 | ;----------------------------------------------------------------- |
1055 | align 4 |
1096 | align 4 |
1056 | SOCKET_find_port: |
1097 | SOCKET_find_port: |
1057 | 1098 | ||
1058 | DEBUGF 1,"SOCKET_find_port\n" |
1099 | DEBUGF 1,"SOCKET_find_port\n" |
1059 | 1100 | ||
1060 | push ebx esi ecx |
1101 | push ebx esi ecx |
1061 | 1102 | ||
1062 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
1103 | cmp [eax + SOCKET.Protocol], IP_PROTO_UDP |
1063 | je .udp |
1104 | je .udp |
1064 | 1105 | ||
1065 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
1106 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
1066 | je .tcp |
1107 | je .tcp |
1067 | 1108 | ||
1068 | jmp .error |
1109 | jmp .error |
1069 | 1110 | ||
1070 | .done: |
1111 | .done: |
1071 | mov [eax + UDP_SOCKET.LocalPort], bx |
1112 | mov [eax + UDP_SOCKET.LocalPort], bx |
1072 | .error: |
1113 | .error: |
1073 | pop ecx esi ebx |
1114 | pop ecx esi ebx |
1074 | ret |
1115 | ret |
1075 | 1116 | ||
1076 | .udp: |
1117 | .udp: |
1077 | mov bx, [last_UDP_port] |
1118 | mov bx, [last_UDP_port] |
1078 | call .findit |
1119 | call .findit |
1079 | mov [last_UDP_port], bx |
1120 | mov [last_UDP_port], bx |
1080 | jmp .done |
1121 | jmp .done |
1081 | 1122 | ||
1082 | .tcp: |
1123 | .tcp: |
1083 | mov bx, [last_TCP_port] |
1124 | mov bx, [last_TCP_port] |
1084 | call .findit |
1125 | call .findit |
1085 | mov [last_TCP_port], bx |
1126 | mov [last_TCP_port], bx |
1086 | jmp .done |
1127 | jmp .done |
1087 | 1128 | ||
1088 | 1129 | ||
1089 | .restart: |
1130 | .restart: |
1090 | mov bx, MIN_EPHEMERAL_PORT |
1131 | mov bx, MIN_EPHEMERAL_PORT |
1091 | .findit: |
1132 | .findit: |
1092 | inc bx |
1133 | inc bx |
1093 | 1134 | ||
1094 | cmp bx, MAX_EPHEMERAL_PORT |
1135 | cmp bx, MAX_EPHEMERAL_PORT |
1095 | jz .restart |
1136 | jz .restart |
1096 | 1137 | ||
1097 | call SOCKET_check_port |
1138 | call SOCKET_check_port |
1098 | jz .findit |
1139 | jz .findit |
1099 | 1140 | ||
1100 | ret |
1141 | ret |
1101 | 1142 | ||
1102 | 1143 | ||
1103 | 1144 | ||
1104 | ;----------------------------------------------------------------- |
1145 | ;----------------------------------------------------------------- |
1105 | ; |
1146 | ; |
1106 | ; SOCKET_check_port (to be used with AF_INET only!) |
1147 | ; SOCKET_check_port (to be used with AF_INET only!) |
1107 | ; |
1148 | ; |
1108 | ; Checks if a local port number is unused |
1149 | ; Checks if a local port number is unused |
1109 | ; If the proposed port number is unused, it is filled in in the socket structure |
1150 | ; If the proposed port number is unused, it is filled in in the socket structure |
1110 | ; |
1151 | ; |
1111 | ; IN: eax = socket ptr (to find out if its a TCP/UDP socket) |
1152 | ; IN: eax = socket ptr (to find out if its a TCP/UDP socket) |
1112 | ; bx = proposed socket number |
1153 | ; bx = proposed socket number |
1113 | ; |
1154 | ; |
1114 | ; OUT: ZF = cleared on error |
1155 | ; OUT: ZF = cleared on error |
1115 | ; |
1156 | ; |
1116 | ;----------------------------------------------------------------- |
1157 | ;----------------------------------------------------------------- |
1117 | align 4 |
1158 | align 4 |
1118 | SOCKET_check_port: |
1159 | SOCKET_check_port: |
1119 | 1160 | ||
1120 | DEBUGF 1,"SOCKET_check_port: " |
1161 | DEBUGF 1,"SOCKET_check_port: " |
1121 | 1162 | ||
1122 | mov ecx, [eax + SOCKET.Protocol] |
1163 | mov ecx, [eax + SOCKET.Protocol] |
1123 | mov edx, [eax + IP_SOCKET.LocalIP] |
1164 | mov edx, [eax + IP_SOCKET.LocalIP] |
1124 | mov esi, net_sockets |
1165 | mov esi, net_sockets |
1125 | 1166 | ||
1126 | .next_socket: |
1167 | .next_socket: |
1127 | mov esi, [esi + SOCKET.NextPtr] |
1168 | mov esi, [esi + SOCKET.NextPtr] |
1128 | or esi, esi |
1169 | or esi, esi |
1129 | jz .port_ok |
1170 | jz .port_ok |
1130 | 1171 | ||
1131 | cmp [esi + SOCKET.Protocol], ecx |
1172 | cmp [esi + SOCKET.Protocol], ecx |
1132 | jne .next_socket |
1173 | jne .next_socket |
1133 | 1174 | ||
1134 | cmp [esi + IP_SOCKET.LocalIP], edx |
1175 | cmp [esi + IP_SOCKET.LocalIP], edx |
1135 | jne .next_socket |
1176 | jne .next_socket |
1136 | 1177 | ||
1137 | cmp [esi + UDP_SOCKET.LocalPort], bx |
1178 | cmp [esi + UDP_SOCKET.LocalPort], bx |
1138 | jne .next_socket |
1179 | jne .next_socket |
1139 | 1180 | ||
1140 | DEBUGF 1,"local port %u already in use\n", bx |
1181 | DEBUGF 1,"local port %u already in use\n", bx |
1141 | ret |
1182 | ret |
1142 | 1183 | ||
1143 | .port_ok: |
1184 | .port_ok: |
1144 | DEBUGF 1,"local port %u is free\n", bx |
1185 | DEBUGF 1,"local port %u is free\n", bx |
1145 | mov [eax + UDP_SOCKET.LocalPort], bx |
1186 | mov [eax + UDP_SOCKET.LocalPort], bx |
1146 | or bx, bx ; set the zero-flag |
1187 | or bx, bx ; set the zero-flag |
1147 | 1188 | ||
1148 | ret |
1189 | ret |
1149 | 1190 | ||
1150 | 1191 | ||
1151 | 1192 | ||
1152 | ;----------------------------------------------------------------- |
1193 | ;----------------------------------------------------------------- |
1153 | ; |
1194 | ; |
1154 | ; SOCKET_input |
1195 | ; SOCKET_input |
1155 | ; |
1196 | ; |
1156 | ; Updates a (stateless) socket with received data |
1197 | ; Updates a (stateless) socket with received data |
1157 | ; |
1198 | ; |
1158 | ; Note: the mutex should already be set ! |
1199 | ; Note: the mutex should already be set ! |
1159 | ; |
1200 | ; |
1160 | ; IN: eax = socket ptr |
1201 | ; IN: eax = socket ptr |
1161 | ; ecx = data size |
1202 | ; ecx = data size |
1162 | ; esi = ptr to data |
1203 | ; esi = ptr to data |
1163 | ; [esp] = ptr to buf |
1204 | ; [esp] = ptr to buf |
1164 | ; [esp + 4] = buf size |
1205 | ; [esp + 4] = buf size |
1165 | ; |
1206 | ; |
1166 | ; OUT: / |
1207 | ; OUT: / |
1167 | ; |
1208 | ; |
1168 | ;----------------------------------------------------------------- |
1209 | ;----------------------------------------------------------------- |
1169 | align 4 |
1210 | align 4 |
1170 | SOCKET_input: |
1211 | SOCKET_input: |
1171 | 1212 | ||
1172 | DEBUGF 1,"SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx |
1213 | DEBUGF 1,"SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx |
1173 | 1214 | ||
1174 | mov [esp+4], ecx |
1215 | mov [esp+4], ecx |
1175 | push esi |
1216 | push esi |
1176 | mov esi, esp |
1217 | mov esi, esp |
1177 | 1218 | ||
1178 | add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full |
1219 | add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full |
1179 | 1220 | ||
1180 | DEBUGF 1,"SOCKET_input: queued packet successfully\n" |
1221 | DEBUGF 1,"SOCKET_input: queued packet successfully\n" |
1181 | add esp, sizeof.socket_queue_entry |
1222 | add esp, sizeof.socket_queue_entry |
1182 | 1223 | ||
1183 | pusha |
1224 | pusha |
1184 | lea ecx, [eax + SOCKET.mutex] |
1225 | lea ecx, [eax + SOCKET.mutex] |
1185 | call mutex_unlock |
1226 | call mutex_unlock |
1186 | popa |
1227 | popa |
1187 | 1228 | ||
1188 | jmp SOCKET_notify_owner |
1229 | jmp SOCKET_notify_owner |
1189 | 1230 | ||
1190 | .full: |
1231 | .full: |
1191 | DEBUGF 2,"SOCKET_input: socket %x is full!\n", eax |
1232 | DEBUGF 2,"SOCKET_input: socket %x is full!\n", eax |
1192 | 1233 | ||
1193 | pusha |
1234 | pusha |
1194 | lea ecx, [eax + SOCKET.mutex] |
1235 | lea ecx, [eax + SOCKET.mutex] |
1195 | call mutex_unlock |
1236 | call mutex_unlock |
1196 | popa |
1237 | popa |
1197 | 1238 | ||
1198 | call kernel_free |
1239 | call kernel_free |
1199 | add esp, 8 |
1240 | add esp, 8 |
1200 | 1241 | ||
1201 | ret |
1242 | ret |
1202 | 1243 | ||
1203 | 1244 | ||
1204 | ;-------------------------- |
1245 | ;-------------------------- |
1205 | ; |
1246 | ; |
1206 | ; eax = ptr to ring struct (just a buffer of the right size) |
1247 | ; eax = ptr to ring struct (just a buffer of the right size) |
1207 | ; |
1248 | ; |
1208 | align 4 |
1249 | align 4 |
1209 | SOCKET_ring_create: |
1250 | SOCKET_ring_create: |
1210 | 1251 | ||
1211 | push esi |
1252 | push esi |
1212 | mov esi, eax |
1253 | mov esi, eax |
1213 | 1254 | ||
1214 | push edx |
1255 | push edx |
1215 | stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW |
1256 | stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW |
1216 | pop edx |
1257 | pop edx |
1217 | 1258 | ||
1218 | DEBUGF 1,"SOCKET_ring_created: %x\n", eax |
1259 | DEBUGF 1,"SOCKET_ring_created: %x\n", eax |
1219 | mov [esi + RING_BUFFER.start_ptr], eax |
1260 | mov [esi + RING_BUFFER.start_ptr], eax |
1220 | mov [esi + RING_BUFFER.write_ptr], eax |
1261 | mov [esi + RING_BUFFER.write_ptr], eax |
1221 | mov [esi + RING_BUFFER.read_ptr], eax |
1262 | mov [esi + RING_BUFFER.read_ptr], eax |
1222 | mov [esi + RING_BUFFER.size], 0 |
1263 | mov [esi + RING_BUFFER.size], 0 |
1223 | add eax, SOCKET_MAXDATA |
1264 | add eax, SOCKET_MAXDATA |
1224 | mov [esi + RING_BUFFER.end_ptr], eax |
1265 | mov [esi + RING_BUFFER.end_ptr], eax |
1225 | mov eax, esi |
1266 | mov eax, esi |
1226 | pop esi |
1267 | pop esi |
1227 | 1268 | ||
1228 | ret |
1269 | ret |
1229 | 1270 | ||
1230 | ;----------------------------------------------------------------- |
1271 | ;----------------------------------------------------------------- |
1231 | ; |
1272 | ; |
1232 | ; SOCKET_ring_write |
1273 | ; SOCKET_ring_write |
1233 | ; |
1274 | ; |
1234 | ; Adds data to a stream socket, and updates write pointer and size |
1275 | ; Adds data to a stream socket, and updates write pointer and size |
1235 | ; |
1276 | ; |
1236 | ; IN: eax = ptr to ring struct |
1277 | ; IN: eax = ptr to ring struct |
1237 | ; ecx = data size |
1278 | ; ecx = data size |
1238 | ; esi = ptr to data |
1279 | ; esi = ptr to data |
1239 | ; |
1280 | ; |
1240 | ; OUT: ecx = number of bytes stored |
1281 | ; OUT: ecx = number of bytes stored |
1241 | ; |
1282 | ; |
1242 | ;----------------------------------------------------------------- |
1283 | ;----------------------------------------------------------------- |
1243 | align 4 |
1284 | align 4 |
1244 | SOCKET_ring_write: |
1285 | SOCKET_ring_write: |
1245 | 1286 | ||
1246 | DEBUGF 1,"SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx |
1287 | DEBUGF 1,"SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx |
1247 | 1288 | ||
1248 | add [eax + RING_BUFFER.size], ecx |
1289 | add [eax + RING_BUFFER.size], ecx |
1249 | jc .way_too_large |
1290 | jc .way_too_large |
1250 | cmp [eax + RING_BUFFER.size], SOCKET_MAXDATA |
1291 | cmp [eax + RING_BUFFER.size], SOCKET_MAXDATA |
1251 | ja .too_large |
1292 | ja .too_large |
1252 | 1293 | ||
1253 | .copy: |
1294 | .copy: |
1254 | mov edi, [eax + RING_BUFFER.write_ptr] |
1295 | mov edi, [eax + RING_BUFFER.write_ptr] |
1255 | DEBUGF 2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi |
1296 | DEBUGF 2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi |
1256 | 1297 | ||
1257 | push ecx |
1298 | push ecx |
1258 | shr ecx, 1 |
1299 | shr ecx, 1 |
1259 | jnc .nb |
1300 | jnc .nb |
1260 | movsb |
1301 | movsb |
1261 | .nb: |
1302 | .nb: |
1262 | shr ecx, 1 |
1303 | shr ecx, 1 |
1263 | jnc .nw |
1304 | jnc .nw |
1264 | movsw |
1305 | movsw |
1265 | .nw: |
1306 | .nw: |
1266 | test ecx, ecx |
1307 | test ecx, ecx |
1267 | jz .nd |
1308 | jz .nd |
1268 | rep movsd |
1309 | rep movsd |
1269 | .nd: |
1310 | .nd: |
1270 | pop ecx |
1311 | pop ecx |
1271 | 1312 | ||
1272 | cmp edi, [eax + RING_BUFFER.end_ptr] |
1313 | cmp edi, [eax + RING_BUFFER.end_ptr] |
1273 | jae .wrap |
1314 | jae .wrap |
1274 | mov [eax + RING_BUFFER.write_ptr], edi |
1315 | mov [eax + RING_BUFFER.write_ptr], edi |
1275 | 1316 | ||
1276 | ret |
1317 | ret |
1277 | 1318 | ||
1278 | .wrap: |
1319 | .wrap: |
1279 | sub edi, SOCKET_MAXDATA |
1320 | sub edi, SOCKET_MAXDATA |
1280 | mov [eax + RING_BUFFER.write_ptr], edi |
1321 | mov [eax + RING_BUFFER.write_ptr], edi |
1281 | 1322 | ||
1282 | ret |
1323 | ret |
1283 | 1324 | ||
1284 | .too_large: ; update size, we will fill buffer completely |
1325 | .too_large: ; update size, we will fill buffer completely |
1285 | sub [eax + RING_BUFFER.size], SOCKET_MAXDATA |
1326 | sub [eax + RING_BUFFER.size], SOCKET_MAXDATA |
1286 | sub ecx, [eax + RING_BUFFER.size] |
1327 | sub ecx, [eax + RING_BUFFER.size] |
1287 | mov [eax + RING_BUFFER.size], SOCKET_MAXDATA |
1328 | mov [eax + RING_BUFFER.size], SOCKET_MAXDATA |
1288 | ja .copy |
1329 | ja .copy |
1289 | 1330 | ||
1290 | .full: |
1331 | .full: |
1291 | DEBUGF 2,"SOCKET_ring_write: ring buffer is full!\n" |
1332 | DEBUGF 2,"SOCKET_ring_write: ring buffer is full!\n" |
1292 | xor ecx, ecx |
1333 | xor ecx, ecx |
1293 | ret |
1334 | ret |
1294 | 1335 | ||
1295 | .way_too_large: |
1336 | .way_too_large: |
1296 | sub [eax + RING_BUFFER.size], ecx |
1337 | sub [eax + RING_BUFFER.size], ecx |
1297 | mov ecx, SOCKET_MAXDATA |
1338 | mov ecx, SOCKET_MAXDATA |
1298 | sub ecx, [eax + RING_BUFFER.size] |
1339 | sub ecx, [eax + RING_BUFFER.size] |
1299 | ja .copy |
1340 | ja .copy |
1300 | jmp .full |
1341 | jmp .full |
1301 | 1342 | ||
1302 | 1343 | ||
1303 | 1344 | ||
1304 | ;----------------------------------------------------------------- |
1345 | ;----------------------------------------------------------------- |
1305 | ; |
1346 | ; |
1306 | ; SOCKET_ring_read |
1347 | ; SOCKET_ring_read |
1307 | ; |
1348 | ; |
1308 | ; IN: eax = ring struct ptr |
1349 | ; IN: eax = ring struct ptr |
1309 | ; ecx = bytes to read |
1350 | ; ecx = bytes to read |
1310 | ; edx = offset |
1351 | ; edx = offset |
1311 | ; edi = ptr to buffer |
1352 | ; edi = ptr to buffer start |
1312 | ; |
1353 | ; |
- | 1354 | ; OUT: eax = unchanged |
|
1313 | ; OUT: ecx = number of bytes read (0 on error) |
1355 | ; ecx = number of bytes read (0 on error) |
- | 1356 | ; edx = destroyed |
|
- | 1357 | ; esi = destroyed |
|
- | 1358 | ; edi = ptr to buffer end |
|
1314 | ; |
1359 | ; |
1315 | ;----------------------------------------------------------------- |
1360 | ;----------------------------------------------------------------- |
1316 | align 4 |
1361 | align 4 |
1317 | SOCKET_ring_read: |
1362 | SOCKET_ring_read: |
1318 | 1363 | ||
1319 | DEBUGF 1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u offset=%x\n", eax, edi, ecx, edx |
1364 | DEBUGF 1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u offset=%x\n", eax, edi, ecx, edx |
1320 | 1365 | ||
1321 | mov esi, [eax + RING_BUFFER.read_ptr] |
1366 | mov esi, [eax + RING_BUFFER.read_ptr] |
1322 | add esi, edx ; esi = start_ptr + offset |
1367 | add esi, edx ; esi = start_ptr + offset |
1323 | 1368 | ||
1324 | neg edx |
1369 | neg edx |
1325 | add edx, [eax + RING_BUFFER.size] ; edx = snd.size - offset |
1370 | add edx, [eax + RING_BUFFER.size] ; edx = snd.size - offset |
1326 | jle .no_data_at_all |
1371 | jle .no_data_at_all |
1327 | 1372 | ||
1328 | cmp ecx, edx |
1373 | cmp ecx, edx |
1329 | ja .less_data |
1374 | ja .less_data |
1330 | 1375 | ||
1331 | .copy: |
1376 | .copy: |
1332 | DEBUGF 2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi |
1377 | DEBUGF 2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi |
1333 | push ecx |
1378 | push ecx |
1334 | shr ecx, 1 |
1379 | shr ecx, 1 |
1335 | jnc .nb |
1380 | jnc .nb |
1336 | movsb |
1381 | movsb |
1337 | .nb: |
1382 | .nb: |
1338 | shr ecx, 1 |
1383 | shr ecx, 1 |
1339 | jnc .nw |
1384 | jnc .nw |
1340 | movsw |
1385 | movsw |
1341 | .nw: |
1386 | .nw: |
1342 | test ecx, ecx |
1387 | test ecx, ecx |
1343 | jz .nd |
1388 | jz .nd |
1344 | rep movsd |
1389 | rep movsd |
1345 | .nd: |
1390 | .nd: |
1346 | pop ecx |
1391 | pop ecx |
1347 | ret |
1392 | ret |
1348 | 1393 | ||
1349 | .no_data_at_all: |
1394 | .no_data_at_all: |
1350 | DEBUGF 1,"SOCKET_ring_read: no data at all!\n" |
1395 | DEBUGF 1,"SOCKET_ring_read: no data at all!\n" |
1351 | xor ecx, ecx |
1396 | xor ecx, ecx |
1352 | ret |
1397 | ret |
1353 | 1398 | ||
1354 | .less_data: |
1399 | .less_data: |
1355 | mov ecx, edx |
1400 | mov ecx, edx |
1356 | jmp .copy |
1401 | jmp .copy |
1357 | 1402 | ||
1358 | 1403 | ||
1359 | ;----------------------------------------------------------------- |
1404 | ;----------------------------------------------------------------- |
1360 | ; |
1405 | ; |
1361 | ; SOCKET_ring_free |
1406 | ; SOCKET_ring_free |
1362 | ; |
1407 | ; |
1363 | ; Free's some bytes from the ringbuffer |
1408 | ; Free's some bytes from the ringbuffer |
1364 | ; |
1409 | ; |
1365 | ; IN: eax = ptr to ring struct |
1410 | ; IN: eax = ptr to ring struct |
1366 | ; ecx = data size |
1411 | ; ecx = data size |
1367 | ; |
1412 | ; |
1368 | ; OUT: ecx = number of bytes free-ed |
1413 | ; OUT: ecx = number of bytes free-ed |
1369 | ; |
1414 | ; |
1370 | ;----------------------------------------------------------------- |
1415 | ;----------------------------------------------------------------- |
1371 | align 4 |
1416 | align 4 |
1372 | SOCKET_ring_free: |
1417 | SOCKET_ring_free: |
1373 | 1418 | ||
1374 | DEBUGF 1,"SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax |
1419 | DEBUGF 1,"SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax |
1375 | 1420 | ||
1376 | sub [eax + RING_BUFFER.size], ecx |
1421 | sub [eax + RING_BUFFER.size], ecx |
1377 | jb .error |
1422 | jb .error |
1378 | add [eax + RING_BUFFER.read_ptr], ecx |
1423 | add [eax + RING_BUFFER.read_ptr], ecx |
1379 | 1424 | ||
1380 | mov edx, [eax + RING_BUFFER.end_ptr] |
1425 | mov edx, [eax + RING_BUFFER.end_ptr] |
1381 | cmp [eax + RING_BUFFER.read_ptr], edx |
1426 | cmp [eax + RING_BUFFER.read_ptr], edx |
1382 | jb @f |
1427 | jb @f |
1383 | sub [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA |
1428 | sub [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA |
1384 | @@: |
1429 | @@: |
1385 | ret |
1430 | ret |
1386 | 1431 | ||
1387 | .error: ; we could free all available bytes, but that would be stupid, i guess.. |
1432 | .error: ; we could free all available bytes, but that would be stupid, i guess.. |
1388 | DEBUGF 1,"SOCKET_ring_free: buffer=%x error!\n", eax |
1433 | DEBUGF 1,"SOCKET_ring_free: buffer=%x error!\n", eax |
1389 | add [eax + RING_BUFFER.size], ecx |
1434 | add [eax + RING_BUFFER.size], ecx |
1390 | xor ecx, ecx |
1435 | xor ecx, ecx |
1391 | ret |
1436 | ret |
1392 | 1437 | ||
1393 | 1438 | ||
1394 | ;----------------------------------------------------------------- |
1439 | ;----------------------------------------------------------------- |
1395 | ; |
1440 | ; |
1396 | ; SOCKET_notify_owner |
1441 | ; SOCKET_notify_owner |
1397 | ; |
1442 | ; |
1398 | ; notify's the owner of a socket that something happened |
1443 | ; notify's the owner of a socket that something happened |
1399 | ; |
1444 | ; |
1400 | ; IN: eax = socket ptr |
1445 | ; IN: eax = socket ptr |
1401 | ; OUT: / |
1446 | ; OUT: / |
1402 | ; |
1447 | ; |
1403 | ;----------------------------------------------------------------- |
1448 | ;----------------------------------------------------------------- |
1404 | align 4 |
1449 | align 4 |
1405 | SOCKET_notify_owner: |
1450 | SOCKET_notify_owner: |
1406 | 1451 | ||
1407 | DEBUGF 1,"SOCKET_notify_owner: %x\n", eax |
1452 | DEBUGF 1,"SOCKET_notify_owner: %x\n", eax |
1408 | 1453 | ||
1409 | call SOCKET_check |
1454 | call SOCKET_check |
1410 | jz .error |
1455 | jz .error |
1411 | 1456 | ||
1412 | push eax ecx esi |
1457 | push eax ecx esi |
1413 | 1458 | ||
1414 | ; socket exists, now try to flag an event to the application |
1459 | ; socket exists, now try to flag an event to the application |
1415 | 1460 | ||
1416 | mov eax, [eax + SOCKET.PID] |
1461 | mov eax, [eax + SOCKET.PID] |
1417 | test eax, eax |
1462 | test eax, eax |
1418 | jz .error2 |
1463 | jz .error2 |
1419 | mov ecx, 1 |
1464 | mov ecx, 1 |
1420 | mov esi, TASK_DATA + TASKDATA.pid |
1465 | mov esi, TASK_DATA + TASKDATA.pid |
1421 | 1466 | ||
1422 | .next_pid: |
1467 | .next_pid: |
1423 | cmp [esi], eax |
1468 | cmp [esi], eax |
1424 | je .found_pid |
1469 | je .found_pid |
1425 | inc ecx |
1470 | inc ecx |
1426 | add esi, 0x20 |
1471 | add esi, 0x20 |
1427 | cmp ecx, [TASK_COUNT] |
1472 | cmp ecx, [TASK_COUNT] |
1428 | jbe .next_pid |
1473 | jbe .next_pid |
1429 | 1474 | ||
1430 | ; PID not found, TODO: close socket! |
1475 | ; PID not found, TODO: close socket! |
1431 | 1476 | ||
1432 | jmp .error2 |
1477 | jmp .error2 |
1433 | 1478 | ||
1434 | .found_pid: |
1479 | .found_pid: |
1435 | shl ecx, 8 |
1480 | shl ecx, 8 |
1436 | or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK |
1481 | or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK |
1437 | mov [check_idle_semaphore], 200 |
1482 | mov [check_idle_semaphore], 200 |
1438 | 1483 | ||
1439 | DEBUGF 1,"SOCKET_notify_owner: succes!\n" |
1484 | DEBUGF 1,"SOCKET_notify_owner: succes!\n" |
1440 | 1485 | ||
1441 | .error2: |
1486 | .error2: |
1442 | pop esi ecx eax |
1487 | pop esi ecx eax |
1443 | 1488 | ||
1444 | .error: |
1489 | .error: |
1445 | 1490 | ||
1446 | ret |
1491 | ret |
1447 | 1492 | ||
1448 | 1493 | ||
1449 | ;-------------------------------------------------------------------- |
1494 | ;-------------------------------------------------------------------- |
1450 | ; |
1495 | ; |
1451 | ; SOCKET_alloc |
1496 | ; SOCKET_alloc |
1452 | ; |
1497 | ; |
1453 | ; Allocate memory for socket data and put new socket into the list |
1498 | ; Allocate memory for socket data and put new socket into the list |
1454 | ; Newly created socket is initialized with calling PID and number and |
1499 | ; Newly created socket is initialized with calling PID and number and |
1455 | ; put into beginning of list (which is a fastest way). |
1500 | ; put into beginning of list (which is a fastest way). |
1456 | ; |
1501 | ; |
1457 | ; IN: / |
1502 | ; IN: / |
1458 | ; OUT: eax = 0 on error, socket ptr otherwise |
1503 | ; OUT: eax = 0 on error, socket ptr otherwise |
1459 | ; edi = socket number |
1504 | ; edi = socket number |
1460 | ; ZF = cleared on error |
1505 | ; ZF = cleared on error |
1461 | ; |
1506 | ; |
1462 | ;-------------------------------------------------------------------- |
1507 | ;-------------------------------------------------------------------- |
1463 | align 4 |
1508 | align 4 |
1464 | SOCKET_alloc: |
1509 | SOCKET_alloc: |
1465 | 1510 | ||
1466 | push ebx |
1511 | push ebx |
1467 | 1512 | ||
1468 | stdcall kernel_alloc, SOCKETBUFFSIZE |
1513 | stdcall kernel_alloc, SOCKETBUFFSIZE |
1469 | DEBUGF 1, "SOCKET_alloc: ptr=%x\n", eax |
1514 | DEBUGF 1, "SOCKET_alloc: ptr=%x\n", eax |
1470 | or eax, eax |
1515 | or eax, eax |
1471 | jz .exit |
1516 | jz .exit |
1472 | 1517 | ||
1473 | ; zero-initialize allocated memory |
1518 | ; zero-initialize allocated memory |
1474 | push eax |
1519 | push eax |
1475 | mov edi, eax |
1520 | mov edi, eax |
1476 | mov ecx, SOCKETBUFFSIZE / 4 |
1521 | mov ecx, SOCKETBUFFSIZE / 4 |
1477 | xor eax, eax |
1522 | xor eax, eax |
1478 | rep stosd |
1523 | rep stosd |
1479 | pop eax |
1524 | pop eax |
1480 | 1525 | ||
1481 | ; set send-and receive procedures to return -1 |
1526 | ; set send-and receive procedures to return -1 |
1482 | mov [eax + SOCKET.snd_proc], s_error |
1527 | mov [eax + SOCKET.snd_proc], s_error |
1483 | mov [eax + SOCKET.rcv_proc], s_error |
1528 | mov [eax + SOCKET.rcv_proc], s_error |
1484 | 1529 | ||
1485 | ; find first free socket number and use it |
1530 | ; find first free socket number and use it |
1486 | mov edi, [last_socket_num] |
1531 | mov edi, [last_socket_num] |
1487 | .next_socket_number: |
1532 | .next_socket_number: |
1488 | inc edi |
1533 | inc edi |
1489 | jz .next_socket_number ; avoid socket nr 0 |
1534 | jz .next_socket_number ; avoid socket nr 0 |
1490 | cmp edi, -1 |
1535 | cmp edi, -1 |
1491 | je .next_socket_number ; avoid socket nr -1 |
1536 | je .next_socket_number ; avoid socket nr -1 |
1492 | mov ebx, net_sockets |
1537 | mov ebx, net_sockets |
1493 | .next_socket: |
1538 | .next_socket: |
1494 | mov ebx, [ebx + SOCKET.NextPtr] |
1539 | mov ebx, [ebx + SOCKET.NextPtr] |
1495 | test ebx, ebx |
1540 | test ebx, ebx |
1496 | jz .last_socket |
1541 | jz .last_socket |
1497 | 1542 | ||
1498 | cmp [ebx + SOCKET.Number], edi |
1543 | cmp [ebx + SOCKET.Number], edi |
1499 | jne .next_socket |
1544 | jne .next_socket |
1500 | jmp .next_socket_number |
1545 | jmp .next_socket_number |
1501 | 1546 | ||
1502 | .last_socket: |
1547 | .last_socket: |
1503 | mov [last_socket_num], edi |
1548 | mov [last_socket_num], edi |
1504 | mov [eax + SOCKET.Number], edi |
1549 | mov [eax + SOCKET.Number], edi |
1505 | DEBUGF 1, "SOCKET_alloc: number=%u\n", edi |
1550 | DEBUGF 1, "SOCKET_alloc: number=%u\n", edi |
1506 | 1551 | ||
1507 | ; Fill in PID |
1552 | ; Fill in PID |
1508 | mov ebx, [TASK_BASE] |
1553 | mov ebx, [TASK_BASE] |
1509 | mov ebx, [ebx + TASKDATA.pid] |
1554 | mov ebx, [ebx + TASKDATA.pid] |
1510 | mov [eax + SOCKET.PID], ebx |
1555 | mov [eax + SOCKET.PID], ebx |
1511 | 1556 | ||
1512 | ; init mutex |
1557 | ; init mutex |
1513 | pusha |
1558 | pusha |
1514 | lea ecx, [eax + SOCKET.mutex] |
1559 | lea ecx, [eax + SOCKET.mutex] |
1515 | call mutex_init |
1560 | call mutex_init |
1516 | popa |
1561 | popa |
1517 | 1562 | ||
1518 | ; add socket to the list by re-arranging some pointers |
1563 | ; add socket to the list by re-arranging some pointers |
1519 | mov ebx, [net_sockets + SOCKET.NextPtr] |
1564 | mov ebx, [net_sockets + SOCKET.NextPtr] |
1520 | 1565 | ||
1521 | mov [eax + SOCKET.PrevPtr], net_sockets |
1566 | mov [eax + SOCKET.PrevPtr], net_sockets |
1522 | mov [eax + SOCKET.NextPtr], ebx |
1567 | mov [eax + SOCKET.NextPtr], ebx |
1523 | 1568 | ||
1524 | test ebx, ebx |
1569 | test ebx, ebx |
1525 | jz @f |
1570 | jz @f |
1526 | 1571 | ||
1527 | pusha |
1572 | pusha |
1528 | lea ecx, [ebx + SOCKET.mutex] |
1573 | lea ecx, [ebx + SOCKET.mutex] |
1529 | call mutex_lock |
1574 | call mutex_lock |
1530 | popa |
1575 | popa |
1531 | 1576 | ||
1532 | mov [ebx + SOCKET.PrevPtr], eax |
1577 | mov [ebx + SOCKET.PrevPtr], eax |
1533 | 1578 | ||
1534 | pusha |
1579 | pusha |
1535 | lea ecx, [ebx + SOCKET.mutex] |
1580 | lea ecx, [ebx + SOCKET.mutex] |
1536 | call mutex_unlock |
1581 | call mutex_unlock |
1537 | popa |
1582 | popa |
1538 | @@: |
1583 | @@: |
1539 | 1584 | ||
1540 | mov [net_sockets + SOCKET.NextPtr], eax |
1585 | mov [net_sockets + SOCKET.NextPtr], eax |
1541 | or eax, eax ; used to clear zero flag |
1586 | or eax, eax ; used to clear zero flag |
1542 | .exit: |
1587 | .exit: |
1543 | pop ebx |
1588 | pop ebx |
1544 | 1589 | ||
1545 | ret |
1590 | ret |
1546 | 1591 | ||
1547 | 1592 | ||
1548 | ;---------------------------------------------------- |
1593 | ;---------------------------------------------------- |
1549 | ; |
1594 | ; |
1550 | ; SOCKET_free |
1595 | ; SOCKET_free |
1551 | ; |
1596 | ; |
1552 | ; Free socket data memory and remove socket from the list |
1597 | ; Free socket data memory and remove socket from the list |
1553 | ; |
1598 | ; |
1554 | ; IN: eax = socket ptr |
1599 | ; IN: eax = socket ptr |
1555 | ; OUT: / |
1600 | ; OUT: / |
1556 | ; |
1601 | ; |
1557 | ;---------------------------------------------------- |
1602 | ;---------------------------------------------------- |
1558 | align 4 |
1603 | align 4 |
1559 | SOCKET_free: |
1604 | SOCKET_free: |
1560 | 1605 | ||
1561 | DEBUGF 1, "SOCKET_free: %x\n", eax |
1606 | DEBUGF 1, "SOCKET_free: %x\n", eax |
1562 | 1607 | ||
1563 | call SOCKET_check |
1608 | call SOCKET_check |
1564 | jz .error |
1609 | jz .error |
1565 | 1610 | ||
1566 | push ebx |
1611 | push ebx |
1567 | 1612 | ||
1568 | pusha |
1613 | pusha |
1569 | lea ecx, [eax + SOCKET.mutex] |
1614 | lea ecx, [eax + SOCKET.mutex] |
1570 | call mutex_lock |
1615 | call mutex_lock |
1571 | popa |
1616 | popa |
1572 | 1617 | ||
1573 | cmp [eax + SOCKET.Domain], AF_INET4 |
1618 | cmp [eax + SOCKET.Domain], AF_INET4 |
1574 | jnz .no_tcp |
1619 | jnz .no_tcp |
1575 | 1620 | ||
1576 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
1621 | cmp [eax + SOCKET.Protocol], IP_PROTO_TCP |
1577 | jnz .no_tcp |
1622 | jnz .no_tcp |
1578 | 1623 | ||
1579 | mov ebx, eax |
1624 | mov ebx, eax |
1580 | stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr] |
1625 | stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr] |
1581 | stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr] |
1626 | stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr] |
1582 | mov eax, ebx |
1627 | mov eax, ebx |
1583 | .no_tcp: |
1628 | .no_tcp: |
1584 | 1629 | ||
1585 | push eax ; this will be passed to kernel_free |
1630 | push eax ; this will be passed to kernel_free |
1586 | mov ebx, [eax + SOCKET.NextPtr] |
1631 | mov ebx, [eax + SOCKET.NextPtr] |
1587 | mov eax, [eax + SOCKET.PrevPtr] |
1632 | mov eax, [eax + SOCKET.PrevPtr] |
1588 | 1633 | ||
1589 | DEBUGF 1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx |
1634 | DEBUGF 1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx |
1590 | 1635 | ||
1591 | test eax, eax |
1636 | test eax, eax |
1592 | jz @f |
1637 | jz @f |
1593 | mov [eax + SOCKET.NextPtr], ebx |
1638 | mov [eax + SOCKET.NextPtr], ebx |
1594 | @@: |
1639 | @@: |
1595 | 1640 | ||
1596 | test ebx, ebx |
1641 | test ebx, ebx |
1597 | jz @f |
1642 | jz @f |
1598 | mov [ebx + SOCKET.PrevPtr], eax |
1643 | mov [ebx + SOCKET.PrevPtr], eax |
1599 | @@: |
1644 | @@: |
1600 | 1645 | ||
1601 | call kernel_free |
1646 | call kernel_free |
1602 | pop ebx |
1647 | pop ebx |
1603 | 1648 | ||
1604 | DEBUGF 1, "SOCKET_free: success!\n" |
1649 | DEBUGF 1, "SOCKET_free: success!\n" |
1605 | 1650 | ||
1606 | .error: |
1651 | .error: |
1607 | ret |
1652 | ret |
1608 | 1653 | ||
1609 | ;------------------------------------ |
1654 | ;------------------------------------ |
1610 | ; |
1655 | ; |
1611 | ; SOCKET_fork |
1656 | ; SOCKET_fork |
1612 | ; |
1657 | ; |
1613 | ; Create a child socket |
1658 | ; Create a child socket |
1614 | ; |
1659 | ; |
1615 | ; IN: socket nr in ebx |
1660 | ; IN: socket nr in ebx |
1616 | ; OUT: child socket nr in eax |
1661 | ; OUT: child socket nr in eax |
1617 | ; |
1662 | ; |
1618 | ;----------------------------------- |
1663 | ;----------------------------------- |
1619 | align 4 |
1664 | align 4 |
1620 | SOCKET_fork: |
1665 | SOCKET_fork: |
1621 | 1666 | ||
1622 | DEBUGF 1,"SOCKET_fork: %x\n", ebx |
1667 | DEBUGF 1,"SOCKET_fork: %x\n", ebx |
1623 | 1668 | ||
1624 | ; Exit if backlog queue is full |
1669 | ; Exit if backlog queue is full |
1625 | mov eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size] |
1670 | mov eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size] |
1626 | cmp ax, [ebx + SOCKET.backlog] |
1671 | cmp ax, [ebx + SOCKET.backlog] |
1627 | jae .fail |
1672 | jae .fail |
1628 | 1673 | ||
1629 | ; Allocate new socket |
1674 | ; Allocate new socket |
1630 | push ebx |
1675 | push ebx |
1631 | call SOCKET_alloc |
1676 | call SOCKET_alloc |
1632 | pop ebx |
1677 | pop ebx |
1633 | jz .fail |
1678 | jz .fail |
1634 | 1679 | ||
1635 | push eax |
1680 | push eax |
1636 | mov esi, esp |
1681 | mov esi, esp |
1637 | add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2 |
1682 | add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2 |
1638 | pop eax |
1683 | pop eax |
1639 | 1684 | ||
1640 | ; Copy structure from current socket to new |
1685 | ; Copy structure from current socket to new |
1641 | ; We start at PID to preserve the socket num, and the 2 pointers at beginning of socket |
1686 | ; We start at PID to preserve the socket num, and the 2 pointers at beginning of socket |
1642 | lea esi, [ebx + SOCKET.PID] |
1687 | lea esi, [ebx + SOCKET.PID] |
1643 | lea edi, [eax + SOCKET.PID] |
1688 | lea edi, [eax + SOCKET.PID] |
1644 | mov ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4 |
1689 | mov ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4 |
1645 | rep movsd |
1690 | rep movsd |
1646 | 1691 | ||
1647 | and [eax + SOCKET.options], not SO_ACCEPTCON |
1692 | and [eax + SOCKET.options], not SO_ACCEPTCON |
1648 | 1693 | ||
1649 | ret |
1694 | ret |
1650 | 1695 | ||
1651 | .fail2: |
1696 | .fail2: |
1652 | add esp, 4+4+4 |
1697 | add esp, 4+4+4 |
1653 | .fail: |
1698 | .fail: |
1654 | DEBUGF 1,"SOCKET_fork: failed\n" |
1699 | DEBUGF 1,"SOCKET_fork: failed\n" |
1655 | xor eax, eax |
1700 | xor eax, eax |
1656 | ret |
1701 | ret |
1657 | 1702 | ||
1658 | 1703 | ||
1659 | ;--------------------------------------------------- |
1704 | ;--------------------------------------------------- |
1660 | ; |
1705 | ; |
1661 | ; SOCKET_num_to_ptr |
1706 | ; SOCKET_num_to_ptr |
1662 | ; |
1707 | ; |
1663 | ; Get socket structure address by its number |
1708 | ; Get socket structure address by its number |
1664 | ; |
1709 | ; |
1665 | ; IN: ecx = socket number |
1710 | ; IN: ecx = socket number |
1666 | ; OUT: eax = 0 on error, socket ptr otherwise |
1711 | ; OUT: eax = 0 on error, socket ptr otherwise |
1667 | ; ZF = set on error |
1712 | ; ZF = set on error |
1668 | ; |
1713 | ; |
1669 | ;--------------------------------------------------- |
1714 | ;--------------------------------------------------- |
1670 | align 4 |
1715 | align 4 |
1671 | SOCKET_num_to_ptr: |
1716 | SOCKET_num_to_ptr: |
1672 | 1717 | ||
1673 | DEBUGF 1,"SOCKET_num_to_ptr: num=%u ", ecx |
1718 | DEBUGF 1,"SOCKET_num_to_ptr: num=%u ", ecx |
1674 | 1719 | ||
1675 | mov eax, net_sockets |
1720 | mov eax, net_sockets |
1676 | 1721 | ||
1677 | .next_socket: |
1722 | .next_socket: |
1678 | mov eax, [eax + SOCKET.NextPtr] |
1723 | mov eax, [eax + SOCKET.NextPtr] |
1679 | or eax, eax |
1724 | or eax, eax |
1680 | jz .error |
1725 | jz .error |
1681 | cmp [eax + SOCKET.Number], ecx |
1726 | cmp [eax + SOCKET.Number], ecx |
1682 | jne .next_socket |
1727 | jne .next_socket |
1683 | 1728 | ||
1684 | test eax, eax |
1729 | test eax, eax |
1685 | 1730 | ||
1686 | DEBUGF 1,"ptr=%x\n", eax |
1731 | DEBUGF 1,"ptr=%x\n", eax |
1687 | ret |
1732 | ret |
1688 | 1733 | ||
1689 | .error: |
1734 | .error: |
1690 | DEBUGF 1,"not found\n", eax |
1735 | DEBUGF 1,"not found\n", eax |
1691 | ret |
1736 | ret |
1692 | 1737 | ||
1693 | 1738 | ||
1694 | ;--------------------------------------------------- |
1739 | ;--------------------------------------------------- |
1695 | ; |
1740 | ; |
1696 | ; SOCKET_ptr_to_num |
1741 | ; SOCKET_ptr_to_num |
1697 | ; |
1742 | ; |
1698 | ; Get socket number by its address |
1743 | ; Get socket number by its address |
1699 | ; |
1744 | ; |
1700 | ; IN: eax = socket ptr |
1745 | ; IN: eax = socket ptr |
1701 | ; OUT: eax = 0 on error, socket num otherwise |
1746 | ; OUT: eax = 0 on error, socket num otherwise |
1702 | ; ZF = set on error |
1747 | ; ZF = set on error |
1703 | ; |
1748 | ; |
1704 | ;--------------------------------------------------- |
1749 | ;--------------------------------------------------- |
1705 | align 4 |
1750 | align 4 |
1706 | SOCKET_ptr_to_num: |
1751 | SOCKET_ptr_to_num: |
1707 | 1752 | ||
1708 | DEBUGF 1,"SOCKET_ptr_to_num: ptr=%x ", eax |
1753 | DEBUGF 1,"SOCKET_ptr_to_num: ptr=%x ", eax |
1709 | 1754 | ||
1710 | call SOCKET_check |
1755 | call SOCKET_check |
1711 | jz .error |
1756 | jz .error |
1712 | 1757 | ||
1713 | mov eax, [eax + SOCKET.Number] |
1758 | mov eax, [eax + SOCKET.Number] |
1714 | 1759 | ||
1715 | DEBUGF 1,"num=%u\n", eax |
1760 | DEBUGF 1,"num=%u\n", eax |
1716 | ret |
1761 | ret |
1717 | 1762 | ||
1718 | .error: |
1763 | .error: |
1719 | DEBUGF 1,"not found\n", eax |
1764 | DEBUGF 1,"not found\n", eax |
1720 | ret |
1765 | ret |
1721 | 1766 | ||
1722 | 1767 | ||
1723 | ;--------------------------------------------------- |
1768 | ;--------------------------------------------------- |
1724 | ; |
1769 | ; |
1725 | ; SOCKET_check |
1770 | ; SOCKET_check |
1726 | ; |
1771 | ; |
1727 | ; checks if the given value is really a socket ptr |
1772 | ; checks if the given value is really a socket ptr |
1728 | ; |
1773 | ; |
1729 | ; IN: eax = socket ptr |
1774 | ; IN: eax = socket ptr |
1730 | ; OUT: eax = 0 on error, unchanged otherwise |
1775 | ; OUT: eax = 0 on error, unchanged otherwise |
1731 | ; ZF = set on error |
1776 | ; ZF = set on error |
1732 | ; |
1777 | ; |
1733 | ;--------------------------------------------------- |
1778 | ;--------------------------------------------------- |
1734 | align 4 |
1779 | align 4 |
1735 | SOCKET_check: |
1780 | SOCKET_check: |
1736 | 1781 | ||
1737 | DEBUGF 1,"SOCKET_check: %x\n", eax |
1782 | DEBUGF 1,"SOCKET_check: %x\n", eax |
1738 | 1783 | ||
1739 | push ebx |
1784 | push ebx |
1740 | mov ebx, net_sockets |
1785 | mov ebx, net_sockets |
1741 | 1786 | ||
1742 | .next_socket: |
1787 | .next_socket: |
1743 | mov ebx, [ebx + SOCKET.NextPtr] |
1788 | mov ebx, [ebx + SOCKET.NextPtr] |
1744 | or ebx, ebx |
1789 | or ebx, ebx |
1745 | jz .done |
1790 | jz .done |
1746 | cmp ebx, eax |
1791 | cmp ebx, eax |
1747 | jnz .next_socket |
1792 | jnz .next_socket |
1748 | 1793 | ||
1749 | .done: |
1794 | .done: |
1750 | mov eax, ebx |
1795 | mov eax, ebx |
1751 | test eax, eax |
1796 | test eax, eax |
1752 | pop ebx |
1797 | pop ebx |
1753 | 1798 | ||
1754 | ret |
1799 | ret |
1755 | 1800 | ||
1756 | 1801 | ||
1757 | 1802 | ||
1758 | ;--------------------------------------------------- |
1803 | ;--------------------------------------------------- |
1759 | ; |
1804 | ; |
1760 | ; SOCKET_check_owner |
1805 | ; SOCKET_check_owner |
1761 | ; |
1806 | ; |
1762 | ; checks if the caller application owns the socket |
1807 | ; checks if the caller application owns the socket |
1763 | ; |
1808 | ; |
1764 | ; IN: eax = socket ptr |
1809 | ; IN: eax = socket ptr |
1765 | ; OUT: ZF = true/false |
1810 | ; OUT: ZF = true/false |
1766 | ; |
1811 | ; |
1767 | ;--------------------------------------------------- |
1812 | ;--------------------------------------------------- |
1768 | align 4 |
1813 | align 4 |
1769 | SOCKET_check_owner: |
1814 | SOCKET_check_owner: |
1770 | 1815 | ||
1771 | DEBUGF 1,"SOCKET_check_owner: %x\n", eax |
1816 | DEBUGF 1,"SOCKET_check_owner: %x\n", eax |
1772 | 1817 | ||
1773 | push ebx |
1818 | push ebx |
1774 | mov ebx, [TASK_BASE] |
1819 | mov ebx, [TASK_BASE] |
1775 | mov ebx, [ecx + TASKDATA.pid] |
1820 | mov ebx, [ecx + TASKDATA.pid] |
1776 | cmp [eax + SOCKET.PID], ebx |
1821 | cmp [eax + SOCKET.PID], ebx |
1777 | pop ebx |
1822 | pop ebx |
1778 | 1823 | ||
1779 | ret |
1824 | ret |
1780 | 1825 | ||
1781 | 1826 | ||
1782 | 1827 | ||
1783 | 1828 | ||
1784 | ;------------------------------------------------------ |
1829 | ;------------------------------------------------------ |
1785 | ; |
1830 | ; |
1786 | ; SOCKET_process_end |
1831 | ; SOCKET_process_end |
1787 | ; |
1832 | ; |
1788 | ; Kernel calls this function when a certain process ends |
1833 | ; Kernel calls this function when a certain process ends |
1789 | ; This function will check if the process had any open sockets |
1834 | ; This function will check if the process had any open sockets |
1790 | ; And update them accordingly |
1835 | ; And update them accordingly |
1791 | ; |
1836 | ; |
1792 | ; IN: edx = pid |
1837 | ; IN: edx = pid |
1793 | ; OUT: / |
1838 | ; OUT: / |
1794 | ; |
1839 | ; |
1795 | ;------------------------------------------------------ |
1840 | ;------------------------------------------------------ |
1796 | align 4 |
1841 | align 4 |
1797 | SOCKET_process_end: |
1842 | SOCKET_process_end: |
1798 | 1843 | ||
1799 | DEBUGF 1,"SOCKET_process_end: %x\n", edx |
1844 | DEBUGF 1,"SOCKET_process_end: %x\n", edx |
1800 | 1845 | ||
1801 | push ebx |
1846 | push ebx |
1802 | mov ebx, net_sockets |
1847 | mov ebx, net_sockets |
1803 | 1848 | ||
1804 | .next_socket: |
1849 | .next_socket: |
1805 | mov ebx, [ebx + SOCKET.NextPtr] |
1850 | mov ebx, [ebx + SOCKET.NextPtr] |
1806 | .test_socket: |
1851 | .test_socket: |
1807 | test ebx, ebx |
1852 | test ebx, ebx |
1808 | jz .done |
1853 | jz .done |
1809 | 1854 | ||
1810 | cmp [ebx + SOCKET.PID], edx |
1855 | cmp [ebx + SOCKET.PID], edx |
1811 | jne .next_socket |
1856 | jne .next_socket |
1812 | 1857 | ||
1813 | DEBUGF 1,"SOCKET_process_end: killing socket %x\n", ebx |
1858 | DEBUGF 1,"SOCKET_process_end: killing socket %x\n", ebx |
1814 | 1859 | ||
1815 | mov [ebx + SOCKET.PID], 0 |
1860 | mov [ebx + SOCKET.PID], 0 |
1816 | 1861 | ||
1817 | cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP |
1862 | cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP |
1818 | je .tcp |
1863 | je .tcp |
1819 | 1864 | ||
1820 | ; The socket is stateless, just kill it right away! |
1865 | ; The socket is stateless, just kill it right away! |
1821 | 1866 | ||
1822 | mov eax, ebx |
1867 | mov eax, ebx |
1823 | mov ebx, [ebx + SOCKET.NextPtr] |
1868 | mov ebx, [ebx + SOCKET.NextPtr] |
1824 | call SOCKET_free |
1869 | call SOCKET_free |
1825 | jmp .test_socket |
1870 | jmp .test_socket |
1826 | 1871 | ||
1827 | .tcp: |
1872 | .tcp: |
1828 | push [ebx + SOCKET.NextPtr] |
1873 | push [ebx + SOCKET.NextPtr] |
1829 | mov eax, ebx |
1874 | mov eax, ebx |
1830 | call TCP_disconnect |
1875 | call TCP_disconnect |
1831 | pop ebx |
1876 | pop ebx |
1832 | jmp .test_socket |
1877 | jmp .test_socket |
1833 | 1878 | ||
1834 | .done: |
1879 | .done: |
1835 | pop ebx |
1880 | pop ebx |
1836 | 1881 | ||
1837 | ret |
1882 | ret |
1838 | 1883 | ||
1839 | 1884 | ||
1840 | 1885 | ||
1841 | 1886 | ||
1842 | ;----------------------------------------------------------------- |
1887 | ;----------------------------------------------------------------- |
1843 | ; |
1888 | ; |
1844 | ; SOCKET_is_connecting |
1889 | ; SOCKET_is_connecting |
1845 | ; |
1890 | ; |
1846 | ; IN: eax = socket ptr |
1891 | ; IN: eax = socket ptr |
1847 | ; OUT: / |
1892 | ; OUT: / |
1848 | ; |
1893 | ; |
1849 | ;----------------------------------------------------------------- |
1894 | ;----------------------------------------------------------------- |
1850 | 1895 | ||
1851 | align 4 |
1896 | align 4 |
1852 | SOCKET_is_connecting: |
1897 | SOCKET_is_connecting: |
1853 | 1898 | ||
1854 | DEBUGF 1,"SOCKET_is_connecting: %x\n", eax |
1899 | DEBUGF 1,"SOCKET_is_connecting: %x\n", eax |
1855 | 1900 | ||
1856 | and [eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING) |
1901 | and [eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING) |
1857 | or [eax + SOCKET.options], SS_ISCONNECTING |
1902 | or [eax + SOCKET.options], SS_ISCONNECTING |
1858 | 1903 | ||
1859 | jmp SOCKET_notify_owner |
1904 | jmp SOCKET_notify_owner |
1860 | 1905 | ||
1861 | 1906 | ||
1862 | 1907 | ||
1863 | ;----------------------------------------------------------------- |
1908 | ;----------------------------------------------------------------- |
1864 | ; |
1909 | ; |
1865 | ; SOCKET_is_connected |
1910 | ; SOCKET_is_connected |
1866 | ; |
1911 | ; |
1867 | ; IN: eax = socket ptr |
1912 | ; IN: eax = socket ptr |
1868 | ; OUT: / |
1913 | ; OUT: / |
1869 | ; |
1914 | ; |
1870 | ;----------------------------------------------------------------- |
1915 | ;----------------------------------------------------------------- |
1871 | 1916 | ||
1872 | align 4 |
1917 | align 4 |
1873 | SOCKET_is_connected: |
1918 | SOCKET_is_connected: |
1874 | 1919 | ||
1875 | DEBUGF 1,"SOCKET_is_connected: %x\n", eax |
1920 | DEBUGF 1,"SOCKET_is_connected: %x\n", eax |
1876 | 1921 | ||
1877 | and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING) |
1922 | and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING) |
1878 | or [eax + SOCKET.options], SS_ISCONNECTED |
1923 | or [eax + SOCKET.options], SS_ISCONNECTED |
1879 | 1924 | ||
1880 | jmp SOCKET_notify_owner |
1925 | jmp SOCKET_notify_owner |
1881 | 1926 | ||
1882 | 1927 | ||
1883 | 1928 | ||
1884 | 1929 | ||
1885 | ;----------------------------------------------------------------- |
1930 | ;----------------------------------------------------------------- |
1886 | ; |
1931 | ; |
1887 | ; SOCKET_is_disconnecting |
1932 | ; SOCKET_is_disconnecting |
1888 | ; |
1933 | ; |
1889 | ; IN: eax = socket ptr |
1934 | ; IN: eax = socket ptr |
1890 | ; OUT: / |
1935 | ; OUT: / |
1891 | ; |
1936 | ; |
1892 | ;----------------------------------------------------------------- |
1937 | ;----------------------------------------------------------------- |
1893 | 1938 | ||
1894 | align 4 |
1939 | align 4 |
1895 | SOCKET_is_disconnecting: |
1940 | SOCKET_is_disconnecting: |
1896 | 1941 | ||
1897 | DEBUGF 1,"SOCKET_is_disconnecting: %x\n", eax |
1942 | DEBUGF 1,"SOCKET_is_disconnecting: %x\n", eax |
1898 | 1943 | ||
1899 | and [eax + SOCKET.options], not (SS_ISCONNECTING) |
1944 | and [eax + SOCKET.options], not (SS_ISCONNECTING) |
1900 | or [eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE |
1945 | or [eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE |
1901 | 1946 | ||
1902 | jmp SOCKET_notify_owner |
1947 | jmp SOCKET_notify_owner |
1903 | 1948 | ||
1904 | 1949 | ||
1905 | 1950 | ||
1906 | ;----------------------------------------------------------------- |
1951 | ;----------------------------------------------------------------- |
1907 | ; |
1952 | ; |
1908 | ; SOCKET_is_disconnected |
1953 | ; SOCKET_is_disconnected |
1909 | ; |
1954 | ; |
1910 | ; IN: eax = socket ptr |
1955 | ; IN: eax = socket ptr |
1911 | ; OUT: / |
1956 | ; OUT: / |
1912 | ; |
1957 | ; |
1913 | ;----------------------------------------------------------------- |
1958 | ;----------------------------------------------------------------- |
1914 | 1959 | ||
1915 | align 4 |
1960 | align 4 |
1916 | SOCKET_is_disconnected: |
1961 | SOCKET_is_disconnected: |
1917 | 1962 | ||
1918 | DEBUGF 1,"SOCKET_is_disconnected: %x\n", eax |
1963 | DEBUGF 1,"SOCKET_is_disconnected: %x\n", eax |
1919 | 1964 | ||
1920 | and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING) |
1965 | and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING) |
1921 | or [eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE |
1966 | or [eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE |
1922 | 1967 | ||
1923 | jmp SOCKET_notify_owner |
1968 | jmp SOCKET_notify_owner |
1924 | 1969 | ||
1925 | 1970 | ||
1926 | ;----------------------------------------------------------------- |
1971 | ;----------------------------------------------------------------- |
1927 | ; |
1972 | ; |
1928 | ; SOCKET_cant_recv_more |
1973 | ; SOCKET_cant_recv_more |
1929 | ; |
1974 | ; |
1930 | ; IN: eax = socket ptr |
1975 | ; IN: eax = socket ptr |
1931 | ; OUT: / |
1976 | ; OUT: / |
1932 | ; |
1977 | ; |
1933 | ;----------------------------------------------------------------- |
1978 | ;----------------------------------------------------------------- |
1934 | 1979 | ||
1935 | align 4 |
1980 | align 4 |
1936 | SOCKET_cant_recv_more: |
1981 | SOCKET_cant_recv_more: |
1937 | 1982 | ||
1938 | DEBUGF 1,"SOCKET_cant_recv_more: %x\n", eax |
1983 | DEBUGF 1,"SOCKET_cant_recv_more: %x\n", eax |
1939 | 1984 | ||
1940 | or [eax + SOCKET.options], SS_CANTRCVMORE |
1985 | or [eax + SOCKET.options], SS_CANTRCVMORE |
1941 | 1986 | ||
1942 | ret |
1987 | ret |
1943 | 1988 | ||
1944 | 1989 | ||
1945 | 1990 | ||
1946 | ;----------------------------------------------------------------- |
1991 | ;----------------------------------------------------------------- |
1947 | ; |
1992 | ; |
1948 | ; SOCKET_cant_send_more |
1993 | ; SOCKET_cant_send_more |
1949 | ; |
1994 | ; |
1950 | ; IN: eax = socket ptr |
1995 | ; IN: eax = socket ptr |
1951 | ; OUT: / |
1996 | ; OUT: / |
1952 | ; |
1997 | ; |
1953 | ;----------------------------------------------------------------- |
1998 | ;----------------------------------------------------------------- |
1954 | 1999 | ||
1955 | align 4 |
2000 | align 4 |
1956 | SOCKET_cant_send_more: |
2001 | SOCKET_cant_send_more: |
1957 | 2002 | ||
1958 | DEBUGF 1,"SOCKET_cant_send_more: %x\n", eax |
2003 | DEBUGF 1,"SOCKET_cant_send_more: %x\n", eax |
1959 | 2004 | ||
1960 | or [eax + SOCKET.options], SS_CANTSENDMORE |
2005 | or [eax + SOCKET.options], SS_CANTSENDMORE |
1961 | 2006 | ||
1962 | ret |
2007 | ret |