Subversion Repositories Kolibri OS

Rev

Rev 2302 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2302 Rev 2303
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2011. 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
;;    Written by hidnplayr@kolibrios.org,                          ;;
6
;;    Written by hidnplayr@kolibrios.org,                          ;;
7
;;     and Clevermouse.                                            ;;
7
;;     and Clevermouse.                                            ;;
8
;;                                                                 ;;
8
;;                                                                 ;;
9
;;       Based on code by mike.dld                                 ;;
9
;;       Based on code by mike.dld                                 ;;
10
;;                                                                 ;;
10
;;                                                                 ;;
11
;;         GNU GENERAL PUBLIC LICENSE                              ;;
11
;;         GNU GENERAL PUBLIC LICENSE                              ;;
12
;;          Version 2, June 1991                                   ;;
12
;;          Version 2, June 1991                                   ;;
13
;;                                                                 ;;
13
;;                                                                 ;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
 
15
 
16
$Revision: 2302 $
16
$Revision: 2303 $
17
 
17
 
18
 
18
 
19
virtual at 0
19
virtual at 0
20
 
20
 
21
	SOCKET:
21
	SOCKET:
22
	.NextPtr		dd ? ; pointer to next socket in list
22
	.NextPtr		dd ? ; pointer to next socket in list
23
	.PrevPtr		dd ? ; pointer to previous socket in list
23
	.PrevPtr		dd ? ; pointer to previous socket in list
24
	.Number 		dd ? ; socket number
24
	.Number 		dd ? ; socket number
25
 
25
 
26
	.lock			dd ? ; lock mutex
26
	.lock			dd ? ; lock mutex
27
 
27
 
28
	.PID			dd ? ; application process id
28
	.PID			dd ? ; application process id
29
	.Domain 		dd ? ; INET/UNIX/..
29
	.Domain 		dd ? ; INET/UNIX/..
30
	.Type			dd ? ; RAW/STREAM/DGRAP
30
	.Type			dd ? ; RAW/STREAM/DGRAP
31
	.Protocol		dd ? ; ICMP/IPv4/ARP/TCP/UDP
31
	.Protocol		dd ? ; ICMP/IPv4/ARP/TCP/UDP
32
	.errorcode		dd ?
32
	.errorcode		dd ?
33
 
33
 
34
	.options		dd ?
34
	.options		dd ?
35
	.state			dd ?
35
	.state			dd ?
36
	.backlog		dw ? ; how many incomming connections that can be queued
36
	.backlog		dw ? ; how many incomming connections that can be queued
37
 
37
 
38
	.snd_proc		dd ?
38
	.snd_proc		dd ?
39
	.rcv_proc		dd ?
39
	.rcv_proc		dd ?
40
 
40
 
41
	.end:
41
	.end:
42
end virtual
42
end virtual
43
 
43
 
44
virtual at SOCKET.end
44
virtual at SOCKET.end
45
 
45
 
46
	IP_SOCKET:
46
	IP_SOCKET:
47
	.LocalIP		rd 4
47
	.LocalIP		rd 4
48
	.RemoteIP		rd 4
48
	.RemoteIP		rd 4
49
 
49
 
50
	.end:
50
	.end:
51
end virtual
51
end virtual
52
 
52
 
53
virtual at IP_SOCKET.end
53
virtual at IP_SOCKET.end
54
 
54
 
55
	TCP_SOCKET:
55
	TCP_SOCKET:
56
 
56
 
57
	.LocalPort		dw ?
57
	.LocalPort		dw ?
58
	.RemotePort		dw ?
58
	.RemotePort		dw ?
59
 
59
 
60
	.t_state		dd ? ; TCB state
60
	.t_state		dd ? ; TCB state
61
	.t_rxtshift		dd ?
61
	.t_rxtshift		dd ?
62
	.t_rxtcur		dd ?
62
	.t_rxtcur		dd ?
63
	.t_dupacks		dd ?
63
	.t_dupacks		dd ?
64
	.t_maxseg		dd ?
64
	.t_maxseg		dd ?
65
	.t_force		dd ?
65
	.t_force		dd ?
66
	.t_flags		dd ?
66
	.t_flags		dd ?
67
 
67
 
68
;---------------
68
;---------------
69
; RFC783 page 21
69
; RFC783 page 21
70
 
70
 
71
; send sequence
71
; send sequence
72
	.SND_UNA		dd ? ; sequence number of unack'ed sent Packets
72
	.SND_UNA		dd ? ; sequence number of unack'ed sent Packets
73
	.SND_NXT		dd ? ; next send sequence number to use
73
	.SND_NXT		dd ? ; next send sequence number to use
74
	.SND_UP 		dd ?
74
	.SND_UP 		dd ?
75
	.SND_WL1		dd ? ; window minus one
75
	.SND_WL1		dd ? ; window minus one
76
	.SND_WL2		dd ? ;
76
	.SND_WL2		dd ? ;
77
	.ISS			dd ? ; initial send sequence number
77
	.ISS			dd ? ; initial send sequence number
78
	.SND_WND		dd ? ; send window
78
	.SND_WND		dd ? ; send window
79
 
79
 
80
; receive sequence
80
; receive sequence
81
	.RCV_WND		dw ? ; receive window
81
	.RCV_WND		dw ? ; receive window
82
	.RCV_NXT		dd ? ; next receive sequence number to use
82
	.RCV_NXT		dd ? ; next receive sequence number to use
83
	.RCV_UP 		dd ?
83
	.RCV_UP 		dd ?
84
	.IRS			dd ? ; initial receive sequence number
84
	.IRS			dd ? ; initial receive sequence number
85
 
85
 
86
;---------------------
86
;---------------------
87
; Additional variables
87
; Additional variables
88
 
88
 
89
; receive variables
89
; receive variables
90
	.RCV_ADV		dd ?
90
	.RCV_ADV		dd ?
91
 
91
 
92
; retransmit variables
92
; retransmit variables
93
	.SND_MAX		dd ?
93
	.SND_MAX		dd ?
94
 
94
 
95
; congestion control
95
; congestion control
96
	.SND_CWND		dd ?
96
	.SND_CWND		dd ?
97
	.SND_SSTHRESH		dd ?
97
	.SND_SSTHRESH		dd ?
98
 
98
 
99
;----------------------
99
;----------------------
100
; Transmit timing stuff
100
; Transmit timing stuff
101
	.t_idle 		dd ?
101
	.t_idle 		dd ?
102
	.t_rtt			dd ?
102
	.t_rtt			dd ?
103
	.t_rtseq		dd ?
103
	.t_rtseq		dd ?
104
	.t_srtt 		dd ?
104
	.t_srtt 		dd ?
105
	.t_rttvar		dd ?
105
	.t_rttvar		dd ?
106
	.t_rttmin		dd ?
106
	.t_rttmin		dd ?
107
	.max_sndwnd		dd ?
107
	.max_sndwnd		dd ?
108
 
108
 
109
;-----------------
109
;-----------------
110
; Out-of-band data
110
; Out-of-band data
111
	.t_oobflags		dd ?
111
	.t_oobflags		dd ?
112
	.t_iobc 		dd ?
112
	.t_iobc 		dd ?
113
	.t_softerror		dd ?
113
	.t_softerror		dd ?
114
 
114
 
115
 
115
 
116
;---------
116
;---------
117
; RFC 1323
117
; RFC 1323
118
	.SND_SCALE		db ? ; Scale factor
118
	.SND_SCALE		db ? ; Scale factor
119
	.RCV_SCALE		db ?
119
	.RCV_SCALE		db ?
120
	.request_r_scale	db ?
120
	.request_r_scale	db ?
121
	.requested_s_scale	dd ?
121
	.requested_s_scale	dd ?
122
 
122
 
123
	.ts_recent		dd ?
123
	.ts_recent		dd ?
124
	.ts_recent_age		dd ?
124
	.ts_recent_age		dd ?
125
	.last_ack_sent		dd ?
125
	.last_ack_sent		dd ?
126
 
126
 
127
 
127
 
128
;-------
128
;-------
129
; Timers
129
; Timers
130
	.timer_retransmission	dw ? ; rexmt
130
	.timer_retransmission	dw ? ; rexmt
131
	.timer_persist		dw ?
131
	.timer_persist		dw ?
132
	.timer_keepalive	dw ? ; keepalive/syn timeout
132
	.timer_keepalive	dw ? ; keepalive/syn timeout
133
	.timer_timed_wait	dw ? ; also used as 2msl timer
133
	.timer_timed_wait	dw ? ; also used as 2msl timer
134
 
134
 
135
	.end:
135
	.end:
136
end virtual
136
end virtual
137
 
137
 
138
virtual at IP_SOCKET.end
138
virtual at IP_SOCKET.end
139
 
139
 
140
	UDP_SOCKET:
140
	UDP_SOCKET:
141
 
141
 
142
	.LocalPort		dw ?
142
	.LocalPort		dw ?
143
	.RemotePort		dw ?
143
	.RemotePort		dw ?
144
	.firstpacket		db ?
144
	.firstpacket		db ?
145
 
145
 
146
	.end:
146
	.end:
147
end virtual
147
end virtual
148
 
148
 
149
virtual at IP_SOCKET.end
149
virtual at IP_SOCKET.end
150
 
150
 
151
	ICMP_SOCKET:
151
	ICMP_SOCKET:
152
 
152
 
153
	.Identifier		dw ?
153
	.Identifier		dw ?
154
 
154
 
155
	.end:
155
	.end:
156
end virtual
156
end virtual
157
 
157
 
158
struc	RING_BUFFER {
158
struc	RING_BUFFER {
159
	.start_ptr		dd ? ; Pointer to start of buffer
159
	.start_ptr		dd ? ; Pointer to start of buffer
160
	.end_ptr		dd ? ; pointer to end of buffer
160
	.end_ptr		dd ? ; pointer to end of buffer
161
	.read_ptr		dd ? ; Read pointer
161
	.read_ptr		dd ? ; Read pointer
162
	.write_ptr		dd ? ; Write pointer
162
	.write_ptr		dd ? ; Write pointer
163
	.size			dd ? ; Number of bytes buffered
163
	.size			dd ? ; Number of bytes buffered
164
	.end:
164
	.end:
165
}
165
}
166
 
166
 
167
virtual at 0
167
virtual at 0
168
 
168
 
169
	RING_BUFFER	RING_BUFFER
169
	RING_BUFFER	RING_BUFFER
170
 
170
 
171
end virtual
171
end virtual
172
 
172
 
173
virtual at TCP_SOCKET.end
173
virtual at TCP_SOCKET.end
174
 
174
 
175
 STREAM_SOCKET:
175
 STREAM_SOCKET:
176
	.rcv	rd     RING_BUFFER.end/4
176
	.rcv	rd     RING_BUFFER.end/4
177
	.snd	rd     RING_BUFFER.end/4
177
	.snd	rd     RING_BUFFER.end/4
178
	.end:
178
	.end:
179
 
179
 
180
end virtual
180
end virtual
181
 
181
 
182
struct	socket_queue_entry
182
struct	socket_queue_entry
183
	.data_ptr	dd ?
183
	.data_ptr	dd ?
184
	.buf_ptr	dd ?
184
	.buf_ptr	dd ?
185
	.data_size	dd ?
185
	.data_size	dd ?
186
	.size:
186
	.size:
187
ends
187
ends
188
 
188
 
189
 
189
 
190
SOCKETBUFFSIZE		equ 4096     ; in bytes
190
SOCKETBUFFSIZE		equ 4096     ; in bytes
191
 
191
 
192
SOCKET_QUEUE_SIZE	equ 10	     ; maximum number ofincoming packets queued for 1 socket
192
SOCKET_QUEUE_SIZE	equ 10	     ; maximum number ofincoming packets queued for 1 socket
193
; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start
193
; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start
194
SOCKET_QUEUE_LOCATION	equ (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*socket_queue_entry.size - queue.data)
194
SOCKET_QUEUE_LOCATION	equ (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*socket_queue_entry.size - queue.data)
195
 
195
 
196
uglobal
196
uglobal
197
	net_sockets	rd 4
197
	net_sockets	rd 4
198
	last_socket_num dd ?
198
	last_socket_num dd ?
199
	last_UDP_port	dw ? ; These values give the number of the last used ephemeral port
199
	last_UDP_port	dw ? ; These values give the number of the last used ephemeral port
200
	last_TCP_port	dw ? ;
200
	last_TCP_port	dw ? ;
201
endg
201
endg
202
 
202
 
203
 
203
 
204
;-----------------------------------------------------------------
204
;-----------------------------------------------------------------
205
;
205
;
206
; SOCKET_init
206
; SOCKET_init
207
;
207
;
208
;-----------------------------------------------------------------
208
;-----------------------------------------------------------------
209
macro	SOCKET_init {
209
macro	SOCKET_init {
210
 
210
 
211
	xor	eax, eax
211
	xor	eax, eax
212
	mov	edi, net_sockets
212
	mov	edi, net_sockets
213
	mov	ecx, 5
213
	mov	ecx, 5
214
	rep	stosd
214
	rep	stosd
215
 
215
 
216
       @@:
216
       @@:
217
	pseudo_random eax
217
	pseudo_random eax
218
	cmp	ax, MIN_EPHEMERAL_PORT
218
	cmp	ax, MIN_EPHEMERAL_PORT
219
	jb	@r
219
	jb	@r
220
	cmp	ax, MAX_EPHEMERAL_PORT
220
	cmp	ax, MAX_EPHEMERAL_PORT
221
	ja	@r
221
	ja	@r
222
	mov	[last_UDP_port], ax
222
	mov	[last_UDP_port], ax
223
 
223
 
224
       @@:
224
       @@:
225
	pseudo_random eax
225
	pseudo_random eax
226
	cmp	ax, MIN_EPHEMERAL_PORT
226
	cmp	ax, MIN_EPHEMERAL_PORT
227
	jb	@r
227
	jb	@r
228
	cmp	ax, MAX_EPHEMERAL_PORT
228
	cmp	ax, MAX_EPHEMERAL_PORT
229
	ja	@r
229
	ja	@r
230
	mov	[last_TCP_port], ax
230
	mov	[last_TCP_port], ax
231
 
231
 
232
}
232
}
233
 
