Subversion Repositories Kolibri OS

Rev

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

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