Subversion Repositories Kolibri OS

Rev

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

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