233
 
234
 
234
 
235
;-----------------------------------------------------------------
235
;-----------------------------------------------------------------
236
;
236
;
237
; Socket API (function 74)
237
; Socket API (function 74)
238
;
238
;
239
;-----------------------------------------------------------------
239
;-----------------------------------------------------------------
240
align 16
240
align 16
241
sock_sysfn_table:
241
sock_sysfn_table:
242
	dd	SOCKET_open	; 0
242
	dd	SOCKET_open	; 0
243
	dd	SOCKET_close	; 1
243
	dd	SOCKET_close	; 1
244
	dd	SOCKET_bind	; 2
244
	dd	SOCKET_bind	; 2
245
	dd	SOCKET_listen	; 3
245
	dd	SOCKET_listen	; 3
246
	dd	SOCKET_connect	; 4
246
	dd	SOCKET_connect	; 4
247
	dd	SOCKET_accept	; 5
247
	dd	SOCKET_accept	; 5
248
	dd	SOCKET_send	; 6
248
	dd	SOCKET_send	; 6
249
	dd	SOCKET_receive	; 7
249
	dd	SOCKET_receive	; 7
250
	dd	SOCKET_set_opt	; 8
250
	dd	SOCKET_set_opt	; 8
251
	dd	SOCKET_get_opt	; 9
251
	dd	SOCKET_get_opt	; 9
252
 
252
 
253
SOCKET_SYSFUNCS = ($ - sock_sysfn_table)/4
253
SOCKET_SYSFUNCS = ($ - sock_sysfn_table)/4
254
 
254
 
255
 
255
 
256
align 4
256
align 4
257
sys_socket:
257
sys_socket:
258
	cmp	ebx, SOCKET_SYSFUNCS-1
258
	cmp	ebx, SOCKET_SYSFUNCS-1
259
	ja	@f
259
	ja	@f
260
	jmp	dword [sock_sysfn_table + 4*ebx]
260
	jmp	dword [sock_sysfn_table + 4*ebx]
261
       @@:
261
       @@:
262
	cmp	ebx, 255
262
	cmp	ebx, 255
263
	jz	SOCKET_debug
263
	jz	SOCKET_debug
264
 
264
 
265
s_error:
265
s_error:
266
	DEBUGF	1,"socket error\n"
266
	DEBUGF	1,"socket error\n"
267
	mov	dword [esp+32], -1
267
	mov	dword [esp+32], -1
268
 
268
 
269
	ret
269
	ret
270
 
270
 
271
 
271
 
272
 
272
 
273
;-----------------------------------------------------------------
273
;-----------------------------------------------------------------
274
;
274
;
275
; SOCKET_open
275
; SOCKET_open
276
;
276
;
277
;  IN:  domain in ecx
277
;  IN:  domain in ecx
278
;       type in edx
278
;       type in edx
279
;       protocol in esi
279
;       protocol in esi
280
;  OUT: eax is socket num, -1 on error
280
;  OUT: eax is socket num, -1 on error
281
;
281
;
282
;-----------------------------------------------------------------
282
;-----------------------------------------------------------------
283
align 4
283
align 4
284
SOCKET_open:
284
SOCKET_open:
285
 
285
 
286
	DEBUGF	1,"SOCKET_open: domain: %u, type: %u protocol: %x\n", ecx, edx, esi
286
	DEBUGF	1,"SOCKET_open: domain: %u, type: %u protocol: %x\n", ecx, edx, esi
287
 
287
 
288
	call	SOCKET_alloc
288
	call	SOCKET_alloc
289
	jz	s_error
289
	jz	s_error
290
 
290
 
291
	mov	[esp+32], edi			; return socketnumber
291
	mov	[esp+32], edi			; return socketnumber
292
 
292
 
293
	mov	[eax + SOCKET.Domain], ecx
293
	mov	[eax + SOCKET.Domain], ecx
294
	mov	[eax + SOCKET.Type], edx
294
	mov	[eax + SOCKET.Type], edx
295
	mov	[eax + SOCKET.Protocol], esi
295
	mov	[eax + SOCKET.Protocol], esi
296
 
296
 
297
	cmp	ecx, AF_INET4
297
	cmp	ecx, AF_INET4
298
	jne	.no_inet4
298
	jne	.no_inet4
299
 
299
 
300
	cmp	edx, SOCK_DGRAM
300
	cmp	edx, SOCK_DGRAM
301
	je	.udp
301
	je	.udp
302
 
302
 
303
	cmp	edx, SOCK_STREAM
303
	cmp	edx, SOCK_STREAM
304
	je	.tcp
304
	je	.tcp
305
 
305
 
306
	cmp	edx, SOCK_RAW
306
	cmp	edx, SOCK_RAW
307
	je	.raw
307
	je	.raw
308
 
308
 
309
  .no_inet4:
309
  .no_inet4:
310
	ret
310
	ret
311
 
311
 
312
align 4
312
align 4
313
  .raw:
313
  .raw:
314
	test	esi, esi       ; IP_PROTO_IP
314
	test	esi, esi       ; IP_PROTO_IP
315
	jz	.ip
315
	jz	.ip
316
 
316
 
317
	cmp	esi, IP_PROTO_ICMP
317
	cmp	esi, IP_PROTO_ICMP
318
	je	.icmp
318
	je	.icmp
319
 
319
 
320
	cmp	esi, IP_PROTO_UDP
320
	cmp	esi, IP_PROTO_UDP
321
	je	.udp
321
	je	.udp
322
 
322
 
323
	cmp	esi, IP_PROTO_TCP
323
	cmp	esi, IP_PROTO_TCP
324
	je	.tcp
324
	je	.tcp
325
 
325
 
326
	ret
326
	ret
327
 
327
 
328
align 4
328
align 4
329
  .udp:
329
  .udp:
330
	mov	[eax + SOCKET.Protocol], IP_PROTO_UDP
330
	mov	[eax + SOCKET.Protocol], IP_PROTO_UDP
331
	mov	[eax + SOCKET.snd_proc], SOCKET_send_udp
331
	mov	[eax + SOCKET.snd_proc], SOCKET_send_udp
332
	mov	[eax + SOCKET.rcv_proc], SOCKET_receive_dgram
332
	mov	[eax + SOCKET.rcv_proc], SOCKET_receive_dgram
333
	ret
333
	ret
334
 
334
 
335
align 4
335
align 4
336
  .tcp:
336
  .tcp:
337
	mov	[eax + SOCKET.Protocol], IP_PROTO_TCP
337
	mov	[eax + SOCKET.Protocol], IP_PROTO_TCP
338
	mov	[eax + SOCKET.snd_proc], SOCKET_send_tcp
338
	mov	[eax + SOCKET.snd_proc], SOCKET_send_tcp
339
	mov	[eax + SOCKET.rcv_proc], SOCKET_receive_tcp
339
	mov	[eax + SOCKET.rcv_proc], SOCKET_receive_tcp
340
 
340
 
341
 
341
 
342
	mov	[eax + TCP_SOCKET.t_maxseg], 1480	;;;;; FIXME
342
	mov	[eax + TCP_SOCKET.t_maxseg], 1480	;;;;; FIXME
343
	ret
343
	ret
344
 
344
 
345
 
345
 
346
align 4
346
align 4
347
  .ip:
347
  .ip:
348
	mov	[eax + SOCKET.snd_proc], SOCKET_send_ip
348
	mov	[eax + SOCKET.snd_proc], SOCKET_send_ip
349
	mov	[eax + SOCKET.rcv_proc], SOCKET_receive_dgram
349
	mov	[eax + SOCKET.rcv_proc], SOCKET_receive_dgram
350
	ret
350
	ret
351
 
351
 
352
 
352
 
353
align 4
353
align 4
354
  .icmp:
354
  .icmp:
355
	mov	[eax + SOCKET.snd_proc], SOCKET_send_icmp
355
	mov	[eax + SOCKET.snd_proc], SOCKET_send_icmp
356
	mov	[eax + SOCKET.rcv_proc], SOCKET_receive_dgram
356
	mov	[eax + SOCKET.rcv_proc], SOCKET_receive_dgram
357
	ret
357
	ret
358
 
358
 
359
 
359
 
360
 
360
 
361
;-----------------------------------------------------------------
361
;-----------------------------------------------------------------
362
;
362
;
363
; SOCKET_bind
363
; SOCKET_bind
364
;
364
;
365
;  IN:  socket number in ecx
365
;  IN:  socket number in ecx
366
;       pointer to sockaddr struct in edx
366
;       pointer to sockaddr struct in edx
367
;       length of that struct in esi
367
;       length of that struct in esi
368
;  OUT: 0 on success
368
;  OUT: 0 on success
369
;
369
;
370
;-----------------------------------------------------------------
370
;-----------------------------------------------------------------
371
align 4
371
align 4
372
SOCKET_bind:
372
SOCKET_bind:
373
 
373
 
374
	DEBUGF	1,"socket_bind: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
374
	DEBUGF	1,"socket_bind: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
375
 
375
 
376
	call	SOCKET_num_to_ptr
376
	call	SOCKET_num_to_ptr
377
	jz	s_error
377
	jz	s_error
378
 
378
 
379
	cmp	esi, 2
379
	cmp	esi, 2
380
	jb	s_error
380
	jb	s_error
381
 
381
 
382
	cmp	word [edx], AF_INET4
382
	cmp	word [edx], AF_INET4
383
	je	.af_inet4
383
	je	.af_inet4
384
 
384
 
385
	cmp	word [edx], AF_UNIX
385
	cmp	word [edx], AF_UNIX
386
	je	.af_unix
386
	je	.af_unix
387
 
387
 
388
	jmp	s_error
388
	jmp	s_error
389
 
389
 
390
  .af_unix:
390
  .af_unix:
391
	; TODO: write code here
391
	; TODO: write code here
392
 
392
 
393
	mov	dword [esp+32], 0
393
	mov	dword [esp+32], 0
394
	ret
394
	ret
395
 
395
 
396
  .af_inet4:
396
  .af_inet4:
397
 
397
 
398
	DEBUGF	1,"af_inet4\n"
398
	DEBUGF	1,"af_inet4\n"
399
 
399
 
400
	cmp	esi, 6
400
	cmp	esi, 6
401
	jb	s_error
401
	jb	s_error
402
 
402
 
403
	pushw	[edx + 2]
403
	pushw	[edx + 2]
404
	pop	[eax + UDP_SOCKET.LocalPort]
404
	pop	[eax + UDP_SOCKET.LocalPort]
405
 
405
 
406
	pushd	[edx + 4]
406
	pushd	[edx + 4]
407
	pop	[eax + IP_SOCKET.LocalIP]
407
	pop	[eax + IP_SOCKET.LocalIP]
408
 
408
 
409
	DEBUGF	1,"local ip: %u.%u.%u.%u\n",\
409
	DEBUGF	1,"local ip: %u.%u.%u.%u\n",\
