Subversion Repositories Kolibri OS

Rev

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

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