Rev 1263 | 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: 1274 $ |
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 | |
337 | |||
1254 | hidnplayr | 338 | ; fill in remote port and IP |
1159 | hidnplayr | 339 | |
1254 | hidnplayr | 340 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 0 ; Reset the window timer. |
341 | ; TODO: figure out WTF this is |
||
342 | mov bx , word [edx + 2] |
||
343 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], bx |
||
344 | DEBUGF 1,"remote port: %x ",bx |
||
1159 | hidnplayr | 345 | |
1254 | hidnplayr | 346 | mov ebx, dword [edx + 4] |
347 | mov [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx |
||
1159 | hidnplayr | 348 | |
1254 | hidnplayr | 349 | ; check if local port and IP is ok |
1159 | hidnplayr | 350 | |
1254 | hidnplayr | 351 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP], 0 |
352 | jne @f |
||
353 | push [IP_LIST] ; device zero = default |
||
354 | pop [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
||
355 | @@: |
||
1159 | hidnplayr | 356 | |
1254 | hidnplayr | 357 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], 0 |
358 | jne @f |
||
1159 | hidnplayr | 359 | |
1254 | hidnplayr | 360 | mov ecx, [eax + SOCKET_head.Type] |
361 | call socket_find_port |
||
362 | test bx, bx |
||
363 | jz s_error |
||
1159 | hidnplayr | 364 | |
1254 | hidnplayr | 365 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], bx |
366 | @@: |
||
1159 | hidnplayr | 367 | |
368 | |||
1254 | hidnplayr | 369 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT |
370 | ; now say hello to the remote tcp socket |
||
1159 | hidnplayr | 371 | |
1254 | hidnplayr | 372 | mov bl, TH_SYN |
1274 | hidnplayr | 373 | xor ecx, ecx |
374 | call TCP_send |
||
1159 | hidnplayr | 375 | |
1254 | hidnplayr | 376 | mov dword [esp+32],0 |
1159 | hidnplayr | 377 | ret |
378 | |||
379 | |||
1257 | hidnplayr | 380 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 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 | ; |
||
1257 | hidnplayr | 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 | |||
1257 | hidnplayr | 417 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 418 | ; |
419 | ; SOCKET_accept |
||
420 | ; |
||
421 | ; |
||
422 | ; IN: socket number in ecx |
||
423 | ; addr in edx |
||
424 | ; addrlen in esi |
||
425 | ; OUT: eax is socket num, -1 on error |
||
426 | ; |
||
1257 | hidnplayr | 427 | ;----------------------------------------------------------------- |
1206 | hidnplayr | 428 | align 4 |
1159 | hidnplayr | 429 | socket_accept: |
430 | |||
431 | DEBUGF 1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n",ecx,edx,esi |
||
432 | |||
433 | stdcall net_socket_num_to_addr, ecx |
||
434 | or eax, eax |
||
1185 | hidnplayr | 435 | jz s_error |
1159 | hidnplayr | 436 | mov esi, eax |
437 | |||
1249 | hidnplayr | 438 | cmp word [esi + SOCKET_head.Domain], AF_INET4 |
439 | je .af_inet4 |
||
440 | |||
441 | jmp s_error |
||
442 | |||
443 | .af_inet4: |
||
444 | |||
445 | cmp [esi + SOCKET_head.Type], IP_PROTO_TCP |
||
446 | je .tcp |
||
447 | |||
448 | jmp s_error |
||
449 | |||
450 | .tcp: |
||
451 | |||
1256 | clevermous | 452 | lea ebx, [esi + SOCKET_head.lock] |
453 | call wait_mutex |
||
454 | movzx eax, [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
||
455 | test eax, eax |
||
456 | jz .unlock_err |
||
457 | dec [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
||
458 | mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end + (eax-1)*4] |
||
459 | mov [esi + SOCKET_head.lock], 0 |
||
1257 | hidnplayr | 460 | stdcall net_socket_addr_to_num, eax |
1159 | hidnplayr | 461 | mov [esp+32], eax |
462 | ret |
||
1256 | clevermous | 463 | .unlock_err: |
464 | mov [esi + SOCKET_head.lock], 0 |
||
465 | jmp s_error |
||
1159 | hidnplayr | 466 | |
467 | |||
1257 | hidnplayr | 468 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 469 | ; |
470 | ; SOCKET_close |
||
471 | ; |
||
472 | ; |
||
473 | ; IN: socket number in ecx |
||
474 | ; OUT: eax is socket num, -1 on error |
||
475 | ; |
||
1257 | hidnplayr | 476 | ;----------------------------------------------------------------- |
1206 | hidnplayr | 477 | align 4 |
1159 | hidnplayr | 478 | socket_close: |
479 | |||
480 | DEBUGF 1,"Socket_close: socknum: %u\n",ecx |
||
481 | |||
482 | stdcall net_socket_num_to_addr, ecx |
||
483 | or eax, eax |
||
1185 | hidnplayr | 484 | jz s_error |
1159 | hidnplayr | 485 | |
1249 | hidnplayr | 486 | cmp [eax + SOCKET_head.Domain], AF_INET4 |
487 | jne s_error |
||
1159 | hidnplayr | 488 | |
1249 | hidnplayr | 489 | cmp [eax + SOCKET_head.Type], IP_PROTO_UDP |
1159 | hidnplayr | 490 | je .udp |
491 | |||
1249 | hidnplayr | 492 | cmp [eax + SOCKET_head.Type], IP_PROTO_ICMP |
1159 | hidnplayr | 493 | je .icmp |
494 | |||
1249 | hidnplayr | 495 | cmp [eax + SOCKET_head.Type], IP_PROTO_TCP |
1206 | hidnplayr | 496 | je .tcp |
1159 | hidnplayr | 497 | |
1185 | hidnplayr | 498 | jmp s_error |
1159 | hidnplayr | 499 | |
500 | .udp: |
||
501 | |||
502 | stdcall net_socket_free, eax |
||
503 | mov dword [esp+32],0 |
||
504 | ret |
||
505 | |||
506 | |||
507 | .icmp: |
||
508 | |||
509 | |||
510 | |||
511 | ret |
||
512 | |||
513 | .tcp: |
||
1254 | hidnplayr | 514 | ; first, remove all resend entries for this socket |
1159 | hidnplayr | 515 | |
1254 | hidnplayr | 516 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN |
1159 | hidnplayr | 517 | je .destroy_tcb |
1254 | hidnplayr | 518 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT |
1159 | hidnplayr | 519 | je .destroy_tcb |
520 | |||
1254 | hidnplayr | 521 | ; Now construct the response, and queue for sending by IP |
1159 | hidnplayr | 522 | |
523 | mov bl, TH_FIN |
||
1274 | hidnplayr | 524 | xor ecx, ecx |
525 | call TCP_send |
||
1159 | hidnplayr | 526 | |
527 | ; increament SND.NXT in socket |
||
1254 | hidnplayr | 528 | lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
529 | inc_INET esi |
||
1159 | hidnplayr | 530 | |
531 | ; Get the socket state |
||
1254 | hidnplayr | 532 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED |
1159 | hidnplayr | 533 | je .fin_wait_1 |
1254 | hidnplayr | 534 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED |
1159 | hidnplayr | 535 | je .fin_wait_1 |
536 | |||
537 | ; assume CLOSE WAIT |
||
538 | ; Send a fin, then enter last-ack state |
||
1254 | hidnplayr | 539 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LAST_ACK |
1159 | hidnplayr | 540 | jmp .send |
541 | |||
542 | .fin_wait_1: |
||
543 | ; Send a fin, then enter finwait2 state |
||
1254 | hidnplayr | 544 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_FIN_WAIT_1 |
1159 | hidnplayr | 545 | |
546 | .send: |
||
547 | |||
1254 | hidnplayr | 548 | ;;;;; |
1159 | hidnplayr | 549 | |
550 | .destroy_tcb: |
||
551 | |||
552 | stdcall net_socket_free, eax |
||
553 | mov dword [esp+32],0 |
||
554 | ret |
||
555 | |||
556 | |||
557 | |||
558 | |||
1257 | hidnplayr | 559 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 560 | ; |
561 | ; SOCKET_receive |
||
562 | ; |
||
563 | ; |
||
564 | ; IN: socket number in ecx |
||
1249 | hidnplayr | 565 | ; addr to buffer in edx |
566 | ; length of buffer in esi |
||
1159 | hidnplayr | 567 | ; flags in edi |
568 | ; OUT: eax is number of bytes copied, -1 on error |
||
569 | ; |
||
1257 | hidnplayr | 570 | ;----------------------------------------------------------------- |
1206 | hidnplayr | 571 | align 4 |
1159 | hidnplayr | 572 | socket_recv: |
573 | |||
1249 | hidnplayr | 574 | DEBUGF 1,"Socket_receive: socknum: %u bufferaddress: %x, length: %u, flags: %x\n",ecx,edx,esi,edi |
1159 | hidnplayr | 575 | stdcall net_socket_num_to_addr, ecx ; get real socket address |
576 | or eax, eax |
||
1185 | hidnplayr | 577 | jz s_error |
1159 | hidnplayr | 578 | |
1249 | hidnplayr | 579 | DEBUGF 1,"Socket pointer: %x\n", eax |
1159 | hidnplayr | 580 | |
1257 | hidnplayr | 581 | get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, s_error |
1159 | hidnplayr | 582 | |
583 | mov edi, edx |
||
1249 | hidnplayr | 584 | mov ecx, [esi + socket_queue_entry.data_size] |
1159 | hidnplayr | 585 | |
1249 | hidnplayr | 586 | DEBUGF 1,"Got %u bytes of data\n", ecx |
1159 | hidnplayr | 587 | |
1249 | hidnplayr | 588 | cmp ecx, edx |
589 | jle .large_enough |
||
590 | DEBUGF 1,"Buffer too small...\n" |
||
591 | jmp s_error |
||
592 | .large_enough: |
||
1159 | hidnplayr | 593 | |
1249 | hidnplayr | 594 | push [esi + socket_queue_entry.data_ptr] |
595 | mov esi, [esi + socket_queue_entry.offset] |
||
596 | add esi, [esp] |
||
597 | DEBUGF 1,"Source buffer: %x, real addr: %x\n", [esp], esi |
||
1159 | hidnplayr | 598 | |
1249 | hidnplayr | 599 | mov dword[esp+32+4], ecx ; return number of bytes copied |
1159 | hidnplayr | 600 | |
1249 | hidnplayr | 601 | shr ecx, 1 |
602 | jnc .nb |
||
603 | movsb |
||
604 | .nb: shr ecx, 1 |
||
605 | jnc .nw |
||
606 | movsw |
||
1274 | hidnplayr | 607 | .nw: test ecx, ecx |
608 | jz .nd |
||
609 | rep movsd |
||
610 | .nd: |
||
1159 | hidnplayr | 611 | |
1249 | hidnplayr | 612 | call kernel_free |
1159 | hidnplayr | 613 | |
614 | ret |
||
615 | |||
616 | |||
1257 | hidnplayr | 617 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 618 | ; |
619 | ; SOCKET_send |
||
620 | ; |
||
621 | ; |
||
622 | ; IN: socket number in ecx |
||
1206 | hidnplayr | 623 | ; pointer to data in edx |
624 | ; datalength in esi |
||
1159 | hidnplayr | 625 | ; flags in edi |
626 | ; OUT: -1 on error |
||
627 | ; |
||
1257 | hidnplayr | 628 | ;----------------------------------------------------------------- |
1206 | hidnplayr | 629 | align 4 |
1159 | hidnplayr | 630 | socket_send: |
631 | |||
632 | DEBUGF 1,"Socket_send: socknum: %u sockaddr: %x, length: %u, flags: %x, ",ecx,edx,esi,edi |
||
633 | |||
634 | stdcall net_socket_num_to_addr, ecx ; get real socket address |
||
635 | or eax, eax |
||
1185 | hidnplayr | 636 | jz s_error |
1159 | hidnplayr | 637 | |
1249 | hidnplayr | 638 | cmp word [eax + SOCKET_head.Domain], AF_INET4 |
1206 | hidnplayr | 639 | je .af_inet4 |
640 | |||
641 | jmp s_error |
||
642 | |||
643 | .af_inet4: |
||
1249 | hidnplayr | 644 | DEBUGF 1,"Socket type:%u\n", [eax + SOCKET_head.Type]:4 |
1206 | hidnplayr | 645 | |
1249 | hidnplayr | 646 | cmp [eax + SOCKET_head.Type], IP_PROTO_TCP |
647 | je .tcp |
||
1159 | hidnplayr | 648 | |
1249 | hidnplayr | 649 | cmp [eax + SOCKET_head.Type], IP_PROTO_UDP |
1159 | hidnplayr | 650 | je .udp |
651 | |||
1249 | hidnplayr | 652 | cmp [eax + SOCKET_head.Type], SOCK_RAW |
653 | je .raw |
||
1159 | hidnplayr | 654 | |
1185 | hidnplayr | 655 | jmp s_error |
1159 | hidnplayr | 656 | |
657 | .udp: |
||
658 | |||
1206 | hidnplayr | 659 | DEBUGF 1,"type: UDP, " |
1159 | hidnplayr | 660 | |
1249 | hidnplayr | 661 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort],0 |
662 | jne @f |
||
1206 | hidnplayr | 663 | |
1208 | hidnplayr | 664 | push esi |
1249 | hidnplayr | 665 | mov ecx, [eax + SOCKET_head.Type] |
1206 | hidnplayr | 666 | call socket_find_port |
667 | test bx, bx |
||
1208 | hidnplayr | 668 | pop esi |
1206 | hidnplayr | 669 | je s_error |
1249 | hidnplayr | 670 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx |
1206 | hidnplayr | 671 | |
1249 | hidnplayr | 672 | @@: |
1206 | hidnplayr | 673 | |
1159 | hidnplayr | 674 | mov ecx, esi |
675 | mov esi, edx |
||
676 | |||
1249 | hidnplayr | 677 | call UDP_socket_send |
1159 | hidnplayr | 678 | |
1263 | clevermous | 679 | and dword [esp+32], 0 |
1159 | hidnplayr | 680 | ret |
681 | |||
1249 | hidnplayr | 682 | .tcp: |
1159 | hidnplayr | 683 | |
1254 | hidnplayr | 684 | cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort],0 |
685 | jne @f |
||
686 | |||
687 | push esi |
||
688 | mov ecx, [eax + SOCKET_head.Type] |
||
689 | call socket_find_port |
||
690 | test bx, bx |
||
691 | pop esi |
||
692 | je s_error |
||
693 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], bx |
||
694 | |||
695 | @@: |
||
696 | |||
697 | mov ecx, esi |
||
698 | mov esi, edx |
||
1274 | hidnplayr | 699 | xor bl , bl |
1254 | hidnplayr | 700 | |
1274 | hidnplayr | 701 | call TCP_send |
1254 | hidnplayr | 702 | |
1249 | hidnplayr | 703 | mov [esp+32], eax |
704 | ret |
||
1159 | hidnplayr | 705 | |
1249 | hidnplayr | 706 | .raw: |
707 | cmp [eax + SOCKET_head.Protocol], IP_PROTO_IP |
||
708 | je .raw_ip |
||
709 | |||
710 | cmp [eax + SOCKET_head.Protocol], IP_PROTO_ICMP |
||
711 | je .raw_icmp |
||
712 | |||
713 | jmp s_error |
||
714 | |||
715 | |||
716 | .raw_ip: |
||
717 | |||
1254 | hidnplayr | 718 | ;;;;;; |
719 | |||
1159 | hidnplayr | 720 | mov [esp+32], eax |
721 | ret |
||
722 | |||
723 | |||
1249 | hidnplayr | 724 | .raw_icmp: |
725 | |||
726 | ; sub ecx, ICMP_Packet.Data |
||
727 | ; mov esi, edx |
||
728 | ; push ax |
||
729 | ; call IPv4_get_frgmnt_num |
||
730 | ; mov dx, ax |
||
731 | ; pop ax |
||
732 | ; shl edx, 16 |
||
733 | ; mov dh , [esi + ICMP_Packet.Type] |
||
734 | ; mov dl , [esi + ICMP_Packet.Code] |
||
735 | ; mov di , [esi + ICMP_Packet.Identifier] |
||
736 | ; mov [eax + SOCKET.LocalPort], di ; Set localport to the identifier number, so we can receive reply's |
||
737 | ; shl edi, 16 |
||
738 | ; mov di , [esi + ICMP_Packet.SequenceNumber] |
||
739 | ; add esi, ICMP_Packet.Data |
||
740 | ; mov ebx, [eax + SOCKET.LocalIP] |
||
741 | ; mov eax, [eax + SOCKET.RemoteIP] |
||
742 | ; call ICMP_create_packet |
||
743 | |||
744 | mov [esp+32], eax |
||
1159 | hidnplayr | 745 | ret |
746 | |||
1257 | hidnplayr | 747 | ;----------------------------------------------------------------- |
1256 | clevermous | 748 | ; |
1257 | hidnplayr | 749 | ; SOCKET_get_options |
1256 | clevermous | 750 | ; |
751 | ; |
||
752 | ; IN: socket number in ecx |
||
753 | ; edx points to the options: |
||
1257 | hidnplayr | 754 | ; dd level, optname, optval, optlen |
1256 | clevermous | 755 | ; OUT: -1 on error |
756 | ; |
||
757 | ; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP. |
||
758 | ; TODO: find best way to notify that send()'ed data were acknowledged |
||
759 | ; |
||
1257 | hidnplayr | 760 | ;----------------------------------------------------------------- |
761 | align 4 |
||
1256 | clevermous | 762 | socket_get_opt: |
1257 | hidnplayr | 763 | |
1256 | clevermous | 764 | cmp dword [edx], IP_PROTO_TCP |
765 | jnz .unknown |
||
766 | cmp dword [edx+4], -2 |
||
767 | jnz .unknown |
||
768 | mov eax, [edx+12] |
||
769 | test eax, eax |
||
770 | jz .fail |
||
771 | cmp dword [eax], 4 |
||
772 | mov dword [eax], 4 |
||
773 | jb .fail |
||
1257 | hidnplayr | 774 | stdcall net_socket_num_to_addr, ecx |
1256 | clevermous | 775 | test eax, eax |
776 | jz .fail |
||
777 | ; todo: check that eax is really TCP socket |
||
778 | mov ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number] |
||
779 | mov eax, [edx+8] |
||
780 | test eax, eax |
||
781 | jz @f |
||
782 | mov [eax], ecx |
||
783 | @@: |
||
1257 | hidnplayr | 784 | mov dword [esp+32], 0 |
1256 | clevermous | 785 | ret |
786 | .fail: |
||
787 | .unknown: |
||
1257 | hidnplayr | 788 | mov dword [esp+32], -1 |
1256 | clevermous | 789 | ret |
1159 | hidnplayr | 790 | |
791 | |||
1257 | hidnplayr | 792 | ;----------------------------------------------------------------- |
1206 | hidnplayr | 793 | ; |
794 | ; SOCKET_find_free_port (local port) |
||
795 | ; |
||
796 | ; works with INET byte order |
||
797 | ; |
||
798 | ; IN: type in ecx (TCP/UDP) |
||
799 | ; OUT: bx = 0 on error, portnumber otherwise |
||
800 | ; |
||
1257 | hidnplayr | 801 | ;----------------------------------------------------------------- |
1206 | hidnplayr | 802 | align 4 |
803 | socket_find_port: |
||
1159 | hidnplayr | 804 | |
1208 | hidnplayr | 805 | DEBUGF 1,"Socket_find_free_port\n" |
1159 | hidnplayr | 806 | |
1206 | hidnplayr | 807 | cmp ecx, IP_PROTO_UDP |
808 | je .udp |
||
1159 | hidnplayr | 809 | |
1206 | hidnplayr | 810 | cmp ecx, IP_PROTO_TCP |
811 | je .tcp |
||
1159 | hidnplayr | 812 | |
1206 | hidnplayr | 813 | .udp: |
814 | mov bx, [last_UDP_port] |
||
815 | je .continue |
||
816 | |||
817 | .tcp: |
||
818 | mov bx, [last_TCP_port] |
||
819 | |||
820 | |||
821 | .continue: |
||
822 | inc bx |
||
823 | |||
824 | .check_only: |
||
825 | mov esi, net_sockets |
||
826 | |||
827 | .next_socket: |
||
1249 | hidnplayr | 828 | mov esi, [esi + SOCKET_head.NextPtr] |
1206 | hidnplayr | 829 | or esi, esi |
830 | jz .port_ok |
||
831 | |||
1249 | hidnplayr | 832 | cmp [esi + SOCKET_head.Type], ecx |
1206 | hidnplayr | 833 | jne .next_socket |
834 | |||
835 | rol bx, 8 |
||
1249 | hidnplayr | 836 | cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx |
1206 | hidnplayr | 837 | rol bx, 8 ; this doesnt change the zero flag, does it ? |
838 | jne .next_socket |
||
839 | |||
840 | cmp bx, MAX_EPHEMERAL_PORT |
||
841 | jle .continue |
||
842 | |||
843 | ; todo: WRAP! |
||
844 | ; mov [last_UDP_port], MIN_EPHEMERAL_PORT |
||
845 | .exit: |
||
846 | xor ebx, ebx |
||
847 | |||
848 | .port_ok: |
||
849 | rol bx, 8 |
||
850 | ret |
||
851 | |||
1257 | hidnplayr | 852 | |
853 | |||
854 | ;----------------------------------------------------------------- |
||
1206 | hidnplayr | 855 | ; |
856 | ; SOCKET_check_port (local port) |
||
857 | ; |
||
858 | ; works with INET byte order |
||
859 | ; |
||
860 | ; IN: type in ecx (TCP/UDP) |
||
861 | ; port to check in bx |
||
862 | ; OUT: bx = 0 on error, unchanged otherwise |
||
863 | ; |
||
1257 | hidnplayr | 864 | ;----------------------------------------------------------------- |
1206 | hidnplayr | 865 | align 4 |
866 | socket_check_port: |
||
867 | mov esi, net_sockets |
||
868 | |||
869 | .next_socket: |
||
1249 | hidnplayr | 870 | mov esi, [esi + SOCKET_head.NextPtr] |
1206 | hidnplayr | 871 | or esi, esi |
872 | jz .port_ok |
||
873 | |||
1249 | hidnplayr | 874 | cmp [esi + SOCKET_head.Type], ecx |
1206 | hidnplayr | 875 | jne .next_socket |
876 | |||
1249 | hidnplayr | 877 | cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx |
1206 | hidnplayr | 878 | jne .next_socket |
879 | |||
880 | xor ebx, ebx |
||
881 | |||
882 | .port_ok: |
||
883 | ret |
||
884 | |||
885 | |||
1257 | hidnplayr | 886 | |
887 | ;----------------------------------------------------------------- |
||
1206 | hidnplayr | 888 | ; |
889 | ; SOCKET_internal_receiver |
||
890 | ; |
||
1249 | hidnplayr | 891 | ; Updates a socket with received data |
1206 | hidnplayr | 892 | ; |
1249 | hidnplayr | 893 | ; Note: the mutex must already be set ! |
1206 | hidnplayr | 894 | ; |
1249 | hidnplayr | 895 | ; IN: eax = socket ptr |
896 | ; ecx = size |
||
897 | ; esi = pointer to buffer |
||
898 | ; edi = offset |
||
899 | ; |
||
1206 | hidnplayr | 900 | ; OUT: xxx |
901 | ; |
||
1257 | hidnplayr | 902 | ;----------------------------------------------------------------- |
1206 | hidnplayr | 903 | align 4 |
904 | socket_internal_receiver: |
||
905 | |||
1255 | hidnplayr | 906 | DEBUGF 1,"Internal socket receiver: buffer %x, offset: %x size=%u socket: %x\n", esi, edi, ecx, eax |
1206 | hidnplayr | 907 | |
1249 | hidnplayr | 908 | push edi ; offset |
909 | push ecx ; size |
||
910 | push esi ; data_ptr |
||
911 | mov esi, esp |
||
1257 | hidnplayr | 912 | add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, notify_network_event.full |
1249 | hidnplayr | 913 | DEBUGF 1,"Queued packet successfully\n" |
1257 | hidnplayr | 914 | add esp, socket_queue_entry.size |
1206 | hidnplayr | 915 | |
1249 | hidnplayr | 916 | mov [eax + SOCKET_head.lock], 0 |
1206 | hidnplayr | 917 | |
1256 | clevermous | 918 | notify_network_event: |
1206 | hidnplayr | 919 | ; flag an event to the application |
1249 | hidnplayr | 920 | mov edx, [eax + SOCKET_head.PID] ; get socket owner PID |
1206 | hidnplayr | 921 | mov ecx, 1 |
922 | mov esi, TASK_DATA + TASKDATA.pid |
||
923 | |||
924 | .next_pid: |
||
925 | cmp [esi], edx |
||
926 | je .found_pid |
||
927 | inc ecx |
||
928 | add esi, 0x20 |
||
929 | cmp ecx, [TASK_COUNT] |
||
930 | jbe .next_pid |
||
931 | ret |
||
932 | |||
933 | .found_pid: |
||
934 | shl ecx, 8 |
||
1249 | hidnplayr | 935 | or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event |
1206 | hidnplayr | 936 | mov [check_idle_semaphore], 200 |
937 | ret |
||
938 | |||
1249 | hidnplayr | 939 | .full: |
940 | DEBUGF 1,"Socket %x is full!\n",eax |
||
941 | mov [eax + SOCKET_head.lock], 0 |
||
942 | call kernel_free |
||
943 | add esp, 8 |
||
1206 | hidnplayr | 944 | ret |
945 | |||
946 | |||
947 | |||
1159 | hidnplayr | 948 | ; Allocate memory for socket data and put new socket into the list |
949 | ; Newly created socket is initialized with calling PID and number and |
||
950 | ; put into beginning of list (which is a fastest way). |
||
951 | ; |
||
952 | ; @return socket structure address in EAX |
||
953 | ; |
||
954 | proc net_socket_alloc stdcall uses ebx ecx edx edi |
||
955 | stdcall kernel_alloc, SOCKETBUFFSIZE |
||
956 | DEBUGF 1, "K : net_socket_alloc (0x%x)\n", eax |
||
957 | ; check if we can allocate needed amount of memory |
||
958 | or eax, eax |
||
959 | jz .exit |
||
960 | |||
961 | ; zero-initialize allocated memory |
||
962 | push eax |
||
963 | mov edi, eax |
||
1249 | hidnplayr | 964 | |
1159 | hidnplayr | 965 | mov ecx, SOCKETBUFFSIZE / 4 |
966 | ; cld |
||
967 | xor eax, eax |
||
968 | rep stosd |
||
969 | pop eax |
||
970 | |||
1257 | hidnplayr | 971 | init_queue (eax + SOCKET_QUEUE_LOCATION) |
1249 | hidnplayr | 972 | |
1159 | hidnplayr | 973 | ; add socket to the list by changing pointers |
974 | mov ebx, net_sockets |
||
1249 | hidnplayr | 975 | push [ebx + SOCKET_head.NextPtr] |
976 | mov [ebx + SOCKET_head.NextPtr], eax |
||
977 | mov [eax + SOCKET_head.PrevPtr], ebx |
||
1159 | hidnplayr | 978 | pop ebx |
1249 | hidnplayr | 979 | mov [eax + SOCKET_head.NextPtr], ebx |
1159 | hidnplayr | 980 | or ebx, ebx |
981 | jz @f |
||
1249 | hidnplayr | 982 | mov [ebx + SOCKET_head.PrevPtr], eax |
1159 | hidnplayr | 983 | |
984 | @@: ; set socket owner PID to the one of calling process |
||
985 | mov ebx, [TASK_BASE] |
||
986 | mov ebx, [ebx + TASKDATA.pid] |
||
1249 | hidnplayr | 987 | mov [eax + SOCKET_head.PID], ebx |
1159 | hidnplayr | 988 | |
989 | ; find first free socket number and use it |
||
990 | ;mov edx, ebx |
||
991 | mov ebx, net_sockets |
||
992 | xor ecx, ecx |
||
993 | .next_socket_number: |
||
994 | inc ecx |
||
995 | .next_socket: |
||
1249 | hidnplayr | 996 | mov ebx, [ebx + SOCKET_head.NextPtr] |
1159 | hidnplayr | 997 | or ebx, ebx |
998 | jz .last_socket_number |
||
1249 | hidnplayr | 999 | cmp [ebx + SOCKET_head.Number], ecx |
1159 | hidnplayr | 1000 | jne .next_socket |
1001 | ;cmp [ebx + SOCKET.PID], edx |
||
1002 | ;jne .next_socket |
||
1003 | mov ebx, net_sockets |
||
1004 | jmp .next_socket_number |
||
1005 | |||
1006 | .last_socket_number: |
||
1249 | hidnplayr | 1007 | mov [eax + SOCKET_head.Number], ecx |
1159 | hidnplayr | 1008 | |
1009 | .exit: |
||
1010 | ret |
||
1011 | endp |
||
1012 | |||
1013 | ; Free socket data memory and pop socket off the list |
||
1014 | ; |
||
1015 | ; @param sockAddr is a socket structure address |
||
1016 | ; |
||
1017 | proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD |
||
1018 | mov eax, [sockAddr] |
||
1019 | DEBUGF 1, "K : net_socket_free (0x%x)\n", eax |
||
1020 | ; check if we got something similar to socket structure address |
||
1021 | or eax, eax |
||
1022 | jz .error |
||
1023 | |||
1024 | ; make sure sockAddr is one of the socket addresses in the list |
||
1025 | mov ebx, net_sockets |
||
1026 | ;mov ecx, [TASK_BASE] |
||
1027 | ;mov ecx, [ecx + TASKDATA.pid] |
||
1028 | .next_socket: |
||
1249 | hidnplayr | 1029 | mov ebx, [ebx + SOCKET_head.NextPtr] |
1159 | hidnplayr | 1030 | or ebx, ebx |
1031 | jz .error |
||
1032 | cmp ebx, eax |
||
1033 | jne .next_socket |
||
1034 | ;cmp [ebx + SOCKET.PID], ecx |
||
1035 | ;jne .next_socket |
||
1036 | |||
1037 | ; okay, we found the correct one |
||
1038 | ; remove it from the list first, changing pointers |
||
1249 | hidnplayr | 1039 | mov ebx, [eax + SOCKET_head.NextPtr] |
1040 | mov eax, [eax + SOCKET_head.PrevPtr] |
||
1041 | mov [eax + SOCKET_head.NextPtr], ebx |
||
1159 | hidnplayr | 1042 | or ebx, ebx |
1043 | jz @f |
||
1249 | hidnplayr | 1044 | mov [ebx + SOCKET_head.PrevPtr], eax |
1159 | hidnplayr | 1045 | |
1249 | hidnplayr | 1046 | lea ebx, [eax + SOCKET_head.lock] |
1047 | call wait_mutex |
||
1048 | |||
1159 | hidnplayr | 1049 | @@: ; and finally free the memory structure used |
1050 | stdcall kernel_free, [sockAddr] |
||
1051 | ret |
||
1052 | |||
1053 | .error: |
||
1054 | DEBUGF 1, "K : failed\n" |
||
1055 | ret |
||
1056 | endp |
||
1057 | |||
1058 | ; Get socket structure address by its number |
||
1059 | ; Scan through sockets list to find the socket with specified number. |
||
1060 | ; This proc uses SOCKET.PID indirectly to check if socket is owned by |
||
1061 | ; calling process. |
||
1062 | ; |
||
1063 | ; @param sockNum is a socket number |
||
1064 | ; @return socket structure address or 0 (not found) in EAX |
||
1065 | ; |
||
1066 | proc net_socket_num_to_addr stdcall uses ebx ecx, sockNum:DWORD |
||
1067 | mov eax, [sockNum] |
||
1068 | ; check if we got something similar to socket number |
||
1069 | or eax, eax |
||
1070 | jz .error |
||
1071 | |||
1072 | ; scan through sockets list |
||
1073 | mov ebx, net_sockets |
||
1074 | ;mov ecx, [TASK_BASE] |
||
1075 | ;mov ecx, [ecx + TASKDATA.pid] |
||
1076 | .next_socket: |
||
1249 | hidnplayr | 1077 | mov ebx, [ebx + SOCKET_head.NextPtr] |
1159 | hidnplayr | 1078 | or ebx, ebx |
1079 | jz .error |
||
1249 | hidnplayr | 1080 | cmp [ebx + SOCKET_head.Number], eax |
1159 | hidnplayr | 1081 | jne .next_socket |
1082 | ;cmp [ebx + SOCKET.PID], ecx |
||
1083 | ;jne .next_socket |
||
1084 | |||
1085 | ; okay, we found the correct one |
||
1086 | mov eax, ebx |
||
1087 | ret |
||
1088 | |||
1089 | .error: |
||
1090 | xor eax, eax |
||
1091 | ret |
||
1092 | endp |
||
1093 | |||
1094 | ; Get socket number by its structure address |
||
1095 | ; Scan through sockets list to find the socket with specified address. |
||
1096 | ; This proc uses SOCKET.PID indirectly to check if socket is owned by |
||
1097 | ; calling process. |
||
1098 | ; |
||
1099 | ; @param sockAddr is a socket structure address |
||
1100 | ; @return socket number (SOCKET.Number) or 0 (not found) in EAX |
||
1101 | ; |
||
1102 | proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD |
||
1103 | mov eax, [sockAddr] |
||
1104 | ; check if we got something similar to socket structure address |
||
1105 | or eax, eax |
||
1106 | jz .error |
||
1107 | |||
1108 | ; scan through sockets list |
||
1109 | mov ebx, net_sockets |
||
1110 | ;mov ecx, [TASK_BASE] |
||
1111 | ;mov ecx, [ecx + TASKDATA.pid] |
||
1112 | .next_socket: |
||
1249 | hidnplayr | 1113 | mov ebx, [ebx + SOCKET_head.NextPtr] |
1159 | hidnplayr | 1114 | or ebx, ebx |
1115 | jz .error |
||
1116 | cmp ebx, eax |
||
1117 | jne .next_socket |
||
1118 | ;cmp [ebx + SOCKET.PID], ecx |
||
1119 | ;jne .next_socket |
||
1120 | |||
1121 | ; okay, we found the correct one |
||
1249 | hidnplayr | 1122 | mov eax, [ebx + SOCKET_head.Number] |
1159 | hidnplayr | 1123 | ret |
1124 | |||
1125 | .error: |
||
1126 | xor eax, eax |
||
1127 | ret |
||
1128 | endp |