Subversion Repositories Kolibri OS

Rev

Rev 9976 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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