Subversion Repositories Kolibri OS

Rev

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

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