410
	[eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
410
	[eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
411
	[eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1
411
	[eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1
412
 
412
 
413
	mov	dword [esp+32], 0
413
	mov	dword [esp+32], 0
414
	ret
414
	ret
415
 
415
 
416
 
416
 
417
 
417
 
418
 
418
 
419
;-----------------------------------------------------------------
419
;-----------------------------------------------------------------
420
;
420
;
421
; SOCKET_connect
421
; SOCKET_connect
422
;
422
;
423
;  IN:  socket number in ecx
423
;  IN:  socket number in ecx
424
;       pointer to sockaddr struct in edx
424
;       pointer to sockaddr struct in edx
425
;       length of that struct in esi
425
;       length of that struct in esi
426
;  OUT: 0 on success
426
;  OUT: 0 on success
427
;
427
;
428
;-----------------------------------------------------------------
428
;-----------------------------------------------------------------
429
align 4
429
align 4
430
SOCKET_connect:
430
SOCKET_connect:
431
 
431
 
432
	DEBUGF	1,"SOCKET_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
432
	DEBUGF	1,"SOCKET_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
433
 
433
 
434
	call	SOCKET_num_to_ptr
434
	call	SOCKET_num_to_ptr
435
	jz	s_error
435
	jz	s_error
436
 
436
 
437
	cmp	esi, 8
437
	cmp	esi, 8
438
	jb	s_error
438
	jb	s_error
439
 
439
 
440
	cmp	word [edx], AF_INET4
440
	cmp	word [edx], AF_INET4
441
	je	.af_inet4
441
	je	.af_inet4
442
 
442
 
443
	jmp	s_error
443
	jmp	s_error
444
 
444
 
445
  .af_inet4:
445
  .af_inet4:
446
	cmp	[eax + IP_SOCKET.LocalIP], 0
446
	cmp	[eax + IP_SOCKET.LocalIP], 0
447
	jne	@f
447
	jne	@f
448
	push	[IP_LIST]
448
	push	[IP_LIST]
449
	pop	[eax + IP_SOCKET.LocalIP]
449
	pop	[eax + IP_SOCKET.LocalIP]
450
       @@:
450
       @@:
451
 
451
 
452
	cmp	[eax + SOCKET.Protocol], IP_PROTO_UDP
452
	cmp	[eax + SOCKET.Protocol], IP_PROTO_UDP
453
	je	.udp
453
	je	.udp
454
 
454
 
455
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
455
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
456
	je	.tcp
456
	je	.tcp
457
 
457
 
458
	cmp	[eax + SOCKET.Protocol], IP_PROTO_IP
458
	cmp	[eax + SOCKET.Protocol], IP_PROTO_IP
459
	je	.ip
459
	je	.ip
460
 
460
 
461
	cmp	[eax + SOCKET.Protocol], IP_PROTO_ICMP
461
	cmp	[eax + SOCKET.Protocol], IP_PROTO_ICMP
462
	je	.ip
462
	je	.ip
463
 
463
 
464
	jmp	s_error
464
	jmp	s_error
465
 
465
 
466
align 4
466
align 4
467
  .udp:
467
  .udp:
468
	lea	ebx, [eax + SOCKET.lock]
468
	lea	ebx, [eax + SOCKET.lock]
469
	call	wait_mutex
469
	call	wait_mutex
470
 
470
 
471
	pushw	[edx + 2]
471
	pushw	[edx + 2]
472
	pop	[eax + UDP_SOCKET.RemotePort]
472
	pop	[eax + UDP_SOCKET.RemotePort]
473
 
473
 
474
	pushd	[edx + 4]
474
	pushd	[edx + 4]
475
	pop	[eax + IP_SOCKET.RemoteIP]
475
	pop	[eax + IP_SOCKET.RemoteIP]
476
 
476
 
477
	cmp	[eax + UDP_SOCKET.LocalPort], 0
477
	cmp	[eax + UDP_SOCKET.LocalPort], 0
478
	jne	@f
478
	jne	@f
479
	call	SOCKET_find_port
479
	call	SOCKET_find_port
480
       @@:
480
       @@:
481
 
481
 
482
	mov	[eax + UDP_SOCKET.firstpacket], 0
482
	mov	[eax + UDP_SOCKET.firstpacket], 0
483
 
483
 
484
	push	eax
484
	push	eax
485
	init_queue (eax + SOCKET_QUEUE_LOCATION)	; Set up data receiving queue
485
	init_queue (eax + SOCKET_QUEUE_LOCATION)	; Set up data receiving queue
486
	pop	eax
486
	pop	eax
487
 
487
 
488
	mov	[eax + SOCKET.lock], 0
488
	mov	[eax + SOCKET.lock], 0
489
	mov	dword [esp+32], 0
489
	mov	dword [esp+32], 0
490
	ret
490
	ret
491
 
491
 
492
align 4
492
align 4
493
  .tcp:
493
  .tcp:
494
	lea	ebx, [eax + SOCKET.lock]
494
	lea	ebx, [eax + SOCKET.lock]
495
	call	wait_mutex
495
	call	wait_mutex
496
 
496
 
497
	pushw	[edx + 2]
497
	pushw	[edx + 2]
498
	pop	[eax + TCP_SOCKET.RemotePort]
498
	pop	[eax + TCP_SOCKET.RemotePort]
499
 
499
 
500
	pushd	[edx + 4]
500
	pushd	[edx + 4]
501
	pop	[eax + IP_SOCKET.RemoteIP]
501
	pop	[eax + IP_SOCKET.RemoteIP]
502
 
502
 
503
	cmp	[eax + TCP_SOCKET.LocalPort], 0
503
	cmp	[eax + TCP_SOCKET.LocalPort], 0
504
	jne	@f
504
	jne	@f
505
	call	SOCKET_find_port
505
	call	SOCKET_find_port
506
       @@:
506
       @@:
507
 
507
 
508
	mov	[eax + TCP_SOCKET.timer_persist], 0
508
	mov	[eax + TCP_SOCKET.timer_persist], 0
509
	mov	[eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
509
	mov	[eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
510
	push	[TCP_sequence_num]
510
	push	[TCP_sequence_num]
511
	add	[TCP_sequence_num], 6400
511
	add	[TCP_sequence_num], 6400
512
	pop	[eax + TCP_SOCKET.ISS]
512
	pop	[eax + TCP_SOCKET.ISS]
513
	mov	[eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
513
	mov	[eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
514
 
514
 
515
	TCP_sendseqinit eax
515
	TCP_sendseqinit eax
516
 
516
 
517
;        mov     [ebx + TCP_SOCKET.timer_retransmission],   ;; todo: create macro to set retransmission timer
517
;        mov     [ebx + TCP_SOCKET.timer_retransmission],   ;; todo: create macro to set retransmission timer
518
 
518
 
519
	mov	ebx, eax
519
	mov	ebx, eax
520
 
520
 
521
	lea	eax, [ebx + STREAM_SOCKET.snd]
521
	lea	eax, [ebx + STREAM_SOCKET.snd]
522
	call	SOCKET_ring_create
522
	call	SOCKET_ring_create
523
 
523
 
524
	lea	eax, [ebx + STREAM_SOCKET.rcv]
524
	lea	eax, [ebx + STREAM_SOCKET.rcv]
525
	call	SOCKET_ring_create
525
	call	SOCKET_ring_create
526
 
526
 
527
	mov	[ebx + SOCKET.lock], 0
527
	mov	[ebx + SOCKET.lock], 0
528
 
528
 
529
	mov	eax, ebx
529
	mov	eax, ebx
530
	call	TCP_output
530
	call	TCP_output
531
 
531
 
532
	mov	dword [esp+32], 0
532
	mov	dword [esp+32], 0
533
	ret
533
	ret
534
 
534
 
535
align 4
535
align 4
536
  .ip:
536
  .ip:
537
	lea	ebx, [eax + SOCKET.lock]
537
	lea	ebx, [eax + SOCKET.lock]
538
	call	wait_mutex
538
	call	wait_mutex
539
 
539
 
540
	pushd	[edx + 4]
540
	pushd	[edx + 4]
541
	pop	[eax + IP_SOCKET.RemoteIP]
541
	pop	[eax + IP_SOCKET.RemoteIP]
542
 
542
 
543
	push	eax
543
	push	eax
544
	init_queue (eax + SOCKET_QUEUE_LOCATION)	; Set up data receiving queue
544
	init_queue (eax + SOCKET_QUEUE_LOCATION)	; Set up data receiving queue
545
	pop	eax
545
	pop	eax
546
 
546
 
547
	mov	[eax + SOCKET.lock], 0
547
	mov	[eax + SOCKET.lock], 0
548
	mov	dword [esp+32], 0
548
	mov	dword [esp+32], 0
549
	ret
549
	ret
550
 
550
 
551
 
551
 
552
;-----------------------------------------------------------------
552
;-----------------------------------------------------------------
553
;
553
;
554
; SOCKET_listen
554
; SOCKET_listen
555
;
555
;
556
;  IN:  socket number in ecx
556
;  IN:  socket number in ecx
557
;       backlog in edx
557
;       backlog in edx
558
;  OUT: eax is socket num, -1 on error
558
;  OUT: eax is socket num, -1 on error
559
;
559
;
560
;-----------------------------------------------------------------
560
;-----------------------------------------------------------------
561
align 4
561
align 4
562
SOCKET_listen:
562
SOCKET_listen:
563
 
563
 
564
	DEBUGF	1,"SOCKET_listen: socknum: %u backlog: %u\n", ecx, edx
564
	DEBUGF	1,"SOCKET_listen: socknum: %u backlog: %u\n", ecx, edx
565
 
565
 
566
	call	SOCKET_num_to_ptr
566
	call	SOCKET_num_to_ptr
567
	jz	s_error
567
	jz	s_error
568
 
568
 
569
	cmp	[eax + SOCKET.Domain], AF_INET4
569
	cmp	[eax + SOCKET.Domain], AF_INET4
570
	jne	s_error
570
	jne	s_error
571
 
571
 
572
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
572
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
573
	jne	s_error
573
	jne	s_error
574
 
574
 
575
	cmp	[eax + TCP_SOCKET.LocalPort], 0
575
	cmp	[eax + TCP_SOCKET.LocalPort], 0
576
	je	s_error
576
	je	s_error
577
 
577
 
578
	cmp	[eax + IP_SOCKET.LocalIP], 0
578
	cmp	[eax + IP_SOCKET.LocalIP], 0
579
	jne	@f
579
	jne	@f
580
	push	[IP_LIST]
580
	push	[IP_LIST]
581
	pop	[eax + IP_SOCKET.LocalIP]
581
	pop	[eax + IP_SOCKET.LocalIP]
582
       @@:
582
       @@:
583
 
583
 
584
	cmp	edx, MAX_backlog
584
	cmp	edx, MAX_backlog
585
	jbe	@f
585
	jbe	@f
586
	mov	edx, MAX_backlog
586
	mov	edx, MAX_backlog
587
       @@:
587
       @@:
588
 
588
 
589
	mov	[eax + SOCKET.backlog], dx
589
	mov	[eax + SOCKET.backlog], dx
590
	or	[eax + SOCKET.options], SO_ACCEPTCON
590
	or	[eax + SOCKET.options], SO_ACCEPTCON
591
	mov	[eax + TCP_SOCKET.t_state], TCPS_LISTEN
591
	mov	[eax + TCP_SOCKET.t_state], TCPS_LISTEN
592
 
592
 
593
	push	eax
593
	push	eax
594
	init_queue (eax + SOCKET_QUEUE_LOCATION)		; Set up sockets queue
594
	init_queue (eax + SOCKET_QUEUE_LOCATION)		; Set up sockets queue
595
	pop	eax
595
	pop	eax
596
 
596
 
597
	mov	dword [esp+32], 0
597
	mov	dword [esp+32], 0
598
 
598
 
599
	ret
599
	ret
600
 
600
 
601
 
601
 
602
;-----------------------------------------------------------------
602
;-----------------------------------------------------------------
603
;
603
;
604
; SOCKET_accept
604
; SOCKET_accept
605
;
605
;
606
;  IN:  socket number in ecx
606
;  IN:  socket number in ecx
607
;       addr in edx
607
;       addr in edx
608
;       addrlen in esi
608
;       addrlen in esi
609
;  OUT: eax is socket num, -1 on error
609
;  OUT: eax is socket num, -1 on error
610
;
610
;
611
;-----------------------------------------------------------------
611
;-----------------------------------------------------------------
612
align 4
612
align 4
613
SOCKET_accept:
613
SOCKET_accept:
614
 
614
 
615
	DEBUGF	1,"SOCKET_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
615
	DEBUGF	1,"SOCKET_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
616
 
616
 
617
	call	SOCKET_num_to_ptr
617
	call	SOCKET_num_to_ptr
618
	jz	s_error
618
	jz	s_error
619
 
619
 
620
	test	[eax + SOCKET.options], SO_ACCEPTCON
620
	test	[eax + SOCKET.options], SO_ACCEPTCON
621
	jz	s_error
621
	jz	s_error
622
 
622
 
623
	cmp	[eax + SOCKET.Domain], AF_INET4
623
	cmp	[eax + SOCKET.Domain], AF_INET4
624
	jne	s_error
624
	jne	s_error
625
 
625
 
626
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
626
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
627
	jne	s_error
627
	jne	s_error
628
 
628
 
629
	get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, s_error
629
	get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, s_error
630
 
630
 
631
	mov	eax, [esi]
631
	mov	eax, [esi]
632
	call	SOCKET_ptr_to_num
632
	call	SOCKET_ptr_to_num
633
	jz	s_error
633
	jz	s_error
634
	mov	dword [esp+32], eax
634
	mov	[esp+32], eax
635
	ret
635
	ret
636
 
636
 
637
 
637
 
638
;-----------------------------------------------------------------
638
;-----------------------------------------------------------------
639
;
639
;
640
; SOCKET_close
640
; SOCKET_close
641
;
641
;
642
;  IN:  socket number in ecx
642
;  IN:  socket number in ecx
643
;  OUT: eax is socket num, -1 on error
643
;  OUT: eax is socket num, -1 on error
644
;
644
;
645
;-----------------------------------------------------------------
645
;-----------------------------------------------------------------
646
align 4
646
align 4
647
SOCKET_close:
647
SOCKET_close:
648
 
648
 
649
	DEBUGF	1,"SOCKET_close: socknum: %u\n", ecx
649
	DEBUGF	1,"SOCKET_close: socknum: %u\n", ecx
650
 
650
 
651
	call	SOCKET_num_to_ptr
651
	call	SOCKET_num_to_ptr
652
	jz	s_error
652
	jz	s_error
653
 
653
 
654
	cmp	[eax + SOCKET.Domain], AF_INET4
654
	cmp	[eax + SOCKET.Domain], AF_INET4
655
	jne	s_error
655
	jne	s_error
656
 
656
 
657
	cmp	[eax + SOCKET.Protocol], IP_PROTO_UDP
657
	cmp	[eax + SOCKET.Protocol], IP_PROTO_UDP
658
	je	.free
658
	je	.free
659
 
659
 
660
	cmp	[eax + SOCKET.Protocol], IP_PROTO_ICMP
660
	cmp	[eax + SOCKET.Protocol], IP_PROTO_ICMP
661
	je	.free
661
	je	.free
662
 
662
 
663
	cmp	[eax + SOCKET.Protocol], IP_PROTO_IP
663
	cmp	[eax + SOCKET.Protocol], IP_PROTO_IP
664
	je	.free
664
	je	.free
665
 
665
 
666
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
666
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
667
	je	.tcp
667
	je	.tcp
668
 
668
 
669
	jmp	s_error
669
	jmp	s_error
670
 
670
 
671
  .tcp:
671
  .tcp:
672
	cmp	[eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED	 ; state must be LISTEN, SYN_SENT or CLOSED
672
	cmp	[eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED	 ; state must be LISTEN, SYN_SENT or CLOSED
673
	jb	.free
673
	jb	.free
674
 
674
 
675
	call	TCP_output
675
	call	TCP_output
676
	mov	dword [esp+32], 0
676
	mov	dword [esp+32], 0
677
 
677
 
678
	ret
678
	ret
679
 
679
 
680
  .free:
680
  .free:
681
	call	SOCKET_free
681
	call	SOCKET_free
682
	mov	dword [esp+32], 0
682
	mov	dword [esp+32], 0
683
 
683
 
684
	ret
684
	ret
685
 
685
 
686
 
686
 
687
;-----------------------------------------------------------------
687
;-----------------------------------------------------------------
688
;
688
;
689
; SOCKET_receive
689
; SOCKET_receive
690
;
690
;
691
;  IN:  socket number in ecx
691
;  IN:  socket number in ecx
692
;       addr to buffer in edx
692
;       addr to buffer in edx
693
;       length of buffer in esi
693
;       length of buffer in esi
694
;       flags in edi
694
;       flags in edi
695
;  OUT: eax is number of bytes copied, -1 on error
695
;  OUT: eax is number of bytes copied, -1 on error
696
;
696
;
697
;-----------------------------------------------------------------
697
;-----------------------------------------------------------------
698
align 4
698
align 4
699
SOCKET_receive:
699
SOCKET_receive:
700
 
700
 
701
	DEBUGF	1,"SOCKET_receive: socknum: %u bufaddr: %x, buflength: %u, flags: %x, ", ecx, edx, esi, edi
701
	DEBUGF	1,"SOCKET_receive: socknum: %u bufaddr: %x, buflength: %u, flags: %x, ", ecx, edx, esi, edi
702
 
702
 
703
	call	SOCKET_num_to_ptr
703
	call	SOCKET_num_to_ptr
704
	jz	s_error
704
	jz	s_error
705
 
705
 
706
	jmp	[eax + SOCKET.rcv_proc]
706
	jmp	[eax + SOCKET.rcv_proc]
707
 
707
 
708
 
708
 
709
align 4
709
align 4
710
SOCKET_receive_dgram:
710
SOCKET_receive_dgram:
711
 
711
 
712
	DEBUGF	1,"SOCKET_receive: DGRAM\n"
712
	DEBUGF	1,"SOCKET_receive: DGRAM\n"
713
 
713
 
714
	mov	ebx, esi
714
	mov	ebx, esi
715
	mov	edi, edx					; addr to buffer
715
	mov	edi, edx					; addr to buffer
716
 
716
 
717
	get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, s_error	; destroys esi and ecx
717
	get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, s_error	; destroys esi and ecx
718
 
718
 
719
	mov	ecx, [esi + socket_queue_entry.data_size]
719
	mov	ecx, [esi + socket_queue_entry.data_size]
720
	DEBUGF	1,"Got %u bytes of data\n", ecx
720
	DEBUGF	1,"Got %u bytes of data\n", ecx
721
 
721
 
722
	cmp	ecx, ebx
722
	cmp	ecx, ebx
723
	ja	.too_small
723
	ja	.too_small
724
 
724
 
725
	push	[esi + socket_queue_entry.buf_ptr]		; save the buffer addr so we can clear it later
725
	push	[esi + socket_queue_entry.buf_ptr]		; save the buffer addr so we can clear it later
726
	mov	esi, [esi + socket_queue_entry.data_ptr]
726
	mov	esi, [esi + socket_queue_entry.data_ptr]
727
	DEBUGF	1,"Source buffer: %x, real addr: %x\n", [esp], esi
727
	DEBUGF	1,"Source buffer: %x, real addr: %x\n", [esp], esi
728
	mov	dword[esp+32+4], ecx				; return number of bytes copied
728
	mov	[esp+32+4], ecx 				; return number of bytes copied
729
 
729
 
730
; copy the data
730
; copy the data
731
	shr	ecx, 1
731
	shr	ecx, 1
732
	jnc	.nb
732
	jnc	.nb
733
	movsb
733
	movsb
734
  .nb:
734
  .nb:
735
	shr	ecx, 1
735
	shr	ecx, 1
736
	jnc	.nw
736
	jnc	.nw
737
	movsw
737
	movsw
738
  .nw:
738
  .nw:
739
	test	ecx, ecx
739
	test	ecx, ecx
740
	jz	.nd
740
	jz	.nd
741
	rep	movsd
741
	rep	movsd
742
  .nd:
742
  .nd:
743
 
743
 
744
	call	kernel_free					; remove the packet
744
	call	kernel_free					; remove the packet
745
	ret
745
	ret
746
 
746
 
747
  .too_small:
747
  .too_small:
748
 
748
 
749
	DEBUGF	1,"Buffer too small...\n"
749
	DEBUGF	1,"Buffer too small...\n"
750
	jmp	s_error
750
	jmp	s_error
751
 
751
 
752
align 4
752
align 4
753
SOCKET_receive_tcp:
753
SOCKET_receive_tcp:
754
 
754
 
755
	DEBUGF	1,"SOCKET_receive: TCP\n"
755
	DEBUGF	1,"SOCKET_receive: TCP\n"
756
 
756
 
757
	mov	ecx, esi
757
	mov	ecx, esi
758
	mov	edi, edx
758
	mov	edi, edx
759
	add	eax, STREAM_SOCKET.rcv
759
	add	eax, STREAM_SOCKET.rcv
760
	call	SOCKET_ring_read
760
	call	SOCKET_ring_read
761
	call	SOCKET_ring_free
761
	call	SOCKET_ring_free
762
 
762
 
763
	mov	dword[esp+32], ecx				; return number of bytes copied
763
	mov	[esp+32], ecx					; return number of bytes copied
764
 
764
 
765
	ret
765
	ret
766
 
766
 
767
 
767
 
768
;-----------------------------------------------------------------
768
;-----------------------------------------------------------------
769
;
769
;
770
; SOCKET_send
770
; SOCKET_send
771
;
771
;
772
;
772
;
773
;  IN:  socket number in ecx
773
;  IN:  socket number in ecx
774
;       pointer to data in edx
774
;       pointer to data in edx
775
;       datalength in esi
775
;       datalength in esi
776
;       flags in edi
776
;       flags in edi
777
;  OUT: -1 on error
777
;  OUT: -1 on error
778
;
778
;
779
;-----------------------------------------------------------------
779
;-----------------------------------------------------------------
780
align 4
780
align 4
781
SOCKET_send:
781
SOCKET_send:
782
 
782
 
783
	DEBUGF	1,"SOCKET_send: socknum: %u data ptr: %x, length: %u, flags: %x, ", ecx, edx, esi, edi
783
	DEBUGF	1,"SOCKET_send: socknum: %u data ptr: %x, length: %u, flags: %x, ", ecx, edx, esi, edi
784
 
784
 
785
	call	SOCKET_num_to_ptr
785
	call	SOCKET_num_to_ptr
786
	jz	s_error
786
	jz	s_error
787
 
787
 
788
	mov	ecx, esi
788
	mov	ecx, esi
789
	mov	esi, edx
789
	mov	esi, edx
790
 
790
 
791
	jmp	[eax + SOCKET.snd_proc]
791
	jmp	[eax + SOCKET.snd_proc]
792
 
792
 
793
 
793
 
794
align 4
794
align 4
795
SOCKET_send_udp:
795
SOCKET_send_udp:
796
 
796
 
797
	DEBUGF	1,"SOCKET_send: UDP\n"
797
	DEBUGF	1,"SOCKET_send: UDP\n"
798
 
798
 
799
	call	UDP_output
799
	call	UDP_output
800
 
800
 
801
	mov	dword [esp+32], 0
801
	mov	[esp+32], eax
802
	ret
802
	ret
803
 
803
 
804
 
804
 
805
align 4
805
align 4
806
SOCKET_send_tcp:
806
SOCKET_send_tcp:
807
 
807
 
808
	DEBUGF	1,"SOCKET_send: TCP\n"
808
	DEBUGF	1,"SOCKET_send: TCP\n"
809
 
809
 
810
	push	eax
810
	push	eax
811
	add	eax, STREAM_SOCKET.snd
811
	add	eax, STREAM_SOCKET.snd
812
	call	SOCKET_ring_write
812
	call	SOCKET_ring_write
813
	pop	eax
813
	pop	eax
814
 
814
 
815
	call	TCP_output
815
	call	TCP_output
816
 
816
 
817
	mov	[esp+32], eax
817
	mov	[esp+32], eax
818
	ret
818
	ret
819
 
819
 
820
 
820
 
821
align 4
821
align 4
822
SOCKET_send_ip:
822
SOCKET_send_ip:
823
 
823
 
824
	DEBUGF	1,"type: IP\n"
824
	DEBUGF	1,"type: IP\n"
825
 
825
 
826
	call	IPv4_output_raw
826
	call	IPv4_output_raw
827
 
827
 
828
	mov	[esp+32], eax
828
	mov	[esp+32], eax
829
	ret
829
	ret
830
 
830
 
831
align 4
831
align 4
832
SOCKET_send_icmp:
832
SOCKET_send_icmp:
833
 
833
 
834
	DEBUGF	1,"SOCKET_send: ICMP\n"
834
	DEBUGF	1,"SOCKET_send: ICMP\n"
835
 
835
 
836
	call	ICMP_output_raw
836
	call	ICMP_output_raw
837
 
837
 
838
	mov	dword [esp+32], 0
838
	mov	[esp+32], eax
839
	ret
839
	ret
840
 
840
 
841
 
841
 
842
 
842
 
843
 
843
 
844
;-----------------------------------------------------------------
844
;-----------------------------------------------------------------
845
;
845
;
846
; SOCKET_get_options
846
; SOCKET_get_options
847
;
847
;
848
;  IN:  ecx = socket number
848
;  IN:  ecx = socket number
849
;       edx = pointer to the options:
849
;       edx = pointer to the options:
850
;               dd      level, optname, optval, optlen
850
;               dd      level, optname, optval, optlen
851
;  OUT: -1 on error
851
;  OUT: -1 on error
852
;
852
;
853
; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP.
853
; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP.
854
; TODO: find best way to notify that send()'ed data were acknowledged
854
; TODO: find best way to notify that send()'ed data were acknowledged
855
; Also pseudo-optname -3 is valid and returns socket state, one of TCPS_*.
855
; Also pseudo-optname -3 is valid and returns socket state, one of TCPS_*.
856
;
856
;
857
;-----------------------------------------------------------------
857
;-----------------------------------------------------------------
858
align 4
858
align 4
859
SOCKET_get_opt:
859
SOCKET_get_opt:
860
 
860
 
861
	DEBUGF	1,"SOCKET_get_opt\n"
861
	DEBUGF	1,"SOCKET_get_opt\n"
862
 
862
 
863
	call	SOCKET_num_to_ptr
863
	call	SOCKET_num_to_ptr
864
	jz	s_error
864
	jz	s_error
865
 
865
 
866
	cmp	dword [edx], IP_PROTO_TCP
866
	cmp	dword [edx], IP_PROTO_TCP
867
	jne	s_error
867
	jne	s_error
868
	cmp	dword [edx+4], -2
868
	cmp	dword [edx+4], -2
869
	je	@f
869
	je	@f
870
	cmp	dword [edx+4], -3
870
	cmp	dword [edx+4], -3
871
	jne	s_error
871
	jne	s_error
872
@@:
872
@@:
873
;        mov     eax, [edx+12]
873
;        mov     eax, [edx+12]
874
;        test    eax, eax
874
;        test    eax, eax
875
;        jz      .fail
875
;        jz      .fail
876
;        cmp     dword [eax], 4
876
;        cmp     dword [eax], 4
877
;        mov     dword [eax], 4
877
;        mov     dword [eax], 4
878
;        jb      .fail
878
;        jb      .fail
879
;        stdcall net_socket_num_to_addr, ecx
879
;        stdcall net_socket_num_to_addr, ecx
880
;        test    eax, eax
880
;        test    eax, eax
881
;        jz      .fail
881
;        jz      .fail
882
;        ; todo: check that eax is really TCP socket
882
;        ; todo: check that eax is really TCP socket
883
;        mov     ecx, [eax + TCP_SOCKET.last_ack_number]
883
;        mov     ecx, [eax + TCP_SOCKET.last_ack_number]
884
;        cmp     dword [edx+4], -2
884
;        cmp     dword [edx+4], -2
885
;        jz      @f
885
;        jz      @f
886
;        mov     ecx, [eax + TCP_SOCKET.state]
886
;        mov     ecx, [eax + TCP_SOCKET.state]
887
@@:
887
@@:
888
	mov	eax, [edx+8]
888
	mov	eax, [edx+8]
889
	test	eax, eax
889
	test	eax, eax
890
	jz	@f
890
	jz	@f
891
	mov	[eax], ecx
891
	mov	[eax], ecx
892
@@:
892
@@:
893
	mov	dword [esp+32], 0
893
	mov	dword [esp+32], 0
894
	ret
894
	ret
895
 
895
 
896
 
896
 
897
 
897
 
898
 
898
 
899
align 4
899
align 4
900
SOCKET_set_opt:
900
SOCKET_set_opt:
901
 
901
 
902
	ret
902
	ret
903
 
903
 
904
 
904
 
905
 
905
 
906
;-----------------------------------------------------------------
906
;-----------------------------------------------------------------
907
;
907
;
908
; SOCKET_debug
908
; SOCKET_debug
909
;
909
;
910
;  Copies socket variables to application buffer
910
;  Copies socket variables to application buffer
911
;
911
;
912
;  IN:  ecx = socket number
912
;  IN:  ecx = socket number
913
;       edx = pointer to buffer
913
;       edx = pointer to buffer
914
;
914
;
915
;  OUT: -1 on error
915
;  OUT: -1 on error
916
;-----------------------------------------------------------------
916
;-----------------------------------------------------------------
917
align 4
917
align 4
918
SOCKET_debug:
918
SOCKET_debug:
919
 
919
 
920
	DEBUGF	1,"socket_debug\n"
920
	DEBUGF	1,"socket_debug\n"
921
 
921
 
922
	call	SOCKET_num_to_ptr
922
	call	SOCKET_num_to_ptr
923
	jz	s_error
923
	jz	s_error
924
 
924
 
925
	mov	esi, eax
925
	mov	esi, eax
926
	mov	edi, edx
926
	mov	edi, edx
927
	mov	ecx, SOCKETBUFFSIZE/4
927
	mov	ecx, SOCKETBUFFSIZE/4
928
	rep	movsd
928
	rep	movsd
929
 
929
 
930
	mov	dword [esp+32], 0
930
	mov	dword [esp+32], 0
931
	ret
931
	ret
932
 
932
 
933
 
933
 
934
;-----------------------------------------------------------------
934
;-----------------------------------------------------------------
935
;
935
;
936
; SOCKET_find_port
936
; SOCKET_find_port
937
;
937
;
938
; Fills in the local port number for TCP and UDP sockets
938
; Fills in the local port number for TCP and UDP sockets
939
; This procedure always works because the number of sockets is
939
; This procedure always works because the number of sockets is
940
; limited to a smaller number then the number of possible ports
940
; limited to a smaller number then the number of possible ports
941
;
941
;
942
;  IN:  eax = socket pointer
942
;  IN:  eax = socket pointer
943
;  OUT: /
943
;  OUT: /
944
;
944
;
945
;-----------------------------------------------------------------
945
;-----------------------------------------------------------------
946
align 4
946
align 4
947
SOCKET_find_port:
947
SOCKET_find_port:
948
 
948
 
949
	DEBUGF	1,"SOCKET_find_port\n"
949
	DEBUGF	1,"SOCKET_find_port\n"
950
 
950
 
951
	push	ebx esi ecx
951
	push	ebx esi ecx
952
 
952
 
953
	cmp	[eax + SOCKET.Protocol], IP_PROTO_UDP
953
	cmp	[eax + SOCKET.Protocol], IP_PROTO_UDP
954
	je	.udp
954
	je	.udp
955
 
955
 
956
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
956
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
957
	je	.tcp
957
	je	.tcp
958
 
958
 
959
	jmp	.error
959
	jmp	.error
960
 
960
 
961
  .done:
961
  .done:
962
	mov	[eax + UDP_SOCKET.LocalPort], bx
962
	mov	[eax + UDP_SOCKET.LocalPort], bx
963
  .error:
963
  .error:
964
	pop	ecx esi ebx
964
	pop	ecx esi ebx
965
	ret
965
	ret
966
 
966
 
967
  .udp:
967
  .udp:
968
	mov	bx, [last_UDP_port]
968
	mov	bx, [last_UDP_port]
969
	call	.findit
969
	call	.findit
970
	mov	[last_UDP_port], bx
970
	mov	[last_UDP_port], bx
971
	jmp	.done
971
	jmp	.done
972
 
972
 
973
  .tcp:
973
  .tcp:
974
	mov	bx, [last_TCP_port]
974
	mov	bx, [last_TCP_port]
975
	call	.findit
975
	call	.findit
976
	mov	[last_TCP_port], bx
976
	mov	[last_TCP_port], bx
977
	jmp	.done
977
	jmp	.done
978
 
978
 
979
 
979
 
980
  .restart:
980
  .restart:
981
	mov	bx, MIN_EPHEMERAL_PORT
981
	mov	bx, MIN_EPHEMERAL_PORT
982
  .findit:
982
  .findit:
983
	inc	bx
983
	inc	bx
984
 
984
 
985
	cmp	bx, MAX_EPHEMERAL_PORT
985
	cmp	bx, MAX_EPHEMERAL_PORT
986
	jz	.restart
986
	jz	.restart
987
 
987
 
988
	call	SOCKET_check_port
988
	call	SOCKET_check_port
989
	jz	.findit
989
	jz	.findit
990
 
990
 
991
	ret
991
	ret
992
 
992
 
993
 
993
 
994
 
994
 
995
;-----------------------------------------------------------------
995
;-----------------------------------------------------------------
996
;
996
;
997
; SOCKET_check_port (to be used with AF_INET only!)
997
; SOCKET_check_port (to be used with AF_INET only!)
998
;
998
;
999
; Checks if a local port number is unused
999
; Checks if a local port number is unused
1000
; If the proposed port number is unused, it is filled in in the socket structure
1000
; If the proposed port number is unused, it is filled in in the socket structure
1001
;
1001
;
1002
;  IN:  eax = socket ptr (to find out if its a TCP/UDP socket)
1002
;  IN:  eax = socket ptr (to find out if its a TCP/UDP socket)
1003
;        bx = proposed socket number
1003
;        bx = proposed socket number
1004
;
1004
;
1005
;  OUT:  ZF = cleared on error
1005
;  OUT:  ZF = cleared on error
1006
;
1006
;
1007
;-----------------------------------------------------------------
1007
;-----------------------------------------------------------------
1008
align 4
1008
align 4
1009
SOCKET_check_port:
1009
SOCKET_check_port:
1010
 
1010
 
1011
	DEBUGF	1,"SOCKET_check_port\n"
1011
	DEBUGF	1,"SOCKET_check_port\n"
1012
 
1012
 
1013
	mov	ecx, [eax + SOCKET.Protocol]
1013
	mov	ecx, [eax + SOCKET.Protocol]
1014
	mov	esi, net_sockets
1014
	mov	esi, net_sockets
1015
 
1015
 
1016
  .next_socket:
1016
  .next_socket:
1017
	mov	esi, [esi + SOCKET.NextPtr]
1017
	mov	esi, [esi + SOCKET.NextPtr]
1018
	or	esi, esi
1018
	or	esi, esi
1019
	jz	.port_ok
1019
	jz	.port_ok
1020
 
1020
 
1021
	cmp	[esi + SOCKET.Protocol], ecx
1021
	cmp	[esi + SOCKET.Protocol], ecx
1022
	jne	.next_socket
1022
	jne	.next_socket
1023
 
1023
 
1024
	cmp	[esi + UDP_SOCKET.LocalPort], bx
1024
	cmp	[esi + UDP_SOCKET.LocalPort], bx
1025
	jne	.next_socket
1025
	jne	.next_socket
1026
 
1026
 
1027
	DEBUGF	1,"local port %u already in use\n", bx
1027
	DEBUGF	1,"local port %u already in use\n", bx
1028
	ret
1028
	ret
1029
 
1029
 
1030
  .port_ok:
1030
  .port_ok:
1031
	mov	[eax + UDP_SOCKET.LocalPort], bx
1031
	mov	[eax + UDP_SOCKET.LocalPort], bx
1032
	or	bx, bx					; set the zero-flag
1032
	or	bx, bx					; set the zero-flag
1033
 
1033
 
1034
	ret
1034
	ret
1035
 
1035
 
1036
 
1036
 
1037
 
1037
 
1038
;-----------------------------------------------------------------
1038
;-----------------------------------------------------------------
1039
;
1039
;
1040
; SOCKET_input
1040
; SOCKET_input
1041
;
1041
;
1042
; Updates a (stateless) socket with received data
1042
; Updates a (stateless) socket with received data
1043
;
1043
;
1044
; Note: the mutex should already be set !
1044
; Note: the mutex should already be set !
1045
;
1045
;
1046
;  IN:  eax = socket ptr
1046
;  IN:  eax = socket ptr
1047
;       ebx = pointer to device struct
1047
;       ebx = pointer to device struct
1048
;       ecx = data size
1048
;       ecx = data size
1049
;       esi = ptr to data
1049
;       esi = ptr to data
1050
;       [esp] = ptr to buf
1050
;       [esp] = ptr to buf
1051
;       [esp + 4] = buf size
1051
;       [esp + 4] = buf size
1052
;
1052
;
1053
;  OUT: /
1053
;  OUT: /
1054
;
1054
;
1055
;-----------------------------------------------------------------
1055
;-----------------------------------------------------------------
1056
align 4
1056
align 4
1057
SOCKET_input:
1057
SOCKET_input:
1058
 
1058
 
1059
	DEBUGF	1,"SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx
1059
	DEBUGF	1,"SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx
1060
 
1060
 
1061
	mov	dword[esp+4], ecx
1061
	mov	[esp+4], ecx
1062
	push	esi
1062
	push	esi
1063
	mov	esi, esp
1063
	mov	esi, esp
1064
 
1064
 
1065
	add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, SOCKET_input.full
1065
	add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, SOCKET_input.full
1066
 
1066
 
1067
	DEBUGF	1,"SOCKET_input: queued packet successfully\n"
1067
	DEBUGF	1,"SOCKET_input: queued packet successfully\n"
1068
	add	esp, socket_queue_entry.size
1068
	add	esp, socket_queue_entry.size
1069
	mov	[eax + SOCKET.lock], 0
1069
	mov	[eax + SOCKET.lock], 0
1070
	jmp	SOCKET_notify_owner
1070
	jmp	SOCKET_notify_owner
1071
 
1071
 
1072
  .full:
1072
  .full:
1073
	DEBUGF	2,"SOCKET_input: socket %x is full!\n", eax
1073
	DEBUGF	2,"SOCKET_input: socket %x is full!\n", eax
1074
	mov	[eax + SOCKET.lock], 0
1074
	mov	[eax + SOCKET.lock], 0
1075
	call	kernel_free
1075
	call	kernel_free
1076
	add	esp, 8
1076
	add	esp, 8
1077
 
1077
 
1078
	ret
1078
	ret
1079
 
1079
 
1080
 
1080
 
1081
;--------------------------
1081
;--------------------------
1082
;
1082
;
1083
; eax = ptr to ring struct (just a buffer of the right size)
1083
; eax = ptr to ring struct (just a buffer of the right size)
1084
;
1084
;
1085
align 4
1085
align 4
1086
SOCKET_ring_create:
1086
SOCKET_ring_create:
1087
 
1087
 
1088
	push	esi
1088
	push	esi
1089
	mov	esi, eax
1089
	mov	esi, eax
1090
 
1090
 
1091
	push	edx
1091
	push	edx
1092
	stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
1092
	stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
1093
	pop	edx
1093
	pop	edx
1094
 
1094
 
1095
	DEBUGF	1,"SOCKET_ring_created: %x\n", eax
1095
	DEBUGF	1,"SOCKET_ring_created: %x\n", eax
1096
	mov	[esi + RING_BUFFER.start_ptr], eax
1096
	mov	[esi + RING_BUFFER.start_ptr], eax
1097
	mov	[esi + RING_BUFFER.write_ptr], eax
1097
	mov	[esi + RING_BUFFER.write_ptr], eax
1098
	mov	[esi + RING_BUFFER.read_ptr], eax
1098
	mov	[esi + RING_BUFFER.read_ptr], eax
1099
	mov	[esi + RING_BUFFER.size], 0
1099
	mov	[esi + RING_BUFFER.size], 0
1100
	add	eax,  SOCKET_MAXDATA
1100
	add	eax,  SOCKET_MAXDATA
1101
	mov	[esi + RING_BUFFER.end_ptr], eax
1101
	mov	[esi + RING_BUFFER.end_ptr], eax
1102
	mov	eax, esi
1102
	mov	eax, esi
1103
	pop	esi
1103
	pop	esi
1104
 
1104
 
1105
	ret
1105
	ret
1106
 
1106
 
1107
;-----------------------------------------------------------------
1107
;-----------------------------------------------------------------
1108
;
1108
;
1109
; SOCKET_ring_write
1109
; SOCKET_ring_write
1110
;
1110
;
1111
; Adds data to a stream socket, and updates write pointer and size
1111
; Adds data to a stream socket, and updates write pointer and size
1112
;
1112
;
1113
;  IN:  eax = ptr to ring struct
1113
;  IN:  eax = ptr to ring struct
1114
;       ecx = data size
1114
;       ecx = data size
1115
;       esi = ptr to data
1115
;       esi = ptr to data
1116
;
1116
;
1117
;  OUT: ecx = number of bytes stored
1117
;  OUT: ecx = number of bytes stored
1118
;
1118
;
1119
;-----------------------------------------------------------------
1119
;-----------------------------------------------------------------
1120
align 4
1120
align 4
1121
SOCKET_ring_write:
1121
SOCKET_ring_write:
1122
 
1122
 
1123
	DEBUGF	1,"SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx
1123
	DEBUGF	1,"SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx
1124
 
1124
 
1125
	add	[eax + RING_BUFFER.size], ecx
1125
	add	[eax + RING_BUFFER.size], ecx
1126
	cmp	[eax + RING_BUFFER.size], SOCKET_MAXDATA
1126
	cmp	[eax + RING_BUFFER.size], SOCKET_MAXDATA
1127
	ja	.too_large
1127
	ja	.too_large
1128
 
1128
 
1129
  .copy:
1129
  .copy:
1130
	mov	edi, [eax + RING_BUFFER.write_ptr]
1130
	mov	edi, [eax + RING_BUFFER.write_ptr]
1131
	DEBUGF	2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi
1131
	DEBUGF	2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi
1132
 
1132
 
1133
	push	ecx
1133
	push	ecx
1134
	shr	ecx, 1
1134
	shr	ecx, 1
1135
	jnc	.nb
1135
	jnc	.nb
1136
	movsb
1136
	movsb
1137
  .nb:
1137
  .nb:
1138
	shr	ecx, 1
1138
	shr	ecx, 1
1139
	jnc	.nw
1139
	jnc	.nw
1140
	movsw
1140
	movsw
1141
  .nw:
1141
  .nw:
1142
	test	ecx, ecx
1142
	test	ecx, ecx
1143
	jz	.nd
1143
	jz	.nd
1144
	rep	movsd
1144
	rep	movsd
1145
  .nd:
1145
  .nd:
1146
	pop	ecx
1146
	pop	ecx
1147
 
1147
 
1148
	cmp	edi, [eax + RING_BUFFER.end_ptr]
1148
	cmp	edi, [eax + RING_BUFFER.end_ptr]
1149
	jae	.wrap
1149
	jae	.wrap
1150
	mov	[eax + RING_BUFFER.write_ptr], edi
1150
	mov	[eax + RING_BUFFER.write_ptr], edi
1151
 
1151
 
1152
	ret
1152
	ret
1153
 
1153
 
1154
  .wrap:
1154
  .wrap:
1155
	sub	edi, SOCKET_MAXDATA
1155
	sub	edi, SOCKET_MAXDATA
1156
	mov	[eax + RING_BUFFER.write_ptr], edi
1156
	mov	[eax + RING_BUFFER.write_ptr], edi
1157
 
1157
 
1158
	ret
1158
	ret
1159
 
1159
 
1160
  .too_large:
1160
  .too_large:
1161
	mov	ecx, SOCKET_MAXDATA				; calculate number of bytes available in buffer
1161
	mov	ecx, SOCKET_MAXDATA				; calculate number of bytes available in buffer
1162
	sub	ecx, [eax + RING_BUFFER.size]
1162
	sub	ecx, [eax + RING_BUFFER.size]
1163
	jae	.full
1163
	jae	.full
1164
 
1164
 
1165
	mov	[eax + RING_BUFFER.size], SOCKET_MAXDATA	; update size, we will fill buffer completely
1165
	mov	[eax + RING_BUFFER.size], SOCKET_MAXDATA	; update size, we will fill buffer completely
1166
	jmp	.copy
1166
	jmp	.copy
1167
 
1167
 
1168
  .full:
1168
  .full:
1169
	DEBUGF	2,"SOCKET_ring_write: ring buffer is full!\n"
1169
	DEBUGF	2,"SOCKET_ring_write: ring buffer is full!\n"
1170
	xor	ecx, ecx
1170
	xor	ecx, ecx
1171
	ret
1171
	ret
1172
 
1172
 
1173
 
1173
 
1174
;-----------------------------------------------------------------
1174
;-----------------------------------------------------------------
1175
;
1175
;
1176
; SOCKET_ring_read
1176
; SOCKET_ring_read
1177
;
1177
;
1178
; reads the data, BUT DOES NOT CLEAR IT FROM MEMORY YET
1178
; reads the data, BUT DOES NOT CLEAR IT FROM MEMORY YET
1179
;
1179
;
1180
;  IN:  eax = ptr to ring struct
1180
;  IN:  eax = ptr to ring struct
1181
;       ecx = buffer size
1181
;       ecx = buffer size
1182
;       edi = ptr to buffer
1182
;       edi = ptr to buffer
1183
;
1183
;
1184
;  OUT: ecx = number of bytes read
1184
;  OUT: ecx = number of bytes read
1185
;
1185
;
1186
;-----------------------------------------------------------------
1186
;-----------------------------------------------------------------
1187
align 4
1187
align 4
1188
SOCKET_ring_read:
1188
SOCKET_ring_read:
1189
 
1189
 
1190
	DEBUGF	1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u\n", eax, edi, ecx
1190
	DEBUGF	1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u\n", eax, edi, ecx
1191
 
1191
 
1192
	cmp	ecx, [eax + RING_BUFFER.size]
1192
	cmp	ecx, [eax + RING_BUFFER.size]
1193
	ja	.less_data
1193
	ja	.less_data
1194
 
1194
 
1195
  .copy:
1195
  .copy:
1196
	mov	esi, [eax + RING_BUFFER.read_ptr]
1196
	mov	esi, [eax + RING_BUFFER.read_ptr]
1197
 
1197
 
1198
	DEBUGF	2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi
1198
	DEBUGF	2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi
1199
	push	ecx
1199
	push	ecx
1200
	shr	ecx, 1
1200
	shr	ecx, 1
1201
	jnc	.nb
1201
	jnc	.nb
1202
	movsb
1202
	movsb
1203
  .nb:
1203
  .nb:
1204
	shr	ecx, 1
1204
	shr	ecx, 1
1205
	jnc	.nw
1205
	jnc	.nw
1206
	movsw
1206
	movsw
1207
  .nw:
1207
  .nw:
1208
	test	ecx, ecx
1208
	test	ecx, ecx
1209
	jz	.nd
1209
	jz	.nd
1210
	rep	movsd
1210
	rep	movsd
1211
  .nd:
1211
  .nd:
1212
	pop	ecx
1212
	pop	ecx
1213
 
1213
 
1214
  .no_data_at_all:
1214
  .no_data_at_all:
1215
	ret
1215
	ret
1216
 
1216
 
1217
  .less_data:
1217
  .less_data:
1218
	mov	ecx, [eax + RING_BUFFER.size]
1218
	mov	ecx, [eax + RING_BUFFER.size]
1219
;        test    ecx, ecx
1219
;        test    ecx, ecx
1220
;        jz      .no_data_at_all
1220
;        jz      .no_data_at_all
1221
	jmp	.copy
1221
	jmp	.copy
1222
 
1222
 
1223
 
1223
 
1224
;-----------------------------------------------------------------
1224
;-----------------------------------------------------------------
1225
;
1225
;
1226
; SOCKET_ring_free
1226
; SOCKET_ring_free
1227
;
1227
;
1228
; Free's some bytes from the ringbuffer
1228
; Free's some bytes from the ringbuffer
1229
;
1229
;
1230
;  IN:  eax = ptr to ring struct
1230
;  IN:  eax = ptr to ring struct
1231
;       ecx = data size
1231
;       ecx = data size
1232
;
1232
;
1233
;  OUT: ecx = number of bytes free-ed
1233
;  OUT: ecx = number of bytes free-ed
1234
;
1234
;
1235
;-----------------------------------------------------------------
1235
;-----------------------------------------------------------------
1236
align 4
1236
align 4
1237
SOCKET_ring_free:
1237
SOCKET_ring_free:
1238
 
1238
 
1239
	DEBUGF	1,"SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax
1239
	DEBUGF	1,"SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax
1240
 
1240
 
1241
	sub	[eax + RING_BUFFER.size], ecx
1241
	sub	[eax + RING_BUFFER.size], ecx
1242
	jb	.sumthinwong
1242
	jb	.sumthinwong
1243
	add	[eax + RING_BUFFER.read_ptr], ecx
1243
	add	[eax + RING_BUFFER.read_ptr], ecx
1244
 
1244
 
1245
	mov	edx, [eax + RING_BUFFER.end_ptr]
1245
	mov	edx, [eax + RING_BUFFER.end_ptr]
1246
	cmp	[eax + RING_BUFFER.read_ptr], edx
1246
	cmp	[eax + RING_BUFFER.read_ptr], edx
1247
	jb	@f
1247
	jb	@f
1248
	sub	[eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA
1248
	sub	[eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA
1249
       @@:
1249
       @@:
1250
	ret
1250
	ret
1251
 
1251
 
1252
  .sumthinwong: 	       ; we could free all available bytes, but that would be stupid, i guess..
1252
  .sumthinwong: 	       ; we could free all available bytes, but that would be stupid, i guess..
1253
	add	[eax + RING_BUFFER.size], ecx
1253
	add	[eax + RING_BUFFER.size], ecx
1254
	xor	ecx, ecx
1254
	xor	ecx, ecx
1255
	ret
1255
	ret
1256
 
1256
 
1257
 
1257
 
1258
;-----------------------------------------------------------------
1258
;-----------------------------------------------------------------
1259
;
1259
;
1260
; SOCKET_notify_owner
1260
; SOCKET_notify_owner
1261
;
1261
;
1262
; notify's the owner of a socket that something happened
1262
; notify's the owner of a socket that something happened
1263
;
1263
;
1264
;  IN:  eax = socket ptr
1264
;  IN:  eax = socket ptr
1265
;  OUT: /
1265
;  OUT: /
1266
;
1266
;
1267
;-----------------------------------------------------------------
1267
;-----------------------------------------------------------------
1268
align 4
1268
align 4
1269
SOCKET_notify_owner:
1269
SOCKET_notify_owner:
1270
 
1270
 
1271
	DEBUGF	1,"SOCKET_notify_owner: %x\n", eax
1271
	DEBUGF	1,"SOCKET_notify_owner: %x\n", eax
1272
 
1272
 
1273
	call	SOCKET_check
1273
	call	SOCKET_check
1274
	jz	.error
1274
	jz	.error
1275
 
1275
 
1276
	push	eax ecx esi
1276
	push	eax ecx esi
1277
 
1277
 
1278
; socket exists, now try to flag an event to the application
1278
; socket exists, now try to flag an event to the application
1279
 
1279
 
1280
	mov	eax, [eax + SOCKET.PID]
1280
	mov	eax, [eax + SOCKET.PID]
1281
	mov	ecx, 1
1281
	mov	ecx, 1
1282
	mov	esi, TASK_DATA + TASKDATA.pid
1282
	mov	esi, TASK_DATA + TASKDATA.pid
1283
 
1283
 
1284
       .next_pid:
1284
       .next_pid:
1285
	cmp	[esi], eax
1285
	cmp	[esi], eax
1286
	je	.found_pid
1286
	je	.found_pid
1287
	inc	ecx
1287
	inc	ecx
1288
	add	esi, 0x20
1288
	add	esi, 0x20
1289
	cmp	ecx, [TASK_COUNT]
1289
	cmp	ecx, [TASK_COUNT]
1290
	jbe	.next_pid
1290
	jbe	.next_pid
1291
 
1291
 
1292
; PID not found, TODO: close socket!
1292
; PID not found, TODO: close socket!
1293
 
1293
 
1294
	jmp	.error2
1294
	jmp	.error2
1295
 
1295
 
1296
       .found_pid:
1296
       .found_pid:
1297
	shl	ecx, 8
1297
	shl	ecx, 8
1298
	or	[ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
1298
	or	[ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
1299
	mov	[check_idle_semaphore], 200
1299
	mov	[check_idle_semaphore], 200
1300
 
1300
 
1301
	DEBUGF	1,"SOCKET_notify_owner: succes!\n"
1301
	DEBUGF	1,"SOCKET_notify_owner: succes!\n"
1302
 
1302
 
1303
  .error2:
1303
  .error2:
1304
	pop	esi ecx eax
1304
	pop	esi ecx eax
1305
 
1305
 
1306
  .error:
1306
  .error:
1307
 
1307
 
1308
	ret
1308
	ret
1309
 
1309
 
1310
 
1310
 
1311
;--------------------------------------------------------------------
1311
;--------------------------------------------------------------------
1312
;
1312
;
1313
; SOCKET_alloc
1313
; SOCKET_alloc
1314
;
1314
;
1315
; Allocate memory for socket data and put new socket into the list
1315
; Allocate memory for socket data and put new socket into the list
1316
; Newly created socket is initialized with calling PID and number and
1316
; Newly created socket is initialized with calling PID and number and
1317
; put into beginning of list (which is a fastest way).
1317
; put into beginning of list (which is a fastest way).
1318
;
1318
;
1319
; IN:  /
1319
; IN:  /
1320
; OUT: eax = 0 on error, socket ptr otherwise
1320
; OUT: eax = 0 on error, socket ptr otherwise
1321
;      edi = socket number
1321
;      edi = socket number
1322
;       ZF = cleared on error
1322
;       ZF = cleared on error
1323
;
1323
;
1324
;--------------------------------------------------------------------
1324
;--------------------------------------------------------------------
1325
align 4
1325
align 4
1326
SOCKET_alloc:
1326
SOCKET_alloc:
1327
 
1327
 
1328
	push	ecx ebx
1328
	push	ecx ebx
1329
 
1329
 
1330
	stdcall kernel_alloc, SOCKETBUFFSIZE
1330
	stdcall kernel_alloc, SOCKETBUFFSIZE
1331
	DEBUGF	1, "SOCKET_alloc: ptr=%x\n", eax
1331
	DEBUGF	1, "SOCKET_alloc: ptr=%x\n", eax
1332
	or	eax, eax
1332
	or	eax, eax
1333
	jz	.exit
1333
	jz	.exit
1334
 
1334
 
1335
; zero-initialize allocated memory
1335
; zero-initialize allocated memory
1336
	push	eax edi
1336
	push	eax edi
1337
	mov	edi, eax
1337
	mov	edi, eax
1338
	mov	ecx, SOCKETBUFFSIZE / 4
1338
	mov	ecx, SOCKETBUFFSIZE / 4
1339
	xor	eax, eax
1339
	xor	eax, eax
1340
	rep	stosd
1340
	rep	stosd
1341
	pop	edi eax
1341
	pop	edi eax
1342
 
1342
 
1343
; set send-and receive procedures to return -1
1343
; set send-and receive procedures to return -1
1344
	mov	[eax + SOCKET.snd_proc], s_error
1344
	mov	[eax + SOCKET.snd_proc], s_error
1345
	mov	[eax + SOCKET.rcv_proc], s_error
1345
	mov	[eax + SOCKET.rcv_proc], s_error
1346
 
1346
 
1347
; find first free socket number and use it
1347
; find first free socket number and use it
1348
	mov	ecx, [last_socket_num]
1348
	mov	ecx, [last_socket_num]
1349
  .next_socket_number:
1349
  .next_socket_number:
1350
	inc	ecx
1350
	inc	ecx
1351
	jz	.next_socket_number	; avoid socket nr 0
1351
	jz	.next_socket_number	; avoid socket nr 0
1352
	cmp	ecx, -1
1352
	cmp	ecx, -1
1353
	je	.next_socket_number	; avoid socket nr -1
1353
	je	.next_socket_number	; avoid socket nr -1
1354
	mov	ebx, net_sockets
1354
	mov	ebx, net_sockets
1355
  .next_socket:
1355
  .next_socket:
1356
	mov	ebx, [ebx + SOCKET.NextPtr]
1356
	mov	ebx, [ebx + SOCKET.NextPtr]
1357
	test	ebx, ebx
1357
	test	ebx, ebx
1358
	jz	.last_socket
1358
	jz	.last_socket
1359
 
1359
 
1360
	cmp	[ebx + SOCKET.Number], ecx
1360
	cmp	[ebx + SOCKET.Number], ecx
1361
	jne	.next_socket
1361
	jne	.next_socket
1362
	jmp	.next_socket_number
1362
	jmp	.next_socket_number
1363
 
1363
 
1364
  .last_socket:
1364
  .last_socket:
1365
	mov	[last_socket_num], ecx
1365
	mov	[last_socket_num], ecx
1366
	mov	[eax + SOCKET.Number], ecx
1366
	mov	[eax + SOCKET.Number], ecx
1367
	DEBUGF	1, "SOCKET_alloc: number=%u\n", ecx
1367
	DEBUGF	1, "SOCKET_alloc: number=%u\n", ecx
1368
	mov	edi, ecx
1368
	mov	edi, ecx
1369
 
1369
 
1370
; Fill in PID
1370
; Fill in PID
1371
	mov	ebx, [TASK_BASE]
1371
	mov	ebx, [TASK_BASE]
1372
	mov	ebx, [ebx + TASKDATA.pid]
1372
	mov	ebx, [ebx + TASKDATA.pid]
1373
	mov	[eax + SOCKET.PID], ebx
1373
	mov	[eax + SOCKET.PID], ebx
1374
 
1374
 
1375
; add socket to the list by re-arranging some pointers
1375
; add socket to the list by re-arranging some pointers
1376
	mov	ebx, [net_sockets + SOCKET.NextPtr]
1376
	mov	ebx, [net_sockets + SOCKET.NextPtr]
1377
 
1377
 
1378
	mov	[eax + SOCKET.PrevPtr], net_sockets
1378
	mov	[eax + SOCKET.PrevPtr], net_sockets
1379
	mov	[eax + SOCKET.NextPtr], ebx
1379
	mov	[eax + SOCKET.NextPtr], ebx
1380
 
1380
 
1381
	test	ebx, ebx
1381
	test	ebx, ebx
1382
	jz	@f
1382
	jz	@f
1383
	add	ebx, SOCKET.lock	; lock the next socket
1383
	add	ebx, SOCKET.lock	; lock the next socket
1384
	call	wait_mutex
1384
	call	wait_mutex
1385
	sub	ebx, SOCKET.lock
1385
	sub	ebx, SOCKET.lock
1386
	mov	[ebx + SOCKET.PrevPtr], eax
1386
	mov	[ebx + SOCKET.PrevPtr], eax
1387
	mov	[ebx + SOCKET.lock], 0	; and unlock it again
1387
	mov	[ebx + SOCKET.lock], 0	; and unlock it again
1388
       @@:
1388
       @@:
1389
 
1389
 
1390
	mov	[net_sockets + SOCKET.NextPtr], eax
1390
	mov	[net_sockets + SOCKET.NextPtr], eax
1391
	or	eax, eax		; used to clear zero flag
1391
	or	eax, eax		; used to clear zero flag
1392
  .exit:
1392
  .exit:
1393
	pop	ebx ecx
1393
	pop	ebx ecx
1394
 
1394
 
1395
	ret
1395
	ret
1396
 
1396
 
1397
 
1397
 
1398
;----------------------------------------------------
1398
;----------------------------------------------------
1399
;
1399
;
1400
; SOCKET_free
1400
; SOCKET_free
1401
;
1401
;
1402
; Free socket data memory and remove socket from the list
1402
; Free socket data memory and remove socket from the list
1403
;
1403
;
1404
; IN:  eax = socket ptr
1404
; IN:  eax = socket ptr
1405
; OUT: /
1405
; OUT: /
1406
;
1406
;
1407
;----------------------------------------------------
1407
;----------------------------------------------------
1408
align 4
1408
align 4
1409
SOCKET_free:
1409
SOCKET_free:
1410
 
1410
 
1411
	DEBUGF	1, "SOCKET_free: %x\n", eax
1411
	DEBUGF	1, "SOCKET_free: %x\n", eax
1412
 
1412
 
1413
	call	SOCKET_check
1413
	call	SOCKET_check
1414
	jz	.error
1414
	jz	.error
1415
 
1415
 
1416
	push	ebx
1416
	push	ebx
1417
	lea	ebx, [eax + SOCKET.lock]
1417
	lea	ebx, [eax + SOCKET.lock]
1418
	call	wait_mutex
1418
	call	wait_mutex
1419
 
1419
 
1420
	DEBUGF	1, "SOCKET_free: freeing socket..\n"
1420
	DEBUGF	1, "SOCKET_free: freeing socket..\n"
1421
 
1421
 
1422
	cmp	[eax + SOCKET.Domain], AF_INET4
1422
	cmp	[eax + SOCKET.Domain], AF_INET4
1423
	jnz	.no_tcp
1423
	jnz	.no_tcp
1424
 
1424
 
1425
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
1425
	cmp	[eax + SOCKET.Protocol], IP_PROTO_TCP
1426
	jnz	.no_tcp
1426
	jnz	.no_tcp
1427
 
1427
 
1428
	mov	ebx, eax
1428
	mov	ebx, eax
1429
	stdcall kernel_free, [ebx + STREAM_SOCKET.rcv + RING_BUFFER.start_ptr]
1429
	stdcall kernel_free, [ebx + STREAM_SOCKET.rcv + RING_BUFFER.start_ptr]
1430
	stdcall kernel_free, [ebx + STREAM_SOCKET.snd + RING_BUFFER.start_ptr]
1430
	stdcall kernel_free, [ebx + STREAM_SOCKET.snd + RING_BUFFER.start_ptr]
1431
	mov	eax, ebx
1431
	mov	eax, ebx
1432
  .no_tcp:
1432
  .no_tcp:
1433
 
1433
 
1434
	push	eax				; this will be passed to kernel_free
1434
	push	eax				; this will be passed to kernel_free
1435
	mov	ebx, [eax + SOCKET.NextPtr]
1435
	mov	ebx, [eax + SOCKET.NextPtr]
1436
	mov	eax, [eax + SOCKET.PrevPtr]
1436
	mov	eax, [eax + SOCKET.PrevPtr]
1437
 
1437
 
1438
	DEBUGF	1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx
1438
	DEBUGF	1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx
1439
 
1439
 
1440
	test	eax, eax
1440
	test	eax, eax
1441
	jz	@f
1441
	jz	@f
1442
	mov	[eax + SOCKET.NextPtr], ebx
1442
	mov	[eax + SOCKET.NextPtr], ebx
1443
       @@:
1443
       @@:
1444
 
1444
 
1445
	test	ebx, ebx
1445
	test	ebx, ebx
1446
	jz	@f
1446
	jz	@f
1447
	mov	[ebx + SOCKET.PrevPtr], eax
1447
	mov	[ebx + SOCKET.PrevPtr], eax
1448
       @@:
1448
       @@:
1449
 
1449
 
1450
	call	kernel_free
1450
	call	kernel_free
1451
	pop	ebx
1451
	pop	ebx
1452
 
1452
 
1453
	DEBUGF	1, "SOCKET_free: success!\n"
1453
	DEBUGF	1, "SOCKET_free: success!\n"
1454
 
1454
 
1455
  .error:
1455
  .error:
1456
	ret
1456
	ret
1457
 
1457
 
1458
;------------------------------------
1458
;------------------------------------
1459
;
1459
;
1460
; SOCKET_fork
1460
; SOCKET_fork
1461
;
1461
;
1462
; Create a child socket
1462
; Create a child socket
1463
;
1463
;
1464
; IN:  socket nr in ebx
1464
; IN:  socket nr in ebx
1465
; OUT: child socket nr in eax
1465
; OUT: child socket nr in eax
1466
;
1466
;
1467
;-----------------------------------
1467
;-----------------------------------
1468
align 4
1468
align 4
1469
SOCKET_fork:
1469
SOCKET_fork:
1470
 
1470
 
1471
	DEBUGF	1,"SOCKET_fork: %x\n", ebx
1471
	DEBUGF	1,"SOCKET_fork: %x\n", ebx
1472
 
1472
 
1473
; Exit if backlog queue is full
1473
; Exit if backlog queue is full
1474
	mov	eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size]
1474
	mov	eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size]
1475
	cmp	ax, [ebx + SOCKET.backlog]
1475
	cmp	ax, [ebx + SOCKET.backlog]
1476
	jae	.fail
1476
	jae	.fail
1477
 
1477
 
1478
; Allocate new socket
1478
; Allocate new socket
1479
	call	SOCKET_alloc
1479
	call	SOCKET_alloc
1480
	jz	.fail
1480
	jz	.fail
1481
 
1481
 
1482
	push	esi ecx edi
1482
	push	esi ecx edi
1483
	push	eax
1483
	push	eax
1484
	mov	esi, esp
1484
	mov	esi, esp
1485
	add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2
1485
	add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2
1486
	pop	eax
1486
	pop	eax
1487
 
1487
 
1488
; Copy structure from current socket to new
1488
; Copy structure from current socket to new
1489
; We start at PID to preserve the socket num, and the 2 pointers at beginning of socket
1489
; We start at PID to preserve the socket num, and the 2 pointers at beginning of socket
1490
	lea	esi, [ebx + SOCKET.PID]
1490
	lea	esi, [ebx + SOCKET.PID]
1491
	lea	edi, [eax + SOCKET.PID]
1491
	lea	edi, [eax + SOCKET.PID]
1492
	mov	ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4
1492
	mov	ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4
1493
	rep	movsd
1493
	rep	movsd
1494
 
1494
 
1495
	and	[eax + SOCKET.options], not SO_ACCEPTCON
1495
	and	[eax + SOCKET.options], not SO_ACCEPTCON
1496
	pop	edi ecx esi
1496
	pop	edi ecx esi
1497
 
1497
 
1498
	ret
1498
	ret
1499
 
1499
 
1500
  .fail2:
1500
  .fail2:
1501
	add	esp, 4+4+4
1501
	add	esp, 4+4+4
1502
  .fail:
1502
  .fail:
1503
	DEBUGF	1,"SOCKET_fork: failed\n"
1503
	DEBUGF	1,"SOCKET_fork: failed\n"
1504
	xor	eax, eax
1504
	xor	eax, eax
1505
	ret
1505
	ret
1506
 
1506
 
1507
 
1507
 
1508
;---------------------------------------------------
1508
;---------------------------------------------------
1509
;
1509
;
1510
; SOCKET_num_to_ptr
1510
; SOCKET_num_to_ptr
1511
;
1511
;
1512
; Get socket structure address by its number
1512
; Get socket structure address by its number
1513
;
1513
;
1514
; IN:  ecx = socket number
1514
; IN:  ecx = socket number
1515
; OUT: eax = 0 on error, socket ptr otherwise
1515
; OUT: eax = 0 on error, socket ptr otherwise
1516
;       ZF = set on error
1516
;       ZF = set on error
1517
;
1517
;
1518
;---------------------------------------------------
1518
;---------------------------------------------------
1519
align 4
1519
align 4
1520
SOCKET_num_to_ptr:
1520
SOCKET_num_to_ptr:
1521
 
1521
 
1522
	DEBUGF	1,"SOCKET_num_to_ptr: %u ", ecx
1522
	DEBUGF	1,"SOCKET_num_to_ptr: %u ", ecx
1523
 
1523
 
1524
	mov	eax, net_sockets
1524
	mov	eax, net_sockets
1525
 
1525
 
1526
  .next_socket:
1526
  .next_socket:
1527
	mov	eax, [eax + SOCKET.NextPtr]
1527
	mov	eax, [eax + SOCKET.NextPtr]
1528
	or	eax, eax
1528
	or	eax, eax
1529
	jz	.error
1529
	jz	.error
1530
	cmp	[eax + SOCKET.Number], ecx
1530
	cmp	[eax + SOCKET.Number], ecx
1531
	jne	.next_socket
1531
	jne	.next_socket
1532
 
1532
 
1533
	test	eax, eax
1533
	test	eax, eax
1534
 
1534
 
1535
	DEBUGF	1,"(%x)\n", eax
1535
	DEBUGF	1,"(%x)\n", eax
1536
  .error:
1536
  .error:
1537
	ret
1537
	ret
1538
 
1538
 
1539
 
1539
 
1540
;---------------------------------------------------
1540
;---------------------------------------------------
1541
;
1541
;
1542
; SOCKET_ptr_to_num
1542
; SOCKET_ptr_to_num
1543
;
1543
;
1544
; Get socket number by its address
1544
; Get socket number by its address
1545
;
1545
;
1546
; IN:  eax = socket ptr
1546
; IN:  eax = socket ptr
1547
; OUT: eax = 0 on error, socket num otherwise
1547
; OUT: eax = 0 on error, socket num otherwise
1548
;       ZF = set on error
1548
;       ZF = set on error
1549
;
1549
;
1550
;---------------------------------------------------
1550
;---------------------------------------------------
1551
align 4
1551
align 4
1552
SOCKET_ptr_to_num:
1552
SOCKET_ptr_to_num:
1553
 
1553
 
1554
	DEBUGF	1,"SOCKET_ptr_to_num: %x ", eax
1554
	DEBUGF	1,"SOCKET_ptr_to_num: %x ", eax
1555
 
1555
 
1556
	call	SOCKET_check
1556
	call	SOCKET_check
1557
	jz	.error
1557
	jz	.error
1558
 
1558
 
1559
	mov	eax, [eax + SOCKET.Number]
1559
	mov	eax, [eax + SOCKET.Number]
1560
 
1560
 
1561
	DEBUGF	1,"(%u)\n", eax
1561
	DEBUGF	1,"(%u)\n", eax
1562
 
1562
 
1563
  .error:
1563
  .error:
1564
	ret
1564
	ret
1565
 
1565
 
1566
 
1566
 
1567
;---------------------------------------------------
1567
;---------------------------------------------------
1568
;
1568
;
1569
; SOCKET_check
1569
; SOCKET_check
1570
;
1570
;
1571
; checks if the given value is really a socket ptr
1571
; checks if the given value is really a socket ptr
1572
;
1572
;
1573
; IN:  eax = socket ptr
1573
; IN:  eax = socket ptr
1574
; OUT: eax = 0 on error, unchanged otherwise
1574
; OUT: eax = 0 on error, unchanged otherwise
1575
;       ZF = set on error
1575
;       ZF = set on error
1576
;
1576
;
1577
;---------------------------------------------------
1577
;---------------------------------------------------
1578
align 4
1578
align 4
1579
SOCKET_check:
1579
SOCKET_check:
1580
 
1580
 
1581
	DEBUGF	1,"SOCKET_check: %x\n", eax
1581
	DEBUGF	1,"SOCKET_check: %x\n", eax
1582
 
1582
 
1583
	push	ebx
1583
	push	ebx
1584
	mov	ebx, net_sockets
1584
	mov	ebx, net_sockets
1585
 
1585
 
1586
  .next_socket:
1586
  .next_socket:
1587
	mov	ebx, [ebx + SOCKET.NextPtr]
1587
	mov	ebx, [ebx + SOCKET.NextPtr]
1588
	or	ebx, ebx
1588
	or	ebx, ebx
1589
	jz	.done
1589
	jz	.done
1590
	cmp	ebx, eax
1590
	cmp	ebx, eax
1591
	jnz	.next_socket
1591
	jnz	.next_socket
1592
 
1592
 
1593
  .done:
1593
  .done:
1594
	mov	eax, ebx
1594
	mov	eax, ebx
1595
	test	eax, eax
1595
	test	eax, eax
1596
	pop	ebx
1596
	pop	ebx
1597
 
1597
 
1598
	ret
1598
	ret
1599
 
1599
 
1600
 
1600
 
1601
 
1601
 
1602
;---------------------------------------------------
1602
;---------------------------------------------------
1603
;
1603
;
1604
; SOCKET_check_owner
1604
; SOCKET_check_owner
1605
;
1605
;
1606
; checks if the caller application owns the socket
1606
; checks if the caller application owns the socket
1607
;
1607
;
1608
; IN:  eax = socket ptr
1608
; IN:  eax = socket ptr
1609
; OUT:  ZF = true/false
1609
; OUT:  ZF = true/false
1610
;
1610
;
1611
;---------------------------------------------------
1611
;---------------------------------------------------
1612
align 4
1612
align 4
1613
SOCKET_check_owner:
1613
SOCKET_check_owner:
1614
 
1614
 
1615
	DEBUGF	1,"SOCKET_check_owner: %x\n", eax
1615
	DEBUGF	1,"SOCKET_check_owner: %x\n", eax
1616
 
1616
 
1617
	push	ebx
1617
	push	ebx
1618
	mov	ebx, [TASK_BASE]
1618
	mov	ebx, [TASK_BASE]
1619
	mov	ebx, [ecx + TASKDATA.pid]
1619
	mov	ebx, [ecx + TASKDATA.pid]
1620
	cmp	[eax + SOCKET.PID], ebx
1620
	cmp	[eax + SOCKET.PID], ebx
1621
	pop	 ebx
1621
	pop	 ebx
1622
 
1622
 
1623
	ret
1623
	ret
1624
 
1624
 
1625
 
1625
 
1626
 
1626
 
1627
 
1627
 
1628
;------------------------------------------------------
1628
;------------------------------------------------------
1629
;
1629
;
1630
; SOCKET_process_end
1630
; SOCKET_process_end
1631
;
1631
;
1632
; Kernel calls this function when a certain process ends
1632
; Kernel calls this function when a certain process ends
1633
; This function will check if the process had any open sockets
1633
; This function will check if the process had any open sockets
1634
; And update them accordingly
1634
; And update them accordingly
1635
;
1635
;
1636
; IN:  eax = pid
1636
; IN:  eax = pid
1637
; OUT: /
1637
; OUT: /
1638
;
1638
;
1639
;------------------------------------------------------
1639
;------------------------------------------------------
1640
align 4
1640
align 4
1641
SOCKET_process_end:
1641
SOCKET_process_end:
1642
 
1642
 
1643
	DEBUGF	1,"SOCKET_process_end: %x\n", eax
1643
	DEBUGF	1,"SOCKET_process_end: %x\n", eax
1644
 
1644
 
1645
	push	ebx
1645
	push	ebx
1646
	mov	ebx, net_sockets
1646
	mov	ebx, net_sockets
1647
 
1647
 
1648
  .next_socket:
1648
  .next_socket:
1649
 
1649
 
1650
	mov	ebx, [ebx + SOCKET.NextPtr]
1650
	mov	ebx, [ebx + SOCKET.NextPtr]
1651
  .test_socket:
1651
  .test_socket:
1652
	test	ebx, ebx
1652
	test	ebx, ebx
1653
	jz	.done
1653
	jz	.done
1654
 
1654
 
1655
	cmp	[ebx + SOCKET.PID], eax
1655
	cmp	[ebx + SOCKET.PID], eax
1656
	jne	.next_socket
1656
	jne	.next_socket
1657
 
1657
 
1658
	DEBUGF	1,"closing socket %x", eax, ebx
1658
	DEBUGF	1,"closing socket %x", eax, ebx
1659
 
1659
 
1660
	mov	[ebx + SOCKET.PID], 0
1660
	mov	[ebx + SOCKET.PID], 0
1661
 
1661
 
1662
	cmp	[ebx + SOCKET.Protocol], IP_PROTO_UDP
1662
	cmp	[ebx + SOCKET.Protocol], IP_PROTO_UDP
1663
	je	.udp
1663
	je	.udp
1664
 
1664
 
1665
	cmp	[ebx + SOCKET.Protocol], IP_PROTO_TCP
1665
	cmp	[ebx + SOCKET.Protocol], IP_PROTO_TCP
1666
	je	.tcp
1666
	je	.tcp
1667
 
1667
 
1668
	jmp	.next_socket	; kill all sockets for given PID
1668
	jmp	.next_socket	; kill all sockets for given PID
1669
 
1669
 
1670
  .udp:
1670
  .udp:
1671
	mov	eax, ebx
1671
	mov	eax, ebx
1672
	mov	ebx, [ebx + SOCKET.NextPtr]
1672
	mov	ebx, [ebx + SOCKET.NextPtr]
1673
	call	SOCKET_free
1673
	call	SOCKET_free
1674
	jmp	.test_socket
1674
	jmp	.test_socket
1675
 
1675
 
1676
  .tcp:
1676
  .tcp:
1677
 
1677
 
1678
	;;; TODO
1678
	;;; TODO
1679
 
1679
 
1680
	jmp	.next_socket
1680
	jmp	.next_socket
1681
 
1681
 
1682
  .done:
1682
  .done:
1683
	pop	ebx
1683
	pop	ebx
1684
 
1684
 
1685
	ret
1685
	ret
1686
 
1686
 
1687
 
1687
 
1688
 
1688
 
1689
 
1689
 
1690
;-----------------------------------------------------------------
1690
;-----------------------------------------------------------------
1691
;
1691
;
1692
; SOCKET_is_connecting
1692
; SOCKET_is_connecting
1693
;
1693
;
1694
;  IN:  eax = socket ptr
1694
;  IN:  eax = socket ptr
1695
;  OUT: /
1695
;  OUT: /
1696
;
1696
;
1697
;-----------------------------------------------------------------
1697
;-----------------------------------------------------------------
1698
 
1698
 
1699
align 4
1699
align 4
1700
SOCKET_is_connecting:
1700
SOCKET_is_connecting:
1701
 
1701
 
1702
 
1702
 
1703
	and	[eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING)
1703
	and	[eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING)
1704
	or	[eax + SOCKET.options], SS_ISCONNECTING
1704
	or	[eax + SOCKET.options], SS_ISCONNECTING
1705
 
1705
 
1706
	jmp	SOCKET_notify_owner
1706
	jmp	SOCKET_notify_owner
1707
 
1707
 
1708
 
1708
 
1709
 
1709
 
1710
;-----------------------------------------------------------------
1710
;-----------------------------------------------------------------
1711
;
1711
;
1712
; SOCKET_is_connected
1712
; SOCKET_is_connected
1713
;
1713
;
1714
;  IN:  eax = socket ptr
1714
;  IN:  eax = socket ptr
1715
;  OUT: /
1715
;  OUT: /
1716
;
1716
;
1717
;-----------------------------------------------------------------
1717
;-----------------------------------------------------------------
1718
 
1718
 
1719
align 4
1719
align 4
1720
SOCKET_is_connected:
1720
SOCKET_is_connected:
1721
 
1721
 
1722
 
1722
 
1723
	and	[eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING)
1723
	and	[eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING)
1724
	or	[eax + SOCKET.options], SS_ISCONNECTED
1724
	or	[eax + SOCKET.options], SS_ISCONNECTED
1725
 
1725
 
1726
	jmp	SOCKET_notify_owner
1726
	jmp	SOCKET_notify_owner
1727
 
1727
 
1728
 
1728
 
1729
 
1729
 
1730
 
1730
 
1731
;-----------------------------------------------------------------
1731
;-----------------------------------------------------------------
1732
;
1732
;
1733
; SOCKET_is_disconnecting
1733
; SOCKET_is_disconnecting
1734
;
1734
;
1735
;  IN:  eax = socket ptr
1735
;  IN:  eax = socket ptr
1736
;  OUT: /
1736
;  OUT: /
1737
;
1737
;
1738
;-----------------------------------------------------------------
1738
;-----------------------------------------------------------------
1739
 
1739
 
1740
align 4
1740
align 4
1741
SOCKET_is_disconnecting:
1741
SOCKET_is_disconnecting:
1742
 
1742
 
1743
	and	[eax + SOCKET.options], not (SS_ISCONNECTING)
1743
	and	[eax + SOCKET.options], not (SS_ISCONNECTING)
1744
	or	[eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE
1744
	or	[eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE
1745
 
1745
 
1746
	jmp	SOCKET_notify_owner
1746
	jmp	SOCKET_notify_owner
1747
 
1747
 
1748
 
1748
 
1749
 
1749
 
1750
;-----------------------------------------------------------------
1750
;-----------------------------------------------------------------
1751
;
1751
;
1752
; SOCKET_is_disconnected
1752
; SOCKET_is_disconnected
1753
;
1753
;
1754
;  IN:  eax = socket ptr
1754
;  IN:  eax = socket ptr
1755
;  OUT: /
1755
;  OUT: /
1756
;
1756
;
1757
;-----------------------------------------------------------------
1757
;-----------------------------------------------------------------
1758
 
1758
 
1759
align 4
1759
align 4
1760
SOCKET_is_disconnected:
1760
SOCKET_is_disconnected:
1761
 
1761
 
1762
	and	[eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING)
1762
	and	[eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING)
1763
	or	[eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE
1763
	or	[eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE
1764
 
1764
 
1765
	jmp	SOCKET_notify_owner
1765
	jmp	SOCKET_notify_owner
1766
 
1766
 
1767
 
1767
 
1768
;-----------------------------------------------------------------
1768
;-----------------------------------------------------------------
1769
;
1769
;
1770
; SOCKET_cant_recv_more
1770
; SOCKET_cant_recv_more
1771
;
1771
;
1772
;  IN:  eax = socket ptr
1772
;  IN:  eax = socket ptr
1773
;  OUT: /
1773
;  OUT: /
1774
;
1774
;
1775
;-----------------------------------------------------------------
1775
;-----------------------------------------------------------------
1776
 
1776
 
1777
align 4
1777
align 4
1778
SOCKET_cant_recv_more:
1778
SOCKET_cant_recv_more:
1779
 
1779
 
1780
	or	[eax + SOCKET.options], SS_CANTRCVMORE
1780
	or	[eax + SOCKET.options], SS_CANTRCVMORE
1781
 
1781
 
1782
	ret
1782
	ret
1783
 
1783
 
1784
 
1784
 
1785
 
1785
 
1786
;-----------------------------------------------------------------
1786
;-----------------------------------------------------------------
1787
;
1787
;
1788
; SOCKET_cant_send_more
1788
; SOCKET_cant_send_more
1789
;
1789
;
1790
;  IN:  eax = socket ptr
1790
;  IN:  eax = socket ptr
1791
;  OUT: /
1791
;  OUT: /
1792
;
1792
;
1793
;-----------------------------------------------------------------
1793
;-----------------------------------------------------------------
1794
 
1794
 
1795
align 4
1795
align 4
1796
SOCKET_cant_send_more:
1796
SOCKET_cant_send_more:
1797
 
1797
 
1798
	or	[eax + SOCKET.options], SS_CANTSENDMORE
1798
	or	[eax + SOCKET.options], SS_CANTSENDMORE
1799
 
1799
 
1800
	ret
1800
	ret