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