Subversion Repositories Kolibri OS

Rev

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

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