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