Subversion Repositories Kolibri OS

Rev

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

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