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