Subversion Repositories Kolibri OS

Rev

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

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