Subversion Repositories Kolibri OS

Rev

Rev 2894 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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