Subversion Repositories Kolibri OS

Rev

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

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