Subversion Repositories Kolibri OS

Rev

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

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