Subversion Repositories Kolibri OS

Rev

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

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