Subversion Repositories Kolibri OS

Rev

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

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