Subversion Repositories Kolibri OS

Rev

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

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