Rev 1255 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1159 | hidnplayr | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
1196 | hidnplayr | 3 | ;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
1159 | hidnplayr | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
||
6 | ;; SOCKET.INC ;; |
||
7 | ;; ;; |
||
8 | ;; Written by hidnplayr@kolibrios.org ;; |
||
9 | ;; based on code by mike.dld ;; |
||
10 | ;; ;; |
||
11 | ;; GNU GENERAL PUBLIC LICENSE ;; |
||
12 | ;; Version 2, June 1991 ;; |
||
13 | ;; ;; |
||
14 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
15 | |||
1206 | hidnplayr | 16 | $Revision: 1256 $ |
1159 | hidnplayr | 17 | |
1249 | hidnplayr | 18 | struct SOCKET_head |
1159 | hidnplayr | 19 | .PrevPtr dd ? ; pointer to previous socket in list |
20 | .NextPtr dd ? ; pointer to next socket in list |
||
21 | .Number dd ? ; socket number (unique within single process) |
||
22 | .PID dd ? ; application process id |
||
23 | .Domain dd ? ; INET/UNIX/.. |
||
24 | .Type dd ? ; RAW/UDP/TCP/... |
||
1196 | hidnplayr | 25 | .Protocol dd ? ; ICMP/IPv4/ARP/ |
1249 | hidnplayr | 26 | .lock dd ? ; lock mutex |
27 | .end: |
||
28 | ends |
||
29 | |||
30 | struct IPv4_SOCKET |
||
31 | .LocalIP dd ? |
||
32 | .RemoteIP dd ? |
||
33 | .SequenceNumber dd ? |
||
34 | |||
35 | ; todo: add options (for func 8 and 9) |
||
36 | |||
37 | .end: |
||
38 | ends |
||
39 | |||
40 | struct TCP_SOCKET |
||
41 | |||
42 | .LocalPort dw ? ; In INET byte order |
||
43 | .RemotePort dw ? ; In INET byte order |
||
44 | |||
45 | .backlog dw ? ; Backlog |
||
1256 | clevermous | 46 | .backlog_cur dw ? ; current size of queue for un-accept-ed connections |
47 | .last_ack_number dd ? ; used only to let application know that ACK has been received |
||
48 | ; todo: may be use SND_UNA instead |
||
49 | ; todo: may be use events which allow additional information instead |
||
50 | ; todo: may be count acknowledged bytes (at least it has obvious sense) |
||
1254 | hidnplayr | 51 | ; .OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state) |
52 | ; .OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state) |
||
53 | .wndsizeTimer dd ? ; window size timer |
||
54 | |||
55 | ; Transmission control block |
||
56 | .state dd ? ; TCB state |
||
57 | .timer dd ? ; TCB timer (seconds) |
||
58 | .ISS dd ? ; initial send sequence number |
||
59 | .IRS dd ? ; initial receive sequence number |
||
1196 | hidnplayr | 60 | .SND_UNA dd ? ; sequence number of unack'ed sent Packets |
1249 | hidnplayr | 61 | .SND_NXT dd ? ; next send sequence number to use |
1196 | hidnplayr | 62 | .SND_WND dd ? ; send window |
63 | .RCV_NXT dd ? ; next receive sequence number to use |
||
64 | .RCV_WND dd ? ; receive window |
||
65 | .SEG_LEN dd ? ; segment length |
||
66 | .SEG_WND dd ? ; segment window |
||
1249 | hidnplayr | 67 | |
68 | .flags db ? ; packet flags |
||
69 | |||
70 | .end: |
||
1159 | hidnplayr | 71 | ends |
72 | |||
1249 | hidnplayr | 73 | struct UDP_SOCKET |
1159 | hidnplayr | 74 | |
1249 | hidnplayr | 75 | .LocalPort dw ? ; In INET byte order |
76 | .RemotePort dw ? ; In INET byte order |
||
1159 | hidnplayr | 77 | |
1249 | hidnplayr | 78 | .end: |
79 | ends |
||
80 | |||
81 | struct ICMP_SOCKET |
||
82 | |||
83 | .Identifier dw ? ; |
||
84 | |||
85 | .end: |
||
86 | |||
87 | ends |
||
88 | |||
89 | struct IPC_SOCKET |
||
90 | |||
91 | .ConnectedTo dd ? ; Socket number of other socket this one is connected to |
||
92 | |||
93 | .end: |
||
94 | |||
95 | ends |
||
96 | |||
97 | MAX_backlog equ 20 ; backlog for stream sockets |
||
98 | SOCKETBUFFSIZE equ 4096 ; in bytes |
||
99 | SOCKET_QUEUE_SIZE equ 10 ; maximum number ofincoming packets queued for 1 socket |
||
100 | |||
1159 | hidnplayr | 101 | uglobal |
102 | net_sockets rd 2 |
||
103 | last_UDP_port dw ? ; These values give the number of the last used ephemeral port |
||
104 | last_TCP_port dw ? ; |
||
105 | endg |
||
106 | |||
107 | |||
108 | ;----------------------------------------------- |
||
109 | ; |
||
110 | ; SOCKET_init |
||
111 | ; |
||
112 | ; - |
||
113 | ; |
||
114 | ; IN: / |
||
115 | ; OUT: / |
||
116 | ; |
||
117 | ;----------------------------------------------- |
||
118 | |||
119 | align 4 |
||
120 | socket_init: |
||
121 | |||
122 | mov [net_sockets], 0 |
||
123 | mov [net_sockets + 4], 0 |
||
124 | |||
125 | mov [last_UDP_port], MIN_EPHEMERAL_PORT |
||
126 | mov [last_TCP_port], MIN_EPHEMERAL_PORT |
||
127 | |||
128 | ret |
||
129 | |||
130 | |||
1254 | hidnplayr | 131 | ;----------------------------------------------- |
1159 | hidnplayr | 132 | ; |
133 | ; Socket API (function 74) |
||
134 | ; |
||
1254 | hidnplayr | 135 | ;----------------------------------------------- |
1159 | hidnplayr | 136 | |
137 | align 4 |
||
138 | sys_socket: |
||
1254 | hidnplayr | 139 | and ebx, 0x000000FF ; should i remove this line ? |
1256 | clevermous | 140 | cmp bl , 8 ; highest possible number |
1254 | hidnplayr | 141 | jg s_error |
142 | lea ebx, [.table + 4*ebx] |
||
143 | jmp dword [ebx] |
||
1159 | hidnplayr | 144 | |
1254 | hidnplayr | 145 | .table: |
146 | dd socket_open ; 0 |
||
147 | dd socket_close ; 1 |
||
148 | dd socket_bind ; 2 |
||
149 | dd socket_listen ; 3 |
||
150 | dd socket_connect ; 4 |
||
151 | dd socket_accept ; 5 |
||
152 | dd socket_send ; 6 |
||
153 | dd socket_recv ; 7 |
||
1256 | clevermous | 154 | dd socket_get_opt ; 8 |
1254 | hidnplayr | 155 | ; dd socket_set_opt ; 9 |
1159 | hidnplayr | 156 | |
1254 | hidnplayr | 157 | |
1185 | hidnplayr | 158 | s_error: |
1159 | hidnplayr | 159 | mov dword [esp+32],-1 |
160 | |||
161 | ret |
||
162 | |||
163 | |||
164 | ;----------------------------------------------- |
||
165 | ; |
||
166 | ; SOCKET_open |
||
167 | ; |
||
168 | ; |
||
169 | ; IN: domain in ecx |
||
170 | ; type in edx |
||
1196 | hidnplayr | 171 | ; protocol in esi |
1159 | hidnplayr | 172 | ; OUT: eax is socket num, -1 on error |
173 | ; |
||
174 | ;----------------------------------------------- |
||
1206 | hidnplayr | 175 | align 4 |
1159 | hidnplayr | 176 | socket_open: |
177 | |||
178 | DEBUGF 1,"socket_open: domain: %u, type: %u",ecx, edx |
||
179 | |||
180 | call net_socket_alloc |
||
181 | or eax, eax |
||
1185 | hidnplayr | 182 | jz s_error |
1159 | hidnplayr | 183 | |
1249 | hidnplayr | 184 | mov [eax + SOCKET_head.Domain], ecx |
185 | mov [eax + SOCKET_head.Type], edx |
||
186 | mov [eax + SOCKET_head.Protocol], esi |
||
1159 | hidnplayr | 187 | |
188 | stdcall net_socket_addr_to_num, eax |
||
189 | DEBUGF 1,", socketnumber: %u\n", eax |
||
190 | |||
1254 | hidnplayr | 191 | ; TODO: if it is txcp socket, set state to TCB_CLOSED |
192 | |||
1159 | hidnplayr | 193 | mov [esp+32], eax |
194 | |||
195 | ret |
||
196 | |||
197 | |||
198 | |||
199 | |||
1249 | hidnplayr | 200 | |
201 | |||
202 | |||
203 | |||
1159 | hidnplayr | 204 | ;----------------------------------------------- |
205 | ; |
||
206 | ; SOCKET_bind |
||
207 | ; |
||
208 | ; IN: socket number in ecx |
||
209 | ; pointer to sockaddr struct in edx |
||
210 | ; length of that struct in esi |
||
211 | ; OUT: 0 on success |
||
212 | ; |
||
213 | ;----------------------------------------------- |
||
1206 | hidnplayr | 214 | align 4 |
1159 | hidnplayr | 215 | socket_bind: |
216 | |||
217 | DEBUGF 1,"Socket_bind: socknum: %u sockaddr: %x, length: %u, ",ecx,edx,esi |
||
218 | |||
219 | stdcall net_socket_num_to_addr, ecx |
||
220 | cmp eax, -1 |
||
1185 | hidnplayr | 221 | jz s_error |
1159 | hidnplayr | 222 | |
223 | cmp esi, 2 |
||
1185 | hidnplayr | 224 | jl s_error |
1159 | hidnplayr | 225 | |
226 | cmp word [edx], AF_INET4 |
||
1249 | hidnplayr | 227 | je .af_inet4 |
1159 | hidnplayr | 228 | |
1249 | hidnplayr | 229 | cmp word [edx], AF_UNIX |
230 | je .af_unix |
||
231 | |||
232 | jmp s_error |
||
233 | |||
234 | .af_unix: |
||
235 | |||
236 | ; TODO: write code here |
||
237 | |||
238 | mov dword [esp+32],0 |
||
239 | ret |
||
240 | |||
1159 | hidnplayr | 241 | .af_inet4: |
242 | |||
243 | cmp esi, 6 |
||
1185 | hidnplayr | 244 | jl s_error |
1159 | hidnplayr | 245 | |
1249 | hidnplayr | 246 | mov ecx, [eax + SOCKET_head.Type] |
247 | |||
1159 | hidnplayr | 248 | mov bx, word [edx + 2] |
1206 | hidnplayr | 249 | DEBUGF 1,"local port: %x ",bx |
1159 | hidnplayr | 250 | test bx, bx |
1206 | hidnplayr | 251 | jz .find_free |
1159 | hidnplayr | 252 | |
1206 | hidnplayr | 253 | call socket_check_port |
254 | test bx, bx |
||
255 | je s_error |
||
256 | jmp .got_port |
||
1159 | hidnplayr | 257 | |
1249 | hidnplayr | 258 | .find_free: |
1159 | hidnplayr | 259 | |
1206 | hidnplayr | 260 | call socket_find_port |
261 | test bx, bx |
||
262 | je s_error |
||
1159 | hidnplayr | 263 | |
1249 | hidnplayr | 264 | .got_port: |
1206 | hidnplayr | 265 | DEBUGF 1,"using port: %x ",bx |
1249 | hidnplayr | 266 | mov word [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx |
1159 | hidnplayr | 267 | |
268 | mov ebx, dword [edx + 4] |
||
1249 | hidnplayr | 269 | mov dword [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP], ebx |
1159 | hidnplayr | 270 | |
271 | DEBUGF 1,"local ip: %u.%u.%u.%u\n",\ |
||
1249 | hidnplayr | 272 | [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 0]:1,[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 1]:1,\ |
273 | [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 2]:1,[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 3]:1 |
||
1159 | hidnplayr | 274 | |
275 | mov dword [esp+32],0 |
||
276 | ret |
||
277 | |||
278 | |||
279 | |||
280 | |||
281 | ;----------------------------------------------- |
||
282 | ; |
||
283 | ; SOCKET_connect |
||
284 | ; |
||
285 | ; |
||
286 | ; IN: socket number in ecx |
||
287 | ; pointer to sockaddr struct in edx |
||
288 | ; length of that struct in esi |
||
289 | ; OUT: 0 on success |
||
290 | ; |
||
291 | ;----------------------------------------------- |
||
292 | align 4 |
||
293 | socket_connect: |
||
294 | |||
295 | DEBUGF 1,"Socket_connect: socknum: %u sockaddr: %x, length: %u,",ecx,edx,esi |
||
296 | |||
297 | stdcall net_socket_num_to_addr, ecx |
||
298 | cmp eax, -1 |
||
1185 | hidnplayr | 299 | jz s_error |
1159 | hidnplayr | 300 | |
1254 | hidnplayr | 301 | cmp esi, 8 |
1185 | hidnplayr | 302 | jl s_error |
1159 | hidnplayr | 303 | |
304 | cmp word [edx], AF_INET4 |
||
305 | je .af_inet4 |
||
306 | |||
1185 | hidnplayr | 307 | jmp s_error |
1159 | hidnplayr | 308 | |
309 | .af_inet4: |
||
310 | |||
1249 | hidnplayr | 311 | cmp [eax + SOCKET_head.Type], IP_PROTO_UDP |
1159 | hidnplayr | 312 | je .udp |
313 | |||
1249 | hidnplayr | 314 | cmp [eax + SOCKET_head.Type], IP_PROTO_TCP |
1206 | hidnplayr | 315 | je .tcp |
1159 | hidnplayr | 316 | |
1185 | hidnplayr | 317 | jmp s_error |
1159 | hidnplayr | 318 | |
1254 | hidnplayr | 319 | .udp: |
1159 | hidnplayr | 320 | |
321 | mov bx , word [edx + 2] |
||
1249 | hidnplayr | 322 | mov word [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx |
1206 | hidnplayr | 323 | DEBUGF 1,"remote port: %x ",bx |
1159 | hidnplayr | 324 | |
325 | mov ebx, dword [edx + 4] |
||
1249 | hidnplayr | 326 | mov dword [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx |
1159 | hidnplayr | 327 | DEBUGF 1,"remote ip: %u.%u.%u.%u\n",[edx+4]:1,[edx+5]:1,[edx+6]:1,[edx+7]:1 |
328 | |||
329 | mov dword [esp+32],0 |
||
330 | ret |
||
331 | |||
332 | |||
1254 | hidnplayr | 333 | .tcp: |
334 | ; TODO: set sequence number to random value |
||
1159 | hidnplayr | 335 | |
336 | |||
1254 | hidnplayr | 337 | ; fill in remote port and IP |
1159 | hidnplayr | 338 | |
1254 | hidnplayr | 339 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 0 ; Reset the window timer. |
340 | ; TODO: figure out WTF this is |
||
341 | mov bx , word [edx + 2] |
||
342 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], bx |
||
343 | DEBUGF 1,"remote port: %x ",bx |
||
1159 | hidnplayr | 344 | |
1254 | hidnplayr | 345 | mov ebx, dword [edx + 4] |
346 | mov [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx |
||
1159 | hidnplayr | 347 | |
1254 | hidnplayr | 348 | ; check if local port and IP is ok |
1159 | hidnplayr | 349 | |
1254 | hidnplayr | 350 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP], 0 |
351 | jne @f |
||
352 | push [IP_LIST] ; device zero = default |
||
353 | pop [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
||
354 | @@: |
||
1159 | hidnplayr | 355 | |
1254 | hidnplayr | 356 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], 0 |
357 | jne @f |
||
1159 | hidnplayr | 358 | |
1254 | hidnplayr | 359 | mov ecx, [eax + SOCKET_head.Type] |
360 | call socket_find_port |
||
361 | test bx, bx |
||
362 | jz s_error |
||
1159 | hidnplayr | 363 | |
1254 | hidnplayr | 364 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], bx |
365 | @@: |
||
1159 | hidnplayr | 366 | |
367 | |||
1254 | hidnplayr | 368 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT |
369 | ; now say hello to the remote tcp socket |
||
1159 | hidnplayr | 370 | |
1254 | hidnplayr | 371 | mov bl, TH_SYN |
372 | call TCP_send_ack |
||
1159 | hidnplayr | 373 | |
1254 | hidnplayr | 374 | mov dword [esp+32],0 |
1159 | hidnplayr | 375 | ret |
376 | |||
377 | |||
378 | |||
379 | |||
380 | ;----------------------------------------------- |
||
381 | ; |
||
382 | ; SOCKET_listen |
||
383 | ; |
||
384 | ; |
||
385 | ; IN: socket number in ecx |
||
386 | ; backlog in edx |
||
387 | ; OUT: eax is socket num, -1 on error |
||
388 | ; |
||
389 | ;----------------------------------------------- |
||
1206 | hidnplayr | 390 | align 4 |
1159 | hidnplayr | 391 | socket_listen: |
392 | |||
393 | DEBUGF 1,"Socket_listen: socknum: %u backlog: %u\n",ecx,edx |
||
394 | |||
395 | stdcall net_socket_num_to_addr, ecx |
||
396 | cmp eax, -1 |
||
1185 | hidnplayr | 397 | jz s_error |
1159 | hidnplayr | 398 | |
1254 | hidnplayr | 399 | cmp word [eax + SOCKET_head.Domain], AF_INET4 |
400 | jne s_error |
||
401 | |||
402 | cmp [eax + SOCKET_head.Type], IP_PROTO_TCP |
||
403 | jne s_error |
||
404 | |||
1159 | hidnplayr | 405 | cmp edx, MAX_backlog |
1256 | clevermous | 406 | jb .ok |
407 | mov dx , MAX_backlog |
||
1159 | hidnplayr | 408 | .ok: |
409 | |||
1249 | hidnplayr | 410 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog], dx |
1254 | hidnplayr | 411 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN |
1159 | hidnplayr | 412 | |
413 | mov dword [esp+32], 0 |
||
414 | ret |
||
415 | |||
416 | |||
417 | |||
418 | |||
419 | |||
420 | |||
421 | ;----------------------------------------------- |
||
422 | ; |
||
423 | ; SOCKET_accept |
||
424 | ; |
||
425 | ; |
||
426 | ; IN: socket number in ecx |
||
427 | ; addr in edx |
||
428 | ; addrlen in esi |
||
429 | ; OUT: eax is socket num, -1 on error |
||
430 | ; |
||
431 | ;----------------------------------------------- |
||
1206 | hidnplayr | 432 | align 4 |
1159 | hidnplayr | 433 | socket_accept: |
434 | |||
435 | DEBUGF 1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n",ecx,edx,esi |
||
436 | |||
437 | stdcall net_socket_num_to_addr, ecx |
||
438 | or eax, eax |
||
1185 | hidnplayr | 439 | jz s_error |
1159 | hidnplayr | 440 | mov esi, eax |
441 | |||
1249 | hidnplayr | 442 | cmp word [esi + SOCKET_head.Domain], AF_INET4 |
443 | je .af_inet4 |
||
444 | |||
445 | jmp s_error |
||
446 | |||
447 | .af_inet4: |
||
448 | |||
449 | cmp [esi + SOCKET_head.Type], IP_PROTO_TCP |
||
450 | je .tcp |
||
451 | |||
452 | jmp s_error |
||
453 | |||
454 | .tcp: |
||
455 | |||
1256 | clevermous | 456 | lea ebx, [esi + SOCKET_head.lock] |
457 | call wait_mutex |
||
458 | movzx eax, [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
||
459 | test eax, eax |
||
460 | jz .unlock_err |
||
461 | dec [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
||
462 | mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end + (eax-1)*4] |
||
463 | mov [esi + SOCKET_head.lock], 0 |
||
464 | stdcall net_socket_addr_to_num, eax |
||
1159 | hidnplayr | 465 | mov [esp+32], eax |
466 | ret |
||
1256 | clevermous | 467 | .unlock_err: |
468 | mov [esi + SOCKET_head.lock], 0 |
||
469 | jmp s_error |
||
1159 | hidnplayr | 470 | |
471 | |||
472 | ;----------------------------------------------- |
||
473 | ; |
||
474 | ; SOCKET_close |
||
475 | ; |
||
476 | ; |
||
477 | ; IN: socket number in ecx |
||
478 | ; OUT: eax is socket num, -1 on error |
||
479 | ; |
||
480 | ;----------------------------------------------- |
||
1206 | hidnplayr | 481 | align 4 |
1159 | hidnplayr | 482 | socket_close: |
483 | |||
484 | DEBUGF 1,"Socket_close: socknum: %u\n",ecx |
||
485 | |||
486 | stdcall net_socket_num_to_addr, ecx |
||
487 | or eax, eax |
||
1185 | hidnplayr | 488 | jz s_error |
1159 | hidnplayr | 489 | |
1249 | hidnplayr | 490 | cmp [eax + SOCKET_head.Domain], AF_INET4 |
491 | jne s_error |
||
1159 | hidnplayr | 492 | |
1249 | hidnplayr | 493 | cmp [eax + SOCKET_head.Type], IP_PROTO_UDP |
1159 | hidnplayr | 494 | je .udp |
495 | |||
1249 | hidnplayr | 496 | cmp [eax + SOCKET_head.Type], IP_PROTO_ICMP |
1159 | hidnplayr | 497 | je .icmp |
498 | |||
1249 | hidnplayr | 499 | cmp [eax + SOCKET_head.Type], IP_PROTO_TCP |
1206 | hidnplayr | 500 | je .tcp |
1159 | hidnplayr | 501 | |
1185 | hidnplayr | 502 | jmp s_error |
1159 | hidnplayr | 503 | |
504 | .udp: |
||
505 | |||
506 | stdcall net_socket_free, eax |
||
507 | mov dword [esp+32],0 |
||
508 | ret |
||
509 | |||
510 | |||
511 | .icmp: |
||
512 | |||
513 | |||
514 | |||
515 | ret |
||
516 | |||
517 | .tcp: |
||
1254 | hidnplayr | 518 | ; first, remove all resend entries for this socket |
1159 | hidnplayr | 519 | |
1254 | hidnplayr | 520 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN |
1159 | hidnplayr | 521 | je .destroy_tcb |
1254 | hidnplayr | 522 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT |
1159 | hidnplayr | 523 | je .destroy_tcb |
524 | |||
1254 | hidnplayr | 525 | ; Now construct the response, and queue for sending by IP |
1159 | hidnplayr | 526 | |
527 | mov bl, TH_FIN |
||
1254 | hidnplayr | 528 | call TCP_send_ack |
1159 | hidnplayr | 529 | |
530 | ; increament SND.NXT in socket |
||
1254 | hidnplayr | 531 | lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
532 | inc_INET esi |
||
1159 | hidnplayr | 533 | |
534 | ; Get the socket state |
||
1254 | hidnplayr | 535 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED |
1159 | hidnplayr | 536 | je .fin_wait_1 |
1254 | hidnplayr | 537 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED |
1159 | hidnplayr | 538 | je .fin_wait_1 |
539 | |||
540 | ; assume CLOSE WAIT |
||
541 | ; Send a fin, then enter last-ack state |
||
1254 | hidnplayr | 542 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LAST_ACK |
1159 | hidnplayr | 543 | jmp .send |
544 | |||
545 | .fin_wait_1: |
||
546 | ; Send a fin, then enter finwait2 state |
||
1254 | hidnplayr | 547 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_FIN_WAIT_1 |
1159 | hidnplayr | 548 | |
549 | .send: |
||
550 | |||
1254 | hidnplayr | 551 | ;;;;; |
1159 | hidnplayr | 552 | |
553 | .destroy_tcb: |
||
554 | |||
555 | stdcall net_socket_free, eax |
||
556 | mov dword [esp+32],0 |
||
557 | ret |
||
558 | |||
559 | |||
560 | |||
561 | |||
562 | ;----------------------------------------------- |
||
563 | ; |
||
564 | ; SOCKET_receive |
||
565 | ; |
||
566 | ; |
||
567 | ; IN: socket number in ecx |
||
1249 | hidnplayr | 568 | ; addr to buffer in edx |
569 | ; length of buffer in esi |
||
1159 | hidnplayr | 570 | ; flags in edi |
571 | ; OUT: eax is number of bytes copied, -1 on error |
||
572 | ; |
||
573 | ;----------------------------------------------- |
||
1206 | hidnplayr | 574 | align 4 |
1159 | hidnplayr | 575 | socket_recv: |
576 | |||
1249 | hidnplayr | 577 | DEBUGF 1,"Socket_receive: socknum: %u bufferaddress: %x, length: %u, flags: %x\n",ecx,edx,esi,edi |
1159 | hidnplayr | 578 | |
579 | stdcall net_socket_num_to_addr, ecx ; get real socket address |
||
580 | or eax, eax |
||
1185 | hidnplayr | 581 | jz s_error |
1159 | hidnplayr | 582 | |
1249 | hidnplayr | 583 | DEBUGF 1,"Socket pointer: %x\n", eax |
1159 | hidnplayr | 584 | |
1249 | hidnplayr | 585 | get_from_queue (eax + 2048), SOCKET_QUEUE_SIZE, 4*3, s_error |
1159 | hidnplayr | 586 | |
587 | mov edi, edx |
||
1249 | hidnplayr | 588 | mov ecx, [esi + socket_queue_entry.data_size] |
1159 | hidnplayr | 589 | |
1249 | hidnplayr | 590 | DEBUGF 1,"Got %u bytes of data\n", ecx |
1159 | hidnplayr | 591 | |
1249 | hidnplayr | 592 | cmp ecx, edx |
593 | jle .large_enough |
||
594 | DEBUGF 1,"Buffer too small...\n" |
||
595 | jmp s_error |
||
596 | .large_enough: |
||
1159 | hidnplayr | 597 | |
1249 | hidnplayr | 598 | push [esi + socket_queue_entry.data_ptr] |
599 | mov esi, [esi + socket_queue_entry.offset] |
||
600 | add esi, [esp] |
||
601 | DEBUGF 1,"Source buffer: %x, real addr: %x\n", [esp], esi |
||
1159 | hidnplayr | 602 | |
1249 | hidnplayr | 603 | mov dword[esp+32+4], ecx ; return number of bytes copied |
1159 | hidnplayr | 604 | |
1249 | hidnplayr | 605 | shr ecx, 1 |
606 | jnc .nb |
||
607 | movsb |
||
608 | .nb: shr ecx, 1 |
||
609 | jnc .nw |
||
610 | movsw |
||
611 | .nw: rep movsd |
||
1159 | hidnplayr | 612 | |
1249 | hidnplayr | 613 | call kernel_free |
1159 | hidnplayr | 614 | |
615 | ret |
||
616 | |||
617 | |||
618 | ;----------------------------------------------- |
||
619 | ; |
||
620 | ; SOCKET_send |
||
621 | ; |
||
622 | ; |
||
623 | ; IN: socket number in ecx |
||
1206 | hidnplayr | 624 | ; pointer to data in edx |
625 | ; datalength in esi |
||
1159 | hidnplayr | 626 | ; flags in edi |
627 | ; OUT: -1 on error |
||
628 | ; |
||
629 | ;----------------------------------------------- |
||
1254 | hidnplayr | 630 | |
1206 | hidnplayr | 631 | align 4 |
1159 | hidnplayr | 632 | socket_send: |
633 | |||
634 | DEBUGF 1,"Socket_send: socknum: %u sockaddr: %x, length: %u, flags: %x, ",ecx,edx,esi,edi |
||
635 | |||
636 | stdcall net_socket_num_to_addr, ecx ; get real socket address |
||
637 | or eax, eax |
||
1185 | hidnplayr | 638 | jz s_error |
1159 | hidnplayr | 639 | |
1249 | hidnplayr | 640 | cmp word [eax + SOCKET_head.Domain], AF_INET4 |
1206 | hidnplayr | 641 | je .af_inet4 |
642 | |||
643 | jmp s_error |
||
644 | |||
645 | .af_inet4: |
||
1249 | hidnplayr | 646 | DEBUGF 1,"Socket type:%u\n", [eax + SOCKET_head.Type]:4 |
1206 | hidnplayr | 647 | |
1249 | hidnplayr | 648 | cmp [eax + SOCKET_head.Type], IP_PROTO_TCP |
649 | je .tcp |
||
1159 | hidnplayr | 650 | |
1249 | hidnplayr | 651 | cmp [eax + SOCKET_head.Type], IP_PROTO_UDP |
1159 | hidnplayr | 652 | je .udp |
653 | |||
1249 | hidnplayr | 654 | cmp [eax + SOCKET_head.Type], SOCK_RAW |
655 | je .raw |
||
1159 | hidnplayr | 656 | |
1185 | hidnplayr | 657 | jmp s_error |
1159 | hidnplayr | 658 | |
659 | .udp: |
||
660 | |||
1206 | hidnplayr | 661 | DEBUGF 1,"type: UDP, " |
1159 | hidnplayr | 662 | |
1249 | hidnplayr | 663 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort],0 |
664 | jne @f |
||
1206 | hidnplayr | 665 | |
1208 | hidnplayr | 666 | push esi |
1249 | hidnplayr | 667 | mov ecx, [eax + SOCKET_head.Type] |
1206 | hidnplayr | 668 | call socket_find_port |
669 | test bx, bx |
||
1208 | hidnplayr | 670 | pop esi |
1206 | hidnplayr | 671 | je s_error |
1249 | hidnplayr | 672 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx |
1206 | hidnplayr | 673 | |
1249 | hidnplayr | 674 | @@: |
1206 | hidnplayr | 675 | |
1159 | hidnplayr | 676 | mov ecx, esi |
677 | mov esi, edx |
||
678 | |||
1249 | hidnplayr | 679 | call UDP_socket_send |
1159 | hidnplayr | 680 | |
681 | mov [esp+32], eax |
||
682 | ret |
||
683 | |||
1249 | hidnplayr | 684 | .tcp: |
1159 | hidnplayr | 685 | |
1254 | hidnplayr | 686 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort],0 |
687 | jne @f |
||
688 | |||
689 | push esi |
||
690 | mov ecx, [eax + SOCKET_head.Type] |
||
691 | call socket_find_port |
||
692 | test bx, bx |
||
693 | pop esi |
||
694 | je s_error |
||
695 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], bx |
||
696 | |||
697 | @@: |
||
698 | |||
699 | mov ecx, esi |
||
700 | mov esi, edx |
||
701 | |||
702 | call TCP_socket_send |
||
703 | |||
1249 | hidnplayr | 704 | mov [esp+32], eax |
705 | ret |
||
1159 | hidnplayr | 706 | |
1249 | hidnplayr | 707 | .raw: |
708 | cmp [eax + SOCKET_head.Protocol], IP_PROTO_IP |
||
709 | je .raw_ip |
||
710 | |||
711 | cmp [eax + SOCKET_head.Protocol], IP_PROTO_ICMP |
||
712 | je .raw_icmp |
||
713 | |||
714 | jmp s_error |
||
715 | |||
716 | |||
717 | .raw_ip: |
||
718 | |||
1254 | hidnplayr | 719 | ;;;;;; |
720 | |||
1159 | hidnplayr | 721 | mov [esp+32], eax |
722 | ret |
||
723 | |||
724 | |||
1249 | hidnplayr | 725 | .raw_icmp: |
726 | |||
727 | ; sub ecx, ICMP_Packet.Data |
||
728 | ; mov esi, edx |
||
729 | ; push ax |
||
730 | ; call IPv4_get_frgmnt_num |
||
731 | ; mov dx, ax |
||
732 | ; pop ax |
||
733 | ; shl edx, 16 |
||
734 | ; mov dh , [esi + ICMP_Packet.Type] |
||
735 | ; mov dl , [esi + ICMP_Packet.Code] |
||
736 | ; mov di , [esi + ICMP_Packet.Identifier] |
||
737 | ; mov [eax + SOCKET.LocalPort], di ; Set localport to the identifier number, so we can receive reply's |
||
738 | ; shl edi, 16 |
||
739 | ; mov di , [esi + ICMP_Packet.SequenceNumber] |
||
740 | ; add esi, ICMP_Packet.Data |
||
741 | ; mov ebx, [eax + SOCKET.LocalIP] |
||
742 | ; mov eax, [eax + SOCKET.RemoteIP] |
||
743 | ; call ICMP_create_packet |
||
744 | |||
745 | mov [esp+32], eax |
||
1159 | hidnplayr | 746 | ret |
747 | |||
1256 | clevermous | 748 | ;----------------------------------------------- |
749 | ; |
||
750 | ; SOCKET_send |
||
751 | ; |
||
752 | ; |
||
753 | ; IN: socket number in ecx |
||
754 | ; edx points to the options: |
||
755 | ; dd level, optname, optval, optlen |
||
756 | ; OUT: -1 on error |
||
757 | ; |
||
758 | ; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP. |
||
759 | ; TODO: find best way to notify that send()'ed data were acknowledged |
||
760 | ; |
||
761 | ;----------------------------------------------- |
||
762 | socket_get_opt: |
||
763 | cmp dword [edx], IP_PROTO_TCP |
||
764 | jnz .unknown |
||
765 | cmp dword [edx+4], -2 |
||
766 | jnz .unknown |
||
767 | mov eax, [edx+12] |
||
768 | test eax, eax |
||
769 | jz .fail |
||
770 | cmp dword [eax], 4 |
||
771 | mov dword [eax], 4 |
||
772 | jb .fail |
||
773 | stdcall net_socket_num_to_addr, ecx |
||
774 | test eax, eax |
||
775 | jz .fail |
||
776 | ; todo: check that eax is really TCP socket |
||
777 | mov ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number] |
||
778 | mov eax, [edx+8] |
||
779 | test eax, eax |
||
780 | jz @f |
||
781 | mov [eax], ecx |
||
782 | @@: |
||
783 | xor eax, eax |
||
784 | ret |
||
785 | .fail: |
||
786 | .unknown: |
||
787 | or eax, -1 |
||
788 | ret |
||
1159 | hidnplayr | 789 | |
790 | |||
1206 | hidnplayr | 791 | ;----------------------------------------------- |
792 | ; |
||
793 | ; SOCKET_find_free_port (local port) |
||
794 | ; |
||
795 | ; works with INET byte order |
||
796 | ; |
||
797 | ; IN: type in ecx (TCP/UDP) |
||
798 | ; OUT: bx = 0 on error, portnumber otherwise |
||
799 | ; |
||
800 | ;----------------------------------------------- |
||
801 | align 4 |
||
802 | socket_find_port: |
||
1159 | hidnplayr | 803 | |
1208 | hidnplayr | 804 | DEBUGF 1,"Socket_find_free_port\n" |
1159 | hidnplayr | 805 | |
1206 | hidnplayr | 806 | cmp ecx, IP_PROTO_UDP |
807 | je .udp |
||
1159 | hidnplayr | 808 | |
1206 | hidnplayr | 809 | cmp ecx, IP_PROTO_TCP |
810 | je .tcp |
||
1159 | hidnplayr | 811 | |
1206 | hidnplayr | 812 | .udp: |
813 | mov bx, [last_UDP_port] |
||
814 | je .continue |
||
815 | |||
816 | .tcp: |
||
817 | mov bx, [last_TCP_port] |
||
818 | |||
819 | |||
820 | .continue: |
||
821 | inc bx |
||
822 | |||
823 | .check_only: |
||
824 | mov esi, net_sockets |
||
825 | |||
826 | .next_socket: |
||
1249 | hidnplayr | 827 | mov esi, [esi + SOCKET_head.NextPtr] |
1206 | hidnplayr | 828 | or esi, esi |
829 | jz .port_ok |
||
830 | |||
1249 | hidnplayr | 831 | cmp [esi + SOCKET_head.Type], ecx |
1206 | hidnplayr | 832 | jne .next_socket |
833 | |||
834 | rol bx, 8 |
||
1249 | hidnplayr | 835 | cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx |
1206 | hidnplayr | 836 | rol bx, 8 ; this doesnt change the zero flag, does it ? |
837 | jne .next_socket |
||
838 | |||
839 | cmp bx, MAX_EPHEMERAL_PORT |
||
840 | jle .continue |
||
841 | |||
842 | ; todo: WRAP! |
||
843 | ; mov [last_UDP_port], MIN_EPHEMERAL_PORT |
||
844 | .exit: |
||
845 | xor ebx, ebx |
||
846 | |||
847 | .port_ok: |
||
848 | rol bx, 8 |
||
849 | ret |
||
850 | |||
851 | ;----------------------------------------------- |
||
852 | ; |
||
853 | ; SOCKET_check_port (local port) |
||
854 | ; |
||
855 | ; works with INET byte order |
||
856 | ; |
||
857 | ; IN: type in ecx (TCP/UDP) |
||
858 | ; port to check in bx |
||
859 | ; OUT: bx = 0 on error, unchanged otherwise |
||
860 | ; |
||
861 | ;----------------------------------------------- |
||
862 | align 4 |
||
863 | socket_check_port: |
||
864 | mov esi, net_sockets |
||
865 | |||
866 | .next_socket: |
||
1249 | hidnplayr | 867 | mov esi, [esi + SOCKET_head.NextPtr] |
1206 | hidnplayr | 868 | or esi, esi |
869 | jz .port_ok |
||
870 | |||
1249 | hidnplayr | 871 | cmp [esi + SOCKET_head.Type], ecx |
1206 | hidnplayr | 872 | jne .next_socket |
873 | |||
1249 | hidnplayr | 874 | cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx |
1206 | hidnplayr | 875 | jne .next_socket |
876 | |||
877 | xor ebx, ebx |
||
878 | |||
879 | .port_ok: |
||
880 | ret |
||
881 | |||
882 | |||
883 | ;----------------------------------------------- |
||
884 | ; |
||
885 | ; SOCKET_internal_receiver |
||
886 | ; |
||
1249 | hidnplayr | 887 | ; Updates a socket with received data |
1206 | hidnplayr | 888 | ; |
1249 | hidnplayr | 889 | ; Note: the mutex must already be set ! |
1206 | hidnplayr | 890 | ; |
1249 | hidnplayr | 891 | ; IN: eax = socket ptr |
892 | ; ecx = size |
||
893 | ; esi = pointer to buffer |
||
894 | ; edi = offset |
||
895 | ; |
||
1206 | hidnplayr | 896 | ; OUT: xxx |
897 | ; |
||
898 | ;----------------------------------------------- |
||
899 | align 4 |
||
900 | socket_internal_receiver: |
||
901 | |||
1255 | hidnplayr | 902 | DEBUGF 1,"Internal socket receiver: buffer %x, offset: %x size=%u socket: %x\n", esi, edi, ecx, eax |
1206 | hidnplayr | 903 | |
1249 | hidnplayr | 904 | push edi ; offset |
905 | push ecx ; size |
||
906 | push esi ; data_ptr |
||
907 | mov esi, esp |
||
1256 | clevermous | 908 | add_to_queue (eax + 2048), SOCKET_QUEUE_SIZE, 3*4, notify_network_event.full |
1249 | hidnplayr | 909 | DEBUGF 1,"Queued packet successfully\n" |
910 | add esp, 4*3 |
||
1206 | hidnplayr | 911 | |
1249 | hidnplayr | 912 | mov [eax + SOCKET_head.lock], 0 |
1206 | hidnplayr | 913 | |
1256 | clevermous | 914 | notify_network_event: |
1206 | hidnplayr | 915 | ; flag an event to the application |
1249 | hidnplayr | 916 | mov edx, [eax + SOCKET_head.PID] ; get socket owner PID |
1206 | hidnplayr | 917 | mov ecx, 1 |
918 | mov esi, TASK_DATA + TASKDATA.pid |
||
919 | |||
920 | .next_pid: |
||
921 | cmp [esi], edx |
||
922 | je .found_pid |
||
923 | inc ecx |
||
924 | add esi, 0x20 |
||
925 | cmp ecx, [TASK_COUNT] |
||
926 | jbe .next_pid |
||
927 | ret |
||
928 | |||
929 | .found_pid: |
||
930 | shl ecx, 8 |
||
1249 | hidnplayr | 931 | or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event |
1206 | hidnplayr | 932 | mov [check_idle_semaphore], 200 |
933 | ret |
||
934 | |||
1249 | hidnplayr | 935 | .full: |
936 | DEBUGF 1,"Socket %x is full!\n",eax |
||
937 | mov [eax + SOCKET_head.lock], 0 |
||
938 | call kernel_free |
||
939 | add esp, 8 |
||
1206 | hidnplayr | 940 | ret |
941 | |||
942 | |||
943 | |||
1159 | hidnplayr | 944 | ; Allocate memory for socket data and put new socket into the list |
945 | ; Newly created socket is initialized with calling PID and number and |
||
946 | ; put into beginning of list (which is a fastest way). |
||
947 | ; |
||
948 | ; @return socket structure address in EAX |
||
949 | ; |
||
950 | proc net_socket_alloc stdcall uses ebx ecx edx edi |
||
951 | stdcall kernel_alloc, SOCKETBUFFSIZE |
||
952 | DEBUGF 1, "K : net_socket_alloc (0x%x)\n", eax |
||
953 | ; check if we can allocate needed amount of memory |
||
954 | or eax, eax |
||
955 | jz .exit |
||
956 | |||
957 | ; zero-initialize allocated memory |
||
958 | push eax |
||
959 | mov edi, eax |
||
1249 | hidnplayr | 960 | |
1159 | hidnplayr | 961 | mov ecx, SOCKETBUFFSIZE / 4 |
962 | ; cld |
||
963 | xor eax, eax |
||
964 | rep stosd |
||
965 | pop eax |
||
966 | |||
1249 | hidnplayr | 967 | init_queue (eax + 2048) |
968 | |||
1159 | hidnplayr | 969 | ; add socket to the list by changing pointers |
970 | mov ebx, net_sockets |
||
1249 | hidnplayr | 971 | push [ebx + SOCKET_head.NextPtr] |
972 | mov [ebx + SOCKET_head.NextPtr], eax |
||
973 | mov [eax + SOCKET_head.PrevPtr], ebx |
||
1159 | hidnplayr | 974 | pop ebx |
1249 | hidnplayr | 975 | mov [eax + SOCKET_head.NextPtr], ebx |
1159 | hidnplayr | 976 | or ebx, ebx |
977 | jz @f |
||
1249 | hidnplayr | 978 | mov [ebx + SOCKET_head.PrevPtr], eax |
1159 | hidnplayr | 979 | |
980 | @@: ; set socket owner PID to the one of calling process |
||
981 | mov ebx, [TASK_BASE] |
||
982 | mov ebx, [ebx + TASKDATA.pid] |
||
1249 | hidnplayr | 983 | mov [eax + SOCKET_head.PID], ebx |
1159 | hidnplayr | 984 | |
985 | ; find first free socket number and use it |
||
986 | ;mov edx, ebx |
||
987 | mov ebx, net_sockets |
||
988 | xor ecx, ecx |
||
989 | .next_socket_number: |
||
990 | inc ecx |
||
991 | .next_socket: |
||
1249 | hidnplayr | 992 | mov ebx, [ebx + SOCKET_head.NextPtr] |
1159 | hidnplayr | 993 | or ebx, ebx |
994 | jz .last_socket_number |
||
1249 | hidnplayr | 995 | cmp [ebx + SOCKET_head.Number], ecx |
1159 | hidnplayr | 996 | jne .next_socket |
997 | ;cmp [ebx + SOCKET.PID], edx |
||
998 | ;jne .next_socket |
||
999 | mov ebx, net_sockets |
||
1000 | jmp .next_socket_number |
||
1001 | |||
1002 | .last_socket_number: |
||
1249 | hidnplayr | 1003 | mov [eax + SOCKET_head.Number], ecx |
1159 | hidnplayr | 1004 | |
1005 | .exit: |
||
1006 | ret |
||
1007 | endp |
||
1008 | |||
1009 | ; Free socket data memory and pop socket off the list |
||
1010 | ; |
||
1011 | ; @param sockAddr is a socket structure address |
||
1012 | ; |
||
1013 | proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD |
||
1014 | mov eax, [sockAddr] |
||
1015 | DEBUGF 1, "K : net_socket_free (0x%x)\n", eax |
||
1016 | ; check if we got something similar to socket structure address |
||
1017 | or eax, eax |
||
1018 | jz .error |
||
1019 | |||
1020 | ; make sure sockAddr is one of the socket addresses in the list |
||
1021 | mov ebx, net_sockets |
||
1022 | ;mov ecx, [TASK_BASE] |
||
1023 | ;mov ecx, [ecx + TASKDATA.pid] |
||
1024 | .next_socket: |
||
1249 | hidnplayr | 1025 | mov ebx, [ebx + SOCKET_head.NextPtr] |
1159 | hidnplayr | 1026 | or ebx, ebx |
1027 | jz .error |
||
1028 | cmp ebx, eax |
||
1029 | jne .next_socket |
||
1030 | ;cmp [ebx + SOCKET.PID], ecx |
||
1031 | ;jne .next_socket |
||
1032 | |||
1033 | ; okay, we found the correct one |
||
1034 | ; remove it from the list first, changing pointers |
||
1249 | hidnplayr | 1035 | mov ebx, [eax + SOCKET_head.NextPtr] |
1036 | mov eax, [eax + SOCKET_head.PrevPtr] |
||
1037 | mov [eax + SOCKET_head.NextPtr], ebx |
||
1159 | hidnplayr | 1038 | or ebx, ebx |
1039 | jz @f |
||
1249 | hidnplayr | 1040 | mov [ebx + SOCKET_head.PrevPtr], eax |
1159 | hidnplayr | 1041 | |
1249 | hidnplayr | 1042 | lea ebx, [eax + SOCKET_head.lock] |
1043 | call wait_mutex |
||
1044 | |||
1159 | hidnplayr | 1045 | @@: ; and finally free the memory structure used |
1046 | stdcall kernel_free, [sockAddr] |
||
1047 | ret |
||
1048 | |||
1049 | .error: |
||
1050 | DEBUGF 1, "K : failed\n" |
||
1051 | ret |
||
1052 | endp |
||
1053 | |||
1054 | ; Get socket structure address by its number |
||
1055 | ; Scan through sockets list to find the socket with specified number. |
||
1056 | ; This proc uses SOCKET.PID indirectly to check if socket is owned by |
||
1057 | ; calling process. |
||
1058 | ; |
||
1059 | ; @param sockNum is a socket number |
||
1060 | ; @return socket structure address or 0 (not found) in EAX |
||
1061 | ; |
||
1062 | proc net_socket_num_to_addr stdcall uses ebx ecx, sockNum:DWORD |
||
1063 | mov eax, [sockNum] |
||
1064 | ; check if we got something similar to socket number |
||
1065 | or eax, eax |
||
1066 | jz .error |
||
1067 | |||
1068 | ; scan through sockets list |
||
1069 | mov ebx, net_sockets |
||
1070 | ;mov ecx, [TASK_BASE] |
||
1071 | ;mov ecx, [ecx + TASKDATA.pid] |
||
1072 | .next_socket: |
||
1249 | hidnplayr | 1073 | mov ebx, [ebx + SOCKET_head.NextPtr] |
1159 | hidnplayr | 1074 | or ebx, ebx |
1075 | jz .error |
||
1249 | hidnplayr | 1076 | cmp [ebx + SOCKET_head.Number], eax |
1159 | hidnplayr | 1077 | jne .next_socket |
1078 | ;cmp [ebx + SOCKET.PID], ecx |
||
1079 | ;jne .next_socket |
||
1080 | |||
1081 | ; okay, we found the correct one |
||
1082 | mov eax, ebx |
||
1083 | ret |
||
1084 | |||
1085 | .error: |
||
1086 | xor eax, eax |
||
1087 | ret |
||
1088 | endp |
||
1089 | |||
1090 | ; Get socket number by its structure address |
||
1091 | ; Scan through sockets list to find the socket with specified address. |
||
1092 | ; This proc uses SOCKET.PID indirectly to check if socket is owned by |
||
1093 | ; calling process. |
||
1094 | ; |
||
1095 | ; @param sockAddr is a socket structure address |
||
1096 | ; @return socket number (SOCKET.Number) or 0 (not found) in EAX |
||
1097 | ; |
||
1098 | proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD |
||
1099 | mov eax, [sockAddr] |
||
1100 | ; check if we got something similar to socket structure address |
||
1101 | or eax, eax |
||
1102 | jz .error |
||
1103 | |||
1104 | ; scan through sockets list |
||
1105 | mov ebx, net_sockets |
||
1106 | ;mov ecx, [TASK_BASE] |
||
1107 | ;mov ecx, [ecx + TASKDATA.pid] |
||
1108 | .next_socket: |
||
1249 | hidnplayr | 1109 | mov ebx, [ebx + SOCKET_head.NextPtr] |
1159 | hidnplayr | 1110 | or ebx, ebx |
1111 | jz .error |
||
1112 | cmp ebx, eax |
||
1113 | jne .next_socket |
||
1114 | ;cmp [ebx + SOCKET.PID], ecx |
||
1115 | ;jne .next_socket |
||
1116 | |||
1117 | ; okay, we found the correct one |
||
1249 | hidnplayr | 1118 | mov eax, [ebx + SOCKET_head.Number] |
1159 | hidnplayr | 1119 | ret |
1120 | |||
1121 | .error: |
||
1122 | xor eax, eax |
||
1123 | ret |
||
1124 | endp |