Subversion Repositories Kolibri OS

Rev

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

Rev 1196 Rev 1206
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2009. 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
;;  SOCKET.INC                                                     ;;
6
;;  SOCKET.INC                                                     ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;                                                                 ;;
8
;;                                                                 ;;
9
;;    Written by hidnplayr@kolibrios.org                           ;;
9
;;    Written by hidnplayr@kolibrios.org                           ;;
10
;;    based on code by mike.dld                                    ;;
10
;;    based on code by mike.dld                                    ;;
11
;;                                                                 ;;
11
;;                                                                 ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
13
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
16
 
17
$Revision: 1019 $
17
$Revision: 1206 $
18
 
18
 
19
align 4
19
align 4
20
struct	 SOCKET
20
struct	 SOCKET
21
	 .PrevPtr		dd ? ; pointer to previous socket in list
21
	 .PrevPtr		dd ? ; pointer to previous socket in list
22
	 .NextPtr		dd ? ; pointer to next socket in list
22
	 .NextPtr		dd ? ; pointer to next socket in list
23
	 .Number		dd ? ; socket number (unique within single process)
23
	 .Number		dd ? ; socket number (unique within single process)
24
	 .PID			dd ? ; application process id
24
	 .PID			dd ? ; application process id
25
	 .Domain		dd ? ; INET/UNIX/..
25
	 .Domain		dd ? ; INET/UNIX/..
26
	 .Type			dd ? ; RAW/UDP/TCP/...
26
	 .Type			dd ? ; RAW/UDP/TCP/...
27
	 .Protocol		dd ? ; ICMP/IPv4/ARP/
27
	 .Protocol		dd ? ; ICMP/IPv4/ARP/
28
	 .LocalIP		dd ? ; local IP address
28
	 .LocalIP		dd ? ; local IP address
29
	 .RemoteIP		dd ? ; remote IP address
29
	 .RemoteIP		dd ? ; remote IP address
30
	 .LocalPort		dw ? ; local port
30
	 .LocalPort		dw ? ; local port       (In INET byte order)
31
	 .RemotePort		dw ? ; remote port
31
	 .RemotePort		dw ? ; remote port      (IN INET byte order
32
	 .OrigRemoteIP		dd ? ; original remote IP address (used to reset to LISTEN state)
32
	 .OrigRemoteIP		dd ? ; original remote IP address (used to reset to LISTEN state)
33
	 .OrigRemotePort	dw ? ; original remote port (used to reset to LISTEN state)
33
	 .OrigRemotePort	dw ? ; original remote port (used to reset to LISTEN state)
34
	 .rxDataCount		dd ? ; rx data count
34
	 .rxDataCount		dd ? ; rx data count
35
	 .TCBState		dd ? ; TCB state
35
	 .TCBState		dd ? ; TCB state
36
	 .TCBTimer		dd ? ; TCB timer (seconds)
36
	 .TCBTimer		dd ? ; TCB timer (seconds)
37
	 .ISS			dd ? ; initial send sequence
37
	 .ISS			dd ? ; initial send sequence
38
	 .IRS			dd ? ; initial receive sequence
38
	 .IRS			dd ? ; initial receive sequence
39
	 .SND_UNA		dd ? ; sequence number of unack'ed sent Packets
39
	 .SND_UNA		dd ? ; sequence number of unack'ed sent Packets
40
	 .SND_NXT		dd ? ; bext send sequence number to use
40
	 .SND_NXT		dd ? ; bext send sequence number to use
41
	 .SND_WND		dd ? ; send window
41
	 .SND_WND		dd ? ; send window
42
	 .RCV_NXT		dd ? ; next receive sequence number to use
42
	 .RCV_NXT		dd ? ; next receive sequence number to use
43
	 .RCV_WND		dd ? ; receive window
43
	 .RCV_WND		dd ? ; receive window
44
	 .SEG_LEN		dd ? ; segment length
44
	 .SEG_LEN		dd ? ; segment length
45
	 .SEG_WND		dd ? ; segment window
45
	 .SEG_WND		dd ? ; segment window
46
	 .wndsizeTimer		dd ? ; window size timer
46
	 .wndsizeTimer		dd ? ; window size timer
47
	 .lock			dd ? ; lock mutex
47
	 .lock			dd ? ; lock mutex
48
	 .backlog		dw ? ; Backlog
48
	 .backlog		dw ? ; Backlog
49
	 .rxData:		     ; receive data buffer here
49
	 .rxData:		     ; receive data buffer here
50
ends
50
ends
51
 
51
 
52
MAX_backlog	equ 20
52
MAX_backlog	equ 20
53
 
53
 
54
; socket buffers
54
; socket buffers
55
SOCKETBUFFSIZE		equ 4096  ; state + config + buffer.
55
SOCKETBUFFSIZE		equ 4096  ; state + config + buffer.
56
SOCKETHEADERSIZE	equ SOCKET.rxData ; thus 4096 - SOCKETHEADERSIZE bytes data
56
SOCKETHEADERSIZE	equ SOCKET.rxData ; thus 4096 - SOCKETHEADERSIZE bytes data
57
 
57
 
58
uglobal
58
uglobal
59
	net_sockets	rd 2
59
	net_sockets	rd 2
60
	last_UDP_port	dw ? ; These values give the number of the last used ephemeral port
60
	last_UDP_port	dw ? ; These values give the number of the last used ephemeral port
61
	last_TCP_port	dw ? ;
61
	last_TCP_port	dw ? ;
62
endg
62
endg
63
 
63
 
64
 
64
 
65
;-----------------------------------------------
65
;-----------------------------------------------
66
;
66
;
67
; SOCKET_init
67
; SOCKET_init
68
;
68
;
69
;  -
69
;  -
70
;
70
;
71
;  IN:  /
71
;  IN:  /
72
;  OUT: /
72
;  OUT: /
73
;
73
;
74
;-----------------------------------------------
74
;-----------------------------------------------
75
 
75
 
76
align 4
76
align 4
77
socket_init:
77
socket_init:
78
 
78
 
79
	mov	[net_sockets], 0
79
	mov	[net_sockets], 0
80
	mov	[net_sockets + 4], 0
80
	mov	[net_sockets + 4], 0
81
 
81
 
82
	mov	[last_UDP_port], MIN_EPHEMERAL_PORT
82
	mov	[last_UDP_port], MIN_EPHEMERAL_PORT
83
	mov	[last_TCP_port], MIN_EPHEMERAL_PORT
83
	mov	[last_TCP_port], MIN_EPHEMERAL_PORT
84
 
84
 
85
	ret
85
	ret
86
 
86
 
87
 
87
 
88
;-----------------------------------------------------------------------------
88
;-----------------------------------------------------------------------------
89
;
89
;
90
; Socket API (function 74)
90
; Socket API (function 74)
91
;
91
;
92
;-----------------------------------------------------------------------------
92
;-----------------------------------------------------------------------------
93
 
93
 
94
align 4
94
align 4
95
sys_socket:
95
sys_socket:
96
 
96
 
97
	test	bl, bl
97
	test	bl, bl
98
	jz	socket_open	; 0
98
	jz	socket_open	; 0
99
	dec	bl
99
	dec	bl
100
	jz	socket_close	; 1
100
	jz	socket_close	; 1
101
	dec	bl
101
	dec	bl
102
	jz	socket_bind	; 2
102
	jz	socket_bind	; 2
103
	dec	bl
103
	dec	bl
104
	jz	socket_listen	; 3
104
	jz	socket_listen	; 3
105
	dec	bl
105
	dec	bl
106
	jz	socket_connect	; 4
106
	jz	socket_connect	; 4
107
	dec	bl
107
	dec	bl
108
	jz	socket_accept	; 5
108
	jz	socket_accept	; 5
109
	dec	bl
109
	dec	bl
110
	jz	socket_send	; 6
110
	jz	socket_send	; 6
111
	dec	bl
111
	dec	bl
112
	jz	socket_recv	; 7
112
	jz	socket_recv	; 7
113
 
113
 
114
s_error:
114
s_error:
115
	mov	dword [esp+32],-1
115
	mov	dword [esp+32],-1
116
 
116
 
117
	ret
117
	ret
118
 
118
 
119
 
119
 
120
 
120
 
121
 
121
 
122
;-----------------------------------------------
122
;-----------------------------------------------
123
;
123
;
124
; SOCKET_open
124
; SOCKET_open
125
;
125
;
126
;
126
;
127
;  IN:  domain in ecx
127
;  IN:  domain in ecx
128
;       type in edx
128
;       type in edx
129
;       protocol in esi
129
;       protocol in esi
130
;  OUT: eax is socket num, -1 on error
130
;  OUT: eax is socket num, -1 on error
131
;
131
;
132
;-----------------------------------------------
132
;-----------------------------------------------
-
 
133
align 4
133
socket_open:
134
socket_open:
134
 
135
 
135
	DEBUGF	1,"socket_open: domain: %u, type: %u",ecx, edx
136
	DEBUGF	1,"socket_open: domain: %u, type: %u",ecx, edx
136
 
137
 
137
	call	net_socket_alloc
138
	call	net_socket_alloc
138
	or	eax, eax
139
	or	eax, eax
139
	jz	s_error
140
	jz	s_error
140
 
141
 
141
	mov	[eax + SOCKET.Domain], ecx
142
	mov	[eax + SOCKET.Domain], ecx
142
	mov	[eax + SOCKET.Type], edx
143
	mov	[eax + SOCKET.Type], edx
143
	mov	[eax + SOCKET.Protocol], esi
144
	mov	[eax + SOCKET.Protocol], esi
144
 
145
 
145
	stdcall net_socket_addr_to_num, eax
146
	stdcall net_socket_addr_to_num, eax
146
	DEBUGF	1,", socketnumber: %u\n", eax
147
	DEBUGF	1,", socketnumber: %u\n", eax
147
 
148
 
148
	mov	[esp+32], eax
149
	mov	[esp+32], eax
149
 
150
 
150
	ret
151
	ret
151
 
152
 
152
 
153
 
153
 
154
 
154
 
155
 
155
;-----------------------------------------------
156
;-----------------------------------------------
156
;
157
;
157
; SOCKET_bind
158
; SOCKET_bind
158
;
159
;
159
;  IN:  socket number in ecx
160
;  IN:  socket number in ecx
160
;       pointer to sockaddr struct in edx
161
;       pointer to sockaddr struct in edx
161
;       length of that struct in esi
162
;       length of that struct in esi
162
;  OUT: 0 on success
163
;  OUT: 0 on success
163
;
164
;
164
;-----------------------------------------------
165
;-----------------------------------------------
165
 
166
align 4
166
socket_bind:
167
socket_bind:
167
 
168
 
168
	DEBUGF	1,"Socket_bind: socknum: %u sockaddr: %x, length: %u, ",ecx,edx,esi
169
	DEBUGF	1,"Socket_bind: socknum: %u sockaddr: %x, length: %u, ",ecx,edx,esi
169
 
170
 
170
	stdcall net_socket_num_to_addr, ecx
171
	stdcall net_socket_num_to_addr, ecx
171
	cmp	eax, -1
172
	cmp	eax, -1
172
	jz	s_error
173
	jz	s_error
173
 
174
 
174
	cmp	esi, 2
175
	cmp	esi, 2
175
	jl	s_error
176
	jl	s_error
176
 
177
 
177
	cmp	word [edx], AF_INET4
178
	cmp	word [edx], AF_INET4
178
	je	.af_inet4
-
 
179
 
-
 
180
	jmp	s_error
179
	jne	s_error
181
 
180
 
182
  .af_inet4:
181
  .af_inet4:
183
 
182
 
184
	cmp	esi, 6
183
	cmp	esi, 6
185
	jl	s_error
184
	jl	s_error
-
 
185
 
186
 
186
	mov	ecx, [eax + SOCKET.Type]
187
	mov	bx, word [edx + 2]
-
 
188
	rol	bx,8			;;;
187
	mov	bx, word [edx + 2]
189
	DEBUGF	1,"local port: %u ",bx
188
	DEBUGF	1,"local port: %x ",bx
190
	test	bx, bx
189
	test	bx, bx
191
	jnz	.check_only
-
 
192
 
-
 
193
	mov	bx , [last_UDP_port]
-
 
194
 
-
 
195
  .find_port_loop:
-
 
196
	inc	bx
-
 
197
	inc	[last_UDP_port]
-
 
198
 
-
 
199
  .check_only:
-
 
200
	mov	esi, net_sockets
-
 
201
 
-
 
202
  .next_udp_socket:
-
 
203
	mov	esi, [esi + SOCKET.NextPtr]
-
 
204
	or	esi, esi
-
 
205
	jz	.udp_port_ok
-
 
206
 
-
 
207
	cmp	[esi + SOCKET.Type], IP_PROTO_UDP
-
 
208
	jne	.next_udp_socket
-
 
209
 
190
	jz	.find_free
210
	cmp	[esi + SOCKET.LocalPort], bx
-
 
211
	jne	.next_udp_socket
191
 
212
 
192
	call	socket_check_port
-
 
193
	test	bx, bx
213
	cmp	word [edx + 2], 0
-
 
214
	jne	s_error
194
	je	s_error
215
 
195
	jmp	.got_port
-
 
196
 
216
	cmp	bx, MAX_EPHEMERAL_PORT
197
  .find_free:
217
	jle	.find_port_loop
198
 
-
 
199
	call	socket_find_port
218
 
200
	test	bx, bx
219
	mov	[last_UDP_port], MIN_EPHEMERAL_PORT
201
	je	s_error
220
	jmp	s_error
202
 
221
 
203
  .got_port:
222
  .udp_port_ok:
204
	DEBUGF	1,"using port: %x ",bx
223
	mov	word [eax + SOCKET.LocalPort], bx
205
	mov	word [eax + SOCKET.LocalPort], bx
224
 
206
 
225
	mov	ebx, dword [edx + 4]
207
	mov	ebx, dword [edx + 4]
226
	mov	dword [eax + SOCKET.LocalIP], ebx
208
	mov	dword [eax + SOCKET.LocalIP], ebx
227
 
209
 
228
	DEBUGF	1,"local ip: %u.%u.%u.%u\n",\
210
	DEBUGF	1,"local ip: %u.%u.%u.%u\n",\
229
	[eax + SOCKET.LocalIP]:1,[eax + SOCKET.LocalIP + 1]:1,[eax + SOCKET.LocalIP + 2]:1,[eax + SOCKET.LocalIP + 3]:1
211
	[eax + SOCKET.LocalIP]:1,[eax + SOCKET.LocalIP + 1]:1,[eax + SOCKET.LocalIP + 2]:1,[eax + SOCKET.LocalIP + 3]:1
230
 
212
 
231
	mov	dword [esp+32],0
213
	mov	dword [esp+32],0
232
	ret
214
	ret
233
 
215
 
234
 
216
 
235
 
217
 
236
 
218
 
237
;-----------------------------------------------
219
;-----------------------------------------------
238
;
220
;
239
; SOCKET_connect
221
; SOCKET_connect
240
;
222
;
241
;
223
;
242
;  IN:  socket number in ecx
224
;  IN:  socket number in ecx
243
;       pointer to sockaddr struct in edx
225
;       pointer to sockaddr struct in edx
244
;       length of that struct in esi
226
;       length of that struct in esi
245
;  OUT: 0 on success
227
;  OUT: 0 on success
246
;
228
;
247
;-----------------------------------------------
229
;-----------------------------------------------
248
align 4
230
align 4
249
 
-
 
250
socket_connect:
231
socket_connect:
251
 
232
 
252
	DEBUGF	1,"Socket_connect: socknum: %u sockaddr: %x, length: %u,",ecx,edx,esi
233
	DEBUGF	1,"Socket_connect: socknum: %u sockaddr: %x, length: %u,",ecx,edx,esi
253
 
234
 
254
	stdcall net_socket_num_to_addr, ecx
235
	stdcall net_socket_num_to_addr, ecx
255
	cmp	eax, -1
236
	cmp	eax, -1
256
	jz	s_error
237
	jz	s_error
257
 
238
 
258
	cmp	esi, 2
239
	cmp	esi, 2
259
	jl	s_error
240
	jl	s_error
260
 
241
 
261
	cmp	word [edx], AF_INET4
242
	cmp	word [edx], AF_INET4
262
	je	.af_inet4
243
	je	.af_inet4
263
 
244
 
264
	jmp	s_error
245
	jmp	s_error
265
 
246
 
266
  .af_inet4:
247
  .af_inet4:
267
 
248
 
268
	cmp	esi, 8
249
	cmp	esi, 8
269
	jl	s_error
250
	jl	s_error
270
 
251
 
271
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
252
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
272
	je	.udp
253
	je	.udp
273
 
254
 
274
	cmp	[eax + SOCKET.Type], IP_PROTO_ICMP
255
	cmp	[eax + SOCKET.Type], IP_PROTO_ICMP
275
	je	.icmp
256
	je	.icmp
276
 
257
 
277
;        cmp     [eax + SOCKET.Type], IP_PROTO_TCP
258
	cmp	[eax + SOCKET.Type], IP_PROTO_TCP
278
;        je      .tcp
259
	je	.tcp
279
 
260
 
280
	jmp	s_error
261
	jmp	s_error
281
 
262
 
282
  .udp:
263
  .udp:
283
 
264
 
284
	mov	bx , word [edx + 2]
265
	mov	bx , word [edx + 2]
285
	rol	bx, 8
-
 
286
	mov	word [eax + SOCKET.RemotePort], bx
266
	mov	word [eax + SOCKET.RemotePort], bx
287
 
-
 
288
	DEBUGF	1,"remote port: %u ",bx
267
	DEBUGF	1,"remote port: %x ",bx
289
 
268
 
290
	mov	ebx, dword [edx + 4]
269
	mov	ebx, dword [edx + 4]
291
	mov	dword [eax + SOCKET.RemoteIP], ebx
270
	mov	dword [eax + SOCKET.RemoteIP], ebx
292
 
-
 
293
	DEBUGF	1,"remote ip: %u.%u.%u.%u\n",[edx+4]:1,[edx+5]:1,[edx+6]:1,[edx+7]:1
271
	DEBUGF	1,"remote ip: %u.%u.%u.%u\n",[edx+4]:1,[edx+5]:1,[edx+6]:1,[edx+7]:1
294
 
272
 
295
	mov	dword [esp+32],0
273
	mov	dword [esp+32],0
296
	ret
274
	ret
297
 
275
 
298
  .icmp:
276
  .icmp:
299
 
277
 
300
 
278
 
301
	ret
279
	ret
302
 
280
 
303
 
281
 
304
 
282
 
305
  .tcp:
283
  .tcp:
306
 
284
 
307
;local sockAddr dd ?
285
;local sockAddr dd ?
308
 
286
 
309
;        cmp     esi, SOCKET_PASSIVE
287
;        cmp     esi, SOCKET_PASSIVE
310
;        jne     .skip_port_check
288
;        jne     .skip_port_check
311
;
289
;
312
;        push    ebx
290
;        push    ebx
313
;        mov     eax, ebx
291
;        mov     eax, ebx
314
;        xchg    al, ah
292
;        xchg    al, ah
315
;        mov     ebx, net_sockets
293
;        mov     ebx, net_sockets
316
;
294
;
317
;  .next_socket:
295
;  .next_socket:
318
;        mov     ebx, [ebx + SOCKET.NextPtr]
296
;        mov     ebx, [ebx + SOCKET.NextPtr]
319
;        or      ebx, ebx
297
;        or      ebx, ebx
320
;        jz      .last_socket
298
;        jz      .last_socket
321
;        cmp     [ebx + SOCKET.TCBState], TCB_LISTEN
299
;        cmp     [ebx + SOCKET.TCBState], TCB_LISTEN
322
;        jne     .next_socket
300
;        jne     .next_socket
323
;        cmp     [ebx + SOCKET.LocalPort], ax
301
;        cmp     [ebx + SOCKET.LocalPort], ax
324
;        jne     .next_socket
302
;        jne     .next_socket
325
;
303
;
326
;        xchg    al, ah
304
;        xchg    al, ah
327
;        DEBUGF  1, "K : error: port %u is listened by 0x%x\n", ax, ebx
305
;        DEBUGF  1, "K : error: port %u is listened by 0x%x\n", ax, ebx
328
;        pop     ebx
306
;        pop     ebx
329
;        jmp     .error
307
;        jmp     .error
330
;
308
;
331
;  .last_socket:
309
;  .last_socket:
332
;        pop     ebx
310
;        pop     ebx
333
;
311
;
334
;  .skip_port_check:
312
;  .skip_port_check:
335
 
313
 
336
;        mov     [eax + SOCKET.wndsizeTimer], 0     ; Reset the window timer.
314
;        mov     [eax + SOCKET.wndsizeTimer], 0     ; Reset the window timer.
337
;
315
;
338
;        xchg    bh, bl
316
;        xchg    bh, bl
339
;        mov     [eax + SOCKET.LocalPort], bx
317
;        mov     [eax + SOCKET.LocalPort], bx
340
;        xchg    ch, cl
318
;        xchg    ch, cl
341
;        mov     [eax + SOCKET.RemotePort], cx
319
;        mov     [eax + SOCKET.RemotePort], cx
342
;        mov     [eax + SOCKET.OrigRemotePort], cx
320
;        mov     [eax + SOCKET.OrigRemotePort], cx
343
;        mov     ebx, [IP_LIST]
321
;        mov     ebx, [IP_LIST]
344
;        mov     [eax + SOCKET.LocalIP], ebx
322
;        mov     [eax + SOCKET.LocalIP], ebx
345
;        mov     [eax + SOCKET.RemoteIP], edx
323
;        mov     [eax + SOCKET.RemoteIP], edx
346
;        mov     [eax + SOCKET.OrigRemoteIP], edx
324
;        mov     [eax + SOCKET.OrigRemoteIP], edx
347
 
325
 
348
;        mov     ebx, TCB_LISTEN
326
;        mov     ebx, TCB_LISTEN
349
;        cmp     esi, SOCKET_PASSIVE
327
;        cmp     esi, SOCKET_PASSIVE
350
;        je      @f
328
;        je      @f
351
;        mov     ebx, TCB_SYN_SENT
329
;        mov     ebx, TCB_SYN_SENT
352
;    @@: mov     [eax + SOCKET.TCBState], ebx            ; Indicate the state of the TCB
330
;    @@: mov     [eax + SOCKET.TCBState], ebx            ; Indicate the state of the TCB
353
 
331
 
354
;        cmp     ebx, TCB_LISTEN
332
;        cmp     ebx, TCB_LISTEN
355
;        je      .exit
333
;        je      .exit
356
 
334
 
357
	; Now, if we are in active mode, then we have to send a SYN to the specified remote port
335
	; Now, if we are in active mode, then we have to send a SYN to the specified remote port
358
;        mov     eax, EMPTY_QUEUE
336
;        mov     eax, EMPTY_QUEUE
359
;        call    dequeue
337
;        call    dequeue
360
;        cmp     ax, NO_BUFFER
338
;        cmp     ax, NO_BUFFER
361
;        je      .exit
339
;        je      .exit
362
 
340
 
363
;        push    eax
341
;        push    eax
364
 
342
 
365
;        mov     bl, TH_SYN
343
;        mov     bl, TH_SYN
366
;        xor     ecx, ecx
344
;        xor     ecx, ecx
367
;        stdcall build_tcp_Packet, [sockAddr]
345
;        stdcall build_tcp_Packet, [sockAddr]
368
 
346
 
369
;        mov     eax, NET1OUT_QUEUE
347
;        mov     eax, NET1OUT_QUEUE
370
;        mov     edx, [IP_LIST]
348
;        mov     edx, [IP_LIST]
371
;        mov     ecx, [sockAddr]
349
;        mov     ecx, [sockAddr]
372
;        cmp     edx, [ecx + SOCKET.RemoteIP]
350
;        cmp     edx, [ecx + SOCKET.RemoteIP]
373
;        jne     .not_local
351
;        jne     .not_local
374
;        mov     eax, IPIN_QUEUE
352
;        mov     eax, IPIN_QUEUE
375
 
353
 
376
;  .not_local:
354
;  .not_local:
377
	; Send it.
355
	; Send it.
378
;        pop     ebx
356
;        pop     ebx
379
;        call    queue
357
;        call    queue
380
 
358
 
381
  .exit:
359
  .exit:
382
	xor	eax, eax
360
	xor	eax, eax
383
	ret
361
	ret
384
 
362
 
385
 
363
 
386
 
364
 
387
 
365
 
388
;-----------------------------------------------
366
;-----------------------------------------------
389
;
367
;
390
; SOCKET_listen
368
; SOCKET_listen
391
;
369
;
392
;
370
;
393
;  IN:  socket number in ecx
371
;  IN:  socket number in ecx
394
;       backlog in edx
372
;       backlog in edx
395
;  OUT: eax is socket num, -1 on error
373
;  OUT: eax is socket num, -1 on error
396
;
374
;
397
;-----------------------------------------------
375
;-----------------------------------------------
398
 
376
align 4
399
socket_listen:
377
socket_listen:
400
 
378
 
401
	DEBUGF	1,"Socket_listen: socknum: %u backlog: %u\n",ecx,edx
379
	DEBUGF	1,"Socket_listen: socknum: %u backlog: %u\n",ecx,edx
402
 
380
 
403
	stdcall net_socket_num_to_addr, ecx
381
	stdcall net_socket_num_to_addr, ecx
404
	cmp	eax, -1
382
	cmp	eax, -1
405
	jz	s_error
383
	jz	s_error
406
 
384
 
407
	cmp	edx, MAX_backlog
385
	cmp	edx, MAX_backlog
408
	jl	.ok
386
	jl	.ok
409
	mov	dx , 20
387
	mov	dx , 20
410
  .ok:
388
  .ok:
411
 
389
 
412
	mov	[eax + SOCKET.backlog], dx
390
	mov	[eax + SOCKET.backlog], dx
413
 
391
 
414
	; TODO: insert code for active connections like TCP
392
	; TODO: insert code for active connections like TCP
415
 
393
 
416
	mov	dword [esp+32], 0
394
	mov	dword [esp+32], 0
417
	ret
395
	ret
418
 
396
 
419
 
397
 
420
 
398
 
421
 
399
 
422
 
400
 
423
 
401
 
424
;-----------------------------------------------
402
;-----------------------------------------------
425
;
403
;
426
; SOCKET_accept
404
; SOCKET_accept
427
;
405
;
428
;
406
;
429
;  IN:  socket number in ecx
407
;  IN:  socket number in ecx
430
;       addr in edx
408
;       addr in edx
431
;       addrlen in esi
409
;       addrlen in esi
432
;  OUT: eax is socket num, -1 on error
410
;  OUT: eax is socket num, -1 on error
433
;
411
;
434
;-----------------------------------------------
412
;-----------------------------------------------
435
 
-
 
436
 
413
align 4
437
socket_accept:
414
socket_accept:
438
 
415
 
439
	DEBUGF	1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n",ecx,edx,esi
416
	DEBUGF	1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n",ecx,edx,esi
440
 
417
 
441
	stdcall net_socket_num_to_addr, ecx
418
	stdcall net_socket_num_to_addr, ecx
442
	or	eax, eax
419
	or	eax, eax
443
	jz	s_error
420
	jz	s_error
444
	mov	esi, eax
421
	mov	esi, eax
445
 
422
 
446
	cmp	[esi + SOCKET.backlog], 0
423
	cmp	[esi + SOCKET.backlog], 0
447
	jz	s_error
424
	jz	s_error
448
 
425
 
449
	call	net_socket_alloc
426
	call	net_socket_alloc
450
	or	eax, eax
427
	or	eax, eax
451
	jz	s_error
428
	jz	s_error
452
	mov	edi, eax
429
	mov	edi, eax
453
 
430
 
454
	dec	[esi + SOCKET.backlog]
431
	dec	[esi + SOCKET.backlog]
455
 
432
 
456
	mov	ecx, (SOCKET.rxData+3)/4
433
	mov	ecx, (SOCKET.rxData+3)/4
457
	rep	movsd
434
	rep	movsd
458
 
435
 
459
	mov	[edi + SOCKET.backlog], 0
436
	mov	[edi + SOCKET.backlog], 0
460
 
437
 
461
	; TODO: fill in structure in ecx
438
	; TODO: fill in structure in ecx
462
 
439
 
463
	mov	[esi + SOCKET.RemoteIP], 0
440
	mov	[esi + SOCKET.RemoteIP], 0
464
	mov	[esi + SOCKET.RemotePort], 0
441
	mov	[esi + SOCKET.RemotePort], 0
465
 
442
 
466
	stdcall net_socket_addr_to_num, eax
443
	stdcall net_socket_addr_to_num, eax
467
	mov	[esp+32], eax
444
	mov	[esp+32], eax
468
 
445
 
469
	ret
446
	ret
470
 
447
 
471
 
448
 
472
 
449
 
473
;-----------------------------------------------
450
;-----------------------------------------------
474
;
451
;
475
; SOCKET_close
452
; SOCKET_close
476
;
453
;
477
;
454
;
478
;  IN:  socket number in ecx
455
;  IN:  socket number in ecx
479
;  OUT: eax is socket num, -1 on error
456
;  OUT: eax is socket num, -1 on error
480
;
457
;
481
;-----------------------------------------------
458
;-----------------------------------------------
482
 
459
align 4
483
socket_close:
460
socket_close:
484
 
461
 
485
	DEBUGF	1,"Socket_close: socknum: %u\n",ecx
462
	DEBUGF	1,"Socket_close: socknum: %u\n",ecx
486
 
463
 
487
	stdcall net_socket_num_to_addr, ecx
464
	stdcall net_socket_num_to_addr, ecx
488
	or	eax, eax
465
	or	eax, eax
489
	jz	s_error
466
	jz	s_error
490
 
467
 
491
 
468
 
492
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
469
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
493
	je	.udp
470
	je	.udp
494
 
471
 
495
	cmp	[eax + SOCKET.Type], IP_PROTO_ICMP
472
	cmp	[eax + SOCKET.Type], IP_PROTO_ICMP
496
	je	.icmp
473
	je	.icmp
497
 
474
 
498
;        cmp     [eax + SOCKET.Type], IP_PROTO_TCP
475
	cmp	[eax + SOCKET.Type], IP_PROTO_TCP
499
;        je      .tcp
476
	je	.tcp
500
 
477
 
501
	jmp	s_error
478
	jmp	s_error
502
 
479
 
503
  .udp:
480
  .udp:
504
 
481
 
505
	lea	ebx, [eax + SOCKET.lock]
482
	lea	ebx, [eax + SOCKET.lock]
506
	call	wait_mutex
483
	call	wait_mutex
507
	; TODO: mark the socket for deletion, using the mutex
484
	; TODO: mark the socket for deletion, using the mutex
508
 
485
 
509
	stdcall net_socket_free, eax
486
	stdcall net_socket_free, eax
510
 
487
 
511
	mov	dword [esp+32],0
488
	mov	dword [esp+32],0
512
	ret
489
	ret
513
 
490
 
514
 
491
 
515
  .icmp:
492
  .icmp:
516
 
493
 
517
 
494
 
518
 
495
 
519
	ret
496
	ret
520
 
497
 
521
  .tcp:
498
  .tcp:
522
 
499
 
523
if 1 = 0
500
if 1 = 0
524
;local sockAddr dd ?
501
;local sockAddr dd ?
525
 
502
 
526
;        DEBUGF  1, "K : socket_close_tcp (0x%x)\n", ebx
503
;        DEBUGF  1, "K : socket_close_tcp (0x%x)\n", ebx
527
	; first, remove any resend entries
504
	; first, remove any resend entries
528
	pusha
505
	pusha
529
 
506
 
530
	mov	esi, resendQ
507
	mov	esi, resendQ
531
	mov	ecx, 0
508
	mov	ecx, 0
532
 
509
 
533
  .next_resendq:
510
  .next_resendq:
534
	cmp	ecx, NUMRESENDENTRIES
511
	cmp	ecx, NUMRESENDENTRIES
535
	je	.last_resendq	    ; None left
512
	je	.last_resendq	    ; None left
536
	cmp	[esi + 4], ebx
513
	cmp	[esi + 4], ebx
537
	je	@f		    ; found one
514
	je	@f		    ; found one
538
	inc	ecx
515
	inc	ecx
539
	add	esi, 8
516
	add	esi, 8
540
	jmp	.next_resendq
517
	jmp	.next_resendq
541
 
518
 
542
    @@: mov	dword[esi + 4], 0
519
    @@: mov	dword[esi + 4], 0
543
	inc	ecx
520
	inc	ecx
544
	add	esi, 8
521
	add	esi, 8
545
	jmp	.next_resendq
522
	jmp	.next_resendq
546
 
523
 
547
  .last_resendq:
524
  .last_resendq:
548
	popa
525
	popa
549
 
526
 
550
	mov	ebx, eax
527
	mov	ebx, eax
551
;        mov     [sockAddr], eax
528
;        mov     [sockAddr], eax
552
 
529
 
553
	cmp	[eax + SOCKET.TCBState], TCB_LISTEN
530
	cmp	[eax + SOCKET.TCBState], TCB_LISTEN
554
	je	.destroy_tcb
531
	je	.destroy_tcb
555
	cmp	[eax + SOCKET.TCBState], TCB_SYN_SENT
532
	cmp	[eax + SOCKET.TCBState], TCB_SYN_SENT
556
	je	.destroy_tcb
533
	je	.destroy_tcb
557
 
534
 
558
; Now construct the response, and queue for sending by IP
535
; Now construct the response, and queue for sending by IP
559
	mov	eax, EMPTY_QUEUE
536
	mov	eax, EMPTY_QUEUE
560
	call	dequeue
537
	call	dequeue
561
	cmp	ax, NO_BUFFER
538
	cmp	ax, NO_BUFFER
562
	je	.error
539
	je	.error
563
 
540
 
564
	push	eax
541
	push	eax
565
 
542
 
566
	mov	bl, TH_FIN
543
	mov	bl, TH_FIN
567
	xor	ecx, ecx
544
	xor	ecx, ecx
568
	xor	esi, esi
545
	xor	esi, esi
569
	stdcall build_tcp_Packet, [sockAddr]
546
	stdcall build_tcp_Packet, [sockAddr]
570
 
547
 
571
	mov	 ebx, [sockAddr]
548
	mov	 ebx, [sockAddr]
572
	; increament SND.NXT in socket
549
	; increament SND.NXT in socket
573
	lea	esi, [ebx + SOCKET.SND_NXT]
550
	lea	esi, [ebx + SOCKET.SND_NXT]
574
	call	inc_inet_esi
551
	call	inc_inet_esi
575
 
552
 
576
	; Get the socket state
553
	; Get the socket state
577
	mov	eax, [ebx + SOCKET.TCBState]
554
	mov	eax, [ebx + SOCKET.TCBState]
578
	cmp	eax, TCB_SYN_RECEIVED
555
	cmp	eax, TCB_SYN_RECEIVED
579
	je	.fin_wait_1
556
	je	.fin_wait_1
580
	cmp	eax, TCB_ESTABLISHED
557
	cmp	eax, TCB_ESTABLISHED
581
	je	.fin_wait_1
558
	je	.fin_wait_1
582
 
559
 
583
	; assume CLOSE WAIT
560
	; assume CLOSE WAIT
584
	; Send a fin, then enter last-ack state
561
	; Send a fin, then enter last-ack state
585
	mov	[ebx + SOCKET.TCBState], TCB_LAST_ACK
562
	mov	[ebx + SOCKET.TCBState], TCB_LAST_ACK
586
	jmp	.send
563
	jmp	.send
587
 
564
 
588
  .fin_wait_1:
565
  .fin_wait_1:
589
	; Send a fin, then enter finwait2 state
566
	; Send a fin, then enter finwait2 state
590
	mov	[ebx + SOCKET.TCBState], TCB_FIN_WAIT_1
567
	mov	[ebx + SOCKET.TCBState], TCB_FIN_WAIT_1
591
 
568
 
592
  .send:
569
  .send:
593
	mov	eax, NET1OUT_QUEUE
570
	mov	eax, NET1OUT_QUEUE
594
	mov	edx, [IP_LIST]
571
	mov	edx, [IP_LIST]
595
;        mov     ecx, [sockAddr]
572
;        mov     ecx, [sockAddr]
596
	cmp	edx, [ecx + SOCKET.RemoteIP]
573
	cmp	edx, [ecx + SOCKET.RemoteIP]
597
	jne	.not_local
574
	jne	.not_local
598
	mov	eax, IPIN_QUEUE
575
	mov	eax, IPIN_QUEUE
599
 
576
 
600
  .not_local:
577
  .not_local:
601
	; Send it.
578
	; Send it.
602
	pop	ebx
579
	pop	ebx
603
	call	queue
580
	call	queue
604
	jmp	.exit
581
	jmp	.exit
605
 
582
 
606
 
583
 
607
  .destroy_tcb:
584
  .destroy_tcb:
608
 
585
 
609
	stdcall net_socket_free, eax
586
	stdcall net_socket_free, eax
610
 
587
 
611
end if
588
end if
612
 
589
 
613
  .exit:
590
  .exit:
614
	mov	dword [esp+32],0
591
	mov	dword [esp+32],0
615
	ret
592
	ret
616
 
593
 
617
 
594
 
618
 
595
 
619
 
596
 
620
;-----------------------------------------------
597
;-----------------------------------------------
621
;
598
;
622
; SOCKET_receive
599
; SOCKET_receive
623
;
600
;
624
;
601
;
625
;  IN:  socket number in ecx
602
;  IN:  socket number in ecx
626
;       addr in edx
603
;       addr in edx
627
;       addrlen in esi
604
;       addrlen in esi
628
;       flags in edi
605
;       flags in edi
629
;  OUT: eax is number of bytes copied, -1 on error
606
;  OUT: eax is number of bytes copied, -1 on error
630
;
607
;
631
;-----------------------------------------------
608
;-----------------------------------------------
632
 
609
align 4
633
socket_recv:
610
socket_recv:
634
 
611
 
635
	DEBUGF	1,"Socket_receive: socknum: %u sockaddr: %x, length: %u, flags: %x\n",ecx,edx,esi,edi
612
	DEBUGF	1,"Socket_receive: socknum: %u sockaddr: %x, length: %u, flags: %x\n",ecx,edx,esi,edi
636
 
613
 
637
	stdcall net_socket_num_to_addr, ecx		   ; get real socket address
614
	stdcall net_socket_num_to_addr, ecx		   ; get real socket address
638
	or	eax, eax
615
	or	eax, eax
639
	jz	s_error
616
	jz	s_error
640
 
617
 
641
	DEBUGF 1,"real socket address:%x\n", eax
618
	DEBUGF 1,"real socket address:%x\n", eax
642
 
619
 
643
	mov	dword[esp+32], -1
620
	mov	dword[esp+32], -1
644
 
621
 
645
	mov	edi, edx
622
	mov	edi, edx
646
 
623
 
647
	lea	ebx, [eax + SOCKET.lock]
624
	lea	ebx, [eax + SOCKET.lock]
648
	call	wait_mutex
625
	call	wait_mutex
649
 
626
 
650
	mov	ecx, [eax + SOCKET.rxDataCount] 	   ; get count of bytes
627
	mov	ecx, [eax + SOCKET.rxDataCount] 	   ; get count of bytes
651
	DEBUGF 1,"bytes in socket:%u\n", ecx
628
	DEBUGF 1,"bytes in socket:%u\n", ecx
652
	test	ecx, ecx				   ; if count of bytes is zero..
629
	test	ecx, ecx				   ; if count of bytes is zero..
653
	jz	.exit					   ; exit function (eax will be zero)
630
	jz	.exit					   ; exit function (eax will be zero)
654
 
631
 
655
	cmp	ecx, esi				   ; if buffer size is larger then the bytes of data, copy all data
632
	cmp	ecx, esi				   ; if buffer size is larger then the bytes of data, copy all data
656
	jle	.copy_all_bytes
633
	jle	.copy_all_bytes
657
 
634
 
658
	sub	ecx, esi				   ; store new count (data bytes in buffer - bytes we're about to copy)
635
	sub	ecx, esi				   ; store new count (data bytes in buffer - bytes we're about to copy)
659
	mov	[eax + SOCKET.rxDataCount], ecx 	   ;
636
	mov	[eax + SOCKET.rxDataCount], ecx 	   ;
660
	push	ecx
637
	push	ecx
661
	mov	edx, esi
638
	mov	edx, esi
662
 
639
 
663
	call	.start_copy				   ; copy to the application
640
	call	.start_copy				   ; copy to the application
664
 
641
 
665
	mov	dword[esp+32], edx
642
	mov	dword[esp+32], edx
666
 
643
 
667
	lea	edi, [eax + SOCKET.rxData]		   ; Now shift the remaining bytes to start of buffer
644
	lea	edi, [eax + SOCKET.rxData]		   ; Now shift the remaining bytes to start of buffer
668
	lea	esi, [edi + edx]
645
	lea	esi, [edi + edx]
669
	mov	ecx, [esp]
646
	mov	ecx, [esp]
670
	shr	ecx, 2					   ; divide eax by 4
647
	shr	ecx, 2					   ; divide eax by 4
671
	rep	movsd					   ; copy all full dwords
648
	rep	movsd					   ; copy all full dwords
672
	pop	ecx
649
	pop	ecx
673
	and	ecx, 3
650
	and	ecx, 3
674
	rep	movsb					   ; copy remaining bytes
651
	rep	movsb					   ; copy remaining bytes
675
 
652
 
676
  .exit:
653
  .exit:
677
	mov	[eax + SOCKET.lock], 0
654
	mov	[eax + SOCKET.lock], 0
678
	ret
655
	ret
679
 
656
 
680
  .copy_all_bytes:
657
  .copy_all_bytes:
681
	mov	dword[esp+32], ecx
658
	mov	dword[esp+32], ecx
682
	mov	[eax + SOCKET.rxDataCount], 0		  ; store new count (zero)
659
	mov	[eax + SOCKET.rxDataCount], 0		  ; store new count (zero)
683
	push	dword .exit				   ; this code results in same as commented out code
660
	push	dword .exit				   ; this code results in same as commented out code
684
 
661
 
685
  .start_copy:
662
  .start_copy:
686
	DEBUGF	1,"copying %u bytes\n",ecx
663
	DEBUGF	1,"copying %u bytes\n",ecx
687
 
664
 
688
	lea	esi, [eax + SOCKET.rxData]
665
	lea	esi, [eax + SOCKET.rxData]
689
	push	ecx
666
	push	ecx
690
	shr	ecx, 2					   ; divide eax by 4
667
	shr	ecx, 2					   ; divide eax by 4
691
	rep	movsd
668
	rep	movsd
692
	pop	ecx
669
	pop	ecx
693
	and	ecx, 3
670
	and	ecx, 3
694
	rep	movsb					   ; copy the rest bytes
671
	rep	movsb					   ; copy the rest bytes
695
 
672
 
696
	ret						   ; exit, or go back to shift remaining bytes if any
673
	ret						   ; exit, or go back to shift remaining bytes if any
697
 
674
 
698
 
675
 
699
 
676
 
700
;-----------------------------------------------
677
;-----------------------------------------------
701
;
678
;
702
; SOCKET_send
679
; SOCKET_send
703
;
680
;
704
;
681
;
705
;  IN:  socket number in ecx
682
;  IN:  socket number in ecx
706
;       addr in edx
683
;       pointer to data in edx
707
;       addrlen in esi
684
;       datalength in esi
708
;       flags in edi
685
;       flags in edi
709
;  OUT: -1 on error
686
;  OUT: -1 on error
710
;
687
;
711
;-----------------------------------------------
688
;-----------------------------------------------
712
 
689
align 4
713
socket_send:
690
socket_send:
714
 
691
 
715
	DEBUGF	1,"Socket_send: socknum: %u sockaddr: %x, length: %u, flags: %x, ",ecx,edx,esi,edi
692
	DEBUGF	1,"Socket_send: socknum: %u sockaddr: %x, length: %u, flags: %x, ",ecx,edx,esi,edi
716
 
693
 
717
	stdcall net_socket_num_to_addr, ecx		   ; get real socket address
694
	stdcall net_socket_num_to_addr, ecx		   ; get real socket address
718
	or	eax, eax
695
	or	eax, eax
719
	jz	s_error
696
	jz	s_error
-
 
697
 
-
 
698
	cmp	word [eax + SOCKET.Domain], AF_INET4
-
 
699
	je	.af_inet4
-
 
700
 
-
 
701
	jmp	s_error
-
 
702
 
-
 
703
  .af_inet4:
720
 
704
 
721
	DEBUGF	1,"Socket type:%u\n", [eax + SOCKET.Type]:4
705
	DEBUGF	1,"Socket type:%u\n", [eax + SOCKET.Type]:4
722
 
706
 
723
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
707
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
724
	je	.udp
708
	je	.udp
725
 
709
 
726
	cmp	[eax + SOCKET.Type], IP_PROTO_ICMP
710
	cmp	[eax + SOCKET.Type], IP_PROTO_ICMP
727
	je	.icmp
711
	je	.icmp
728
 
712
 
729
;        cmp     [eax + SOCKET.Type], IP_PROTO_TCP
713
	cmp	[eax + SOCKET.Type], IP_PROTO_TCP
730
;        je      .tcp
714
	je	.tcp
731
 
715
 
732
	jmp	s_error
716
	jmp	s_error
733
 
717
 
734
  .udp:
718
  .udp:
735
 
719
 
-
 
720
	DEBUGF	1,"type: UDP, "
-
 
721
 
-
 
722
	cmp	[eax + SOCKET.LocalPort],0
-
 
723
	jne	.port_ok
-
 
724
 
-
 
725
	mov	ecx, [eax + SOCKET.Type]
-
 
726
	call	socket_find_port
-
 
727
	test	bx, bx
-
 
728
	je	s_error
-
 
729
	mov	[eax + SOCKET.LocalPort], bx
-
 
730
 
736
	DEBUGF	1,"type: UDP\n"
731
  .port_ok:
737
 
732
 
738
	mov	ecx, esi
733
	mov	ecx, esi
739
	mov	esi, edx
734
	mov	esi, edx
740
	mov	edx, dword [eax + SOCKET.LocalPort] ; load local port and remote port at once
735
	mov	edx, dword [eax + SOCKET.LocalPort] ; load local port and remote port at once
741
	DEBUGF	1,"local port: %u, remote port:%u\n",[eax + SOCKET.LocalPort]:2, [eax + SOCKET.RemotePort]:2
736
	DEBUGF	1,"local port: %x, remote port: %x\n",[eax + SOCKET.LocalPort]:2, [eax + SOCKET.RemotePort]:2
742
	bswap	edx	 ;;;
-
 
743
	rol	edx, 16  ;;;
-
 
744
	mov	ebx, [eax + SOCKET.LocalIP]
737
	mov	ebx, [eax + SOCKET.LocalIP]
745
	mov	eax, [eax + SOCKET.RemoteIP]
738
	mov	eax, [eax + SOCKET.RemoteIP]
746
 
739
 
747
	call	UDP_create_packet
740
	call	UDP_create_packet
748
 
741
 
749
	mov	[esp+32], eax
742
	mov	[esp+32], eax
750
	ret
743
	ret
751
 
744
 
752
  .icmp:
745
  .icmp:
753
	; note: for ICMP sockets the SOCKET.LocalPort is used as the 'Identifier' value for ICMP packets
746
	; note: for ICMP sockets the SOCKET.LocalPort is used as the 'Identifier' value for ICMP packets
754
	; the application must add the header to the data, the kernel will fill in 'identifier' and 'checksum'
747
	; the application must add the header to the data, the kernel will fill in 'identifier' and 'checksum'
755
 
748
 
756
	sub	ecx, ICMP_Packet.Data
749
	sub	ecx, ICMP_Packet.Data
757
	mov	esi, edx
750
	mov	esi, edx
758
	push	ax
751
	push	ax
759
	call	IPv4_get_frgmnt_num
752
	call	IPv4_get_frgmnt_num
760
	mov	dx, ax
753
	mov	dx, ax
761
	pop	ax
754
	pop	ax
762
	shl	edx, 16
755
	shl	edx, 16
763
	mov	dh , [esi + ICMP_Packet.Type]
756
	mov	dh , [esi + ICMP_Packet.Type]
764
	mov	dl , [esi + ICMP_Packet.Code]
757
	mov	dl , [esi + ICMP_Packet.Code]
765
	mov	di , [esi + ICMP_Packet.Identifier]
758
	mov	di , [esi + ICMP_Packet.Identifier]
766
;        mov     [eax + SOCKET.LocalPort], di            ; Set localport to the identifier number, so we can receive reply's
759
;        mov     [eax + SOCKET.LocalPort], di            ; Set localport to the identifier number, so we can receive reply's
767
	shl	edi, 16
760
	shl	edi, 16
768
	mov	di , [esi + ICMP_Packet.SequenceNumber]
761
	mov	di , [esi + ICMP_Packet.SequenceNumber]
769
	add	esi, ICMP_Packet.Data
762
	add	esi, ICMP_Packet.Data
770
	mov	ebx, [eax + SOCKET.LocalIP]
763
	mov	ebx, [eax + SOCKET.LocalIP]
771
	mov	eax, [eax + SOCKET.RemoteIP]
764
	mov	eax, [eax + SOCKET.RemoteIP]
772
	call	ICMP_create_packet
765
	call	ICMP_create_packet
773
 
766
 
774
	mov	[esp+32], eax
767
	mov	[esp+32], eax
775
	ret
768
	ret
776
 
769
 
777
  .tcp:
770
  .tcp:
778
 
771
 
779
	ret
772
	ret
780
 
773
 
781
 
774
 
782
 
775
 
-
 
776
 
-
 
777
;-----------------------------------------------
-
 
778
;
-
 
779
; SOCKET_find_free_port (local port)
-
 
780
;
-
 
781
; works with INET byte order
-
 
782
;
-
 
783
;  IN:  type in ecx (TCP/UDP)
-
 
784
;  OUT: bx = 0 on error, portnumber otherwise
-
 
785
;
-
 
786
;-----------------------------------------------
-
 
787
align 4
-
 
788
socket_find_port:
-
 
789
 
-
 
790
	DEBUGF	1,"Socket_find_free_port, type: %u ",eax
-
 
791
 
-
 
792
	cmp	ecx, IP_PROTO_UDP
-
 
793
	je	.udp
-
 
794
 
-
 
795
	cmp	ecx, IP_PROTO_TCP
-
 
796
	je	.tcp
-
 
797
 
-
 
798
  .udp:
-
 
799
	mov	bx, [last_UDP_port]
-
 
800
	je	.continue
-
 
801
 
-
 
802
  .tcp:
-
 
803
	mov	bx, [last_TCP_port]
-
 
804
 
-
 
805
 
-
 
806
  .continue:
-
 
807
	inc	bx
-
 
808
 
-
 
809
  .check_only:
-
 
810
	mov	esi, net_sockets
-
 
811
 
-
 
812
  .next_socket:
-
 
813
	mov	esi, [esi + SOCKET.NextPtr]
-
 
814
	or	esi, esi
-
 
815
	jz	.port_ok
-
 
816
 
-
 
817
	cmp	[esi + SOCKET.Type], ecx
-
 
818
	jne	.next_socket
-
 
819
 
-
 
820
	rol	bx, 8
-
 
821
	cmp	[esi + SOCKET.LocalPort], bx
-
 
822
	rol	bx, 8				; this doesnt change the zero flag, does it ?
-
 
823
	jne	.next_socket
-
 
824
 
-
 
825
	cmp	bx, MAX_EPHEMERAL_PORT
-
 
826
	jle	.continue
-
 
827
 
-
 
828
	; todo: WRAP!
-
 
829
;        mov     [last_UDP_port], MIN_EPHEMERAL_PORT
-
 
830
  .exit:
-
 
831
	xor	ebx, ebx
-
 
832
 
-
 
833
  .port_ok:
-
 
834
	rol	bx, 8
-
 
835
	ret
-
 
836
 
-
 
837
;-----------------------------------------------
-
 
838
;
-
 
839
; SOCKET_check_port (local port)
-
 
840
;
-
 
841
; works with INET byte order
-
 
842
;
-
 
843
;  IN:  type in ecx (TCP/UDP)
-
 
844
;       port to check in bx
-
 
845
;  OUT: bx = 0 on error, unchanged otherwise
-
 
846
;
-
 
847
;-----------------------------------------------
-
 
848
align 4
-
 
849
socket_check_port:
-
 
850
	mov	esi, net_sockets
-
 
851
 
-
 
852
  .next_socket:
-
 
853
	mov	esi, [esi + SOCKET.NextPtr]
-
 
854
	or	esi, esi
-
 
855
	jz	.port_ok
-
 
856
 
-
 
857
	cmp	[esi + SOCKET.Type], ecx
-
 
858
	jne	.next_socket
-
 
859
 
-
 
860
	cmp	[esi + SOCKET.LocalPort], bx
-
 
861
	jne	.next_socket
-
 
862
 
-
 
863
	xor	ebx, ebx
-
 
864
 
-
 
865
  .port_ok:
-
 
866
	ret
-
 
867
 
-
 
868
 
-
 
869
 
-
 
870
;-----------------------------------------------
-
 
871
;
-
 
872
; SOCKET_internal_receiver
-
 
873
;
-
 
874
; Checks if any socket wants the received data
-
 
875
; If so, update the socket
-
 
876
;
-
 
877
;  IN:  eax = socket number
-
 
878
;       ecx = number of bytes
-
 
879
;       esi = pointer to beginning of data
-
 
880
;       dx = Remote port (in INET byte order)
-
 
881
;       edi = IP address of sender
-
 
882
;
-
 
883
;  OUT: xxx
-
 
884
;
-
 
885
;-----------------------------------------------
-
 
886
align 4
-
 
887
socket_internal_receiver:
-
 
888
 
-
 
889
	DEBUGF 1,"internal socket receiver\n"
-
 
890
 
-
 
891
	lea	ebx, [eax + SOCKET.lock]
-
 
892
	call	wait_mutex
-
 
893
 
-
 
894
	mov	[eax + SOCKET.RemotePort], dx		; update remote port number
-
 
895
	mov	[eax + SOCKET.RemoteIP], edi
-
 
896
 
-
 
897
	mov	edx, [eax + SOCKET.rxDataCount] 	; get # of bytes already in buffer
-
 
898
	DEBUGF 1,"bytes already in socket: %u ", edx
-
 
899
 
-
 
900
	lea	edi, [ecx + edx]			; check for buffer overflow
-
 
901
	cmp	edi, SOCKETBUFFSIZE - SOCKETHEADERSIZE	;
-
 
902
	jg	.dump					;
-
 
903
 
-
 
904
	lea	edi, [eax + SOCKET.rxData + edx]
-
 
905
	add	[eax + SOCKET.rxDataCount], ecx 	; increment the count of bytes in buffer
-
 
906
	DEBUGF 1,"adding %u bytes\n", ecx
-
 
907
 
-
 
908
	; copy the data across
-
 
909
	push	cx
-
 
910
	shr	ecx, 2
-
 
911
	rep	movsd
-
 
912
	pop	cx
-
 
913
	and	cx, 3
-
 
914
	rep	movsb
-
 
915
 
-
 
916
	DEBUGF 1,"socket updated\n"
-
 
917
 
-
 
918
	mov	[eax + SOCKET.lock], 0
-
 
919
 
-
 
920
	; flag an event to the application
-
 
921
	mov	edx, [eax + SOCKET.PID] 		; get socket owner PID
-
 
922
	mov	ecx, 1
-
 
923
	mov	esi, TASK_DATA + TASKDATA.pid
-
 
924
 
-
 
925
       .next_pid:
-
 
926
	cmp	[esi], edx
-
 
927
	je	.found_pid
-
 
928
	inc	ecx
-
 
929
	add	esi, 0x20
-
 
930
	cmp	ecx, [TASK_COUNT]
-
 
931
	jbe	.next_pid
-
 
932
	ret
-
 
933
 
-
 
934
       .found_pid:
-
 
935
	shl	ecx, 8
-
 
936
	or	[ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
-
 
937
	mov	[check_idle_semaphore], 200
-
 
938
	ret
-
 
939
 
-
 
940
       .dump:
-
 
941
	mov	[eax + SOCKET.lock], 0
-
 
942
	ret
783
 
943
 
784
 
944
 
785
 
945
 
786
 
946
 
787
 
947
 
788
; Allocate memory for socket data and put new socket into the list
948
; Allocate memory for socket data and put new socket into the list
789
; Newly created socket is initialized with calling PID and number and
949
; Newly created socket is initialized with calling PID and number and
790
; put into beginning of list (which is a fastest way).
950
; put into beginning of list (which is a fastest way).
791
;
951
;
792
; @return socket structure address in EAX
952
; @return socket structure address in EAX
793
;
953
;
794
proc net_socket_alloc stdcall uses ebx ecx edx edi
954
proc net_socket_alloc stdcall uses ebx ecx edx edi
795
	stdcall kernel_alloc, SOCKETBUFFSIZE
955
	stdcall kernel_alloc, SOCKETBUFFSIZE
796
	DEBUGF	1, "K : net_socket_alloc (0x%x)\n", eax
956
	DEBUGF	1, "K : net_socket_alloc (0x%x)\n", eax
797
	; check if we can allocate needed amount of memory
957
	; check if we can allocate needed amount of memory
798
	or	eax, eax
958
	or	eax, eax
799
	jz	.exit
959
	jz	.exit
800
 
960
 
801
	; zero-initialize allocated memory
961
	; zero-initialize allocated memory
802
	push	eax
962
	push	eax
803
	mov	edi, eax
963
	mov	edi, eax
804
	mov	ecx, SOCKETBUFFSIZE / 4
964
	mov	ecx, SOCKETBUFFSIZE / 4
805
;        cld
965
;        cld
806
	xor	eax, eax
966
	xor	eax, eax
807
	rep	stosd
967
	rep	stosd
808
	pop	eax
968
	pop	eax
809
 
969
 
810
	; add socket to the list by changing pointers
970
	; add socket to the list by changing pointers
811
	mov	ebx, net_sockets
971
	mov	ebx, net_sockets
812
	push	[ebx + SOCKET.NextPtr]
972
	push	[ebx + SOCKET.NextPtr]
813
	mov	[ebx + SOCKET.NextPtr], eax
973
	mov	[ebx + SOCKET.NextPtr], eax
814
	mov	[eax + SOCKET.PrevPtr], ebx
974
	mov	[eax + SOCKET.PrevPtr], ebx
815
	pop	ebx
975
	pop	ebx
816
	mov	[eax + SOCKET.NextPtr], ebx
976
	mov	[eax + SOCKET.NextPtr], ebx
817
	or	ebx, ebx
977
	or	ebx, ebx
818
	jz	@f
978
	jz	@f
819
	mov	[ebx + SOCKET.PrevPtr], eax
979
	mov	[ebx + SOCKET.PrevPtr], eax
820
 
980
 
821
    @@: ; set socket owner PID to the one of calling process
981
    @@: ; set socket owner PID to the one of calling process
822
	mov	ebx, [TASK_BASE]
982
	mov	ebx, [TASK_BASE]
823
	mov	ebx, [ebx + TASKDATA.pid]
983
	mov	ebx, [ebx + TASKDATA.pid]
824
	mov	[eax + SOCKET.PID], ebx
984
	mov	[eax + SOCKET.PID], ebx
825
 
985
 
826
	; find first free socket number and use it
986
	; find first free socket number and use it
827
	;mov     edx, ebx
987
	;mov     edx, ebx
828
	mov	ebx, net_sockets
988
	mov	ebx, net_sockets
829
	xor	ecx, ecx
989
	xor	ecx, ecx
830
  .next_socket_number:
990
  .next_socket_number:
831
	inc	ecx
991
	inc	ecx
832
  .next_socket:
992
  .next_socket:
833
	mov	ebx, [ebx + SOCKET.NextPtr]
993
	mov	ebx, [ebx + SOCKET.NextPtr]
834
	or	ebx, ebx
994
	or	ebx, ebx
835
	jz	.last_socket_number
995
	jz	.last_socket_number
836
	cmp	[ebx + SOCKET.Number], ecx
996
	cmp	[ebx + SOCKET.Number], ecx
837
	jne	.next_socket
997
	jne	.next_socket
838
	;cmp     [ebx + SOCKET.PID], edx
998
	;cmp     [ebx + SOCKET.PID], edx
839
	;jne     .next_socket
999
	;jne     .next_socket
840
	mov	ebx, net_sockets
1000
	mov	ebx, net_sockets
841
	jmp	.next_socket_number
1001
	jmp	.next_socket_number
842
 
1002
 
843
  .last_socket_number:
1003
  .last_socket_number:
844
	mov	[eax + SOCKET.Number], ecx
1004
	mov	[eax + SOCKET.Number], ecx
845
 
1005
 
846
  .exit:
1006
  .exit:
847
	ret
1007
	ret
848
endp
1008
endp
849
 
1009
 
850
; Free socket data memory and pop socket off the list
1010
; Free socket data memory and pop socket off the list
851
;
1011
;
852
; @param sockAddr is a socket structure address
1012
; @param sockAddr is a socket structure address
853
;
1013
;
854
proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD
1014
proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD
855
	mov	eax, [sockAddr]
1015
	mov	eax, [sockAddr]
856
	DEBUGF	1, "K : net_socket_free (0x%x)\n", eax
1016
	DEBUGF	1, "K : net_socket_free (0x%x)\n", eax
857
	; check if we got something similar to socket structure address
1017
	; check if we got something similar to socket structure address
858
	or	eax, eax
1018
	or	eax, eax
859
	jz	.error
1019
	jz	.error
860
 
1020
 
861
	; make sure sockAddr is one of the socket addresses in the list
1021
	; make sure sockAddr is one of the socket addresses in the list
862
	mov	ebx, net_sockets
1022
	mov	ebx, net_sockets
863
	;mov     ecx, [TASK_BASE]
1023
	;mov     ecx, [TASK_BASE]
864
	;mov     ecx, [ecx + TASKDATA.pid]
1024
	;mov     ecx, [ecx + TASKDATA.pid]
865
  .next_socket:
1025
  .next_socket:
866
	mov	ebx, [ebx + SOCKET.NextPtr]
1026
	mov	ebx, [ebx + SOCKET.NextPtr]
867
	or	ebx, ebx
1027
	or	ebx, ebx
868
	jz	.error
1028
	jz	.error
869
	cmp	ebx, eax
1029
	cmp	ebx, eax
870
	jne	.next_socket
1030
	jne	.next_socket
871
	;cmp     [ebx + SOCKET.PID], ecx
1031
	;cmp     [ebx + SOCKET.PID], ecx
872
	;jne     .next_socket
1032
	;jne     .next_socket
873
 
1033
 
874
	; okay, we found the correct one
1034
	; okay, we found the correct one
875
	; remove it from the list first, changing pointers
1035
	; remove it from the list first, changing pointers
876
	mov	ebx, [eax + SOCKET.NextPtr]
1036
	mov	ebx, [eax + SOCKET.NextPtr]
877
	mov	eax, [eax + SOCKET.PrevPtr]
1037
	mov	eax, [eax + SOCKET.PrevPtr]
878
	mov	[eax + SOCKET.NextPtr], ebx
1038
	mov	[eax + SOCKET.NextPtr], ebx
879
	or	ebx, ebx
1039
	or	ebx, ebx
880
	jz	@f
1040
	jz	@f
881
	mov	[ebx + SOCKET.PrevPtr], eax
1041
	mov	[ebx + SOCKET.PrevPtr], eax
882
 
1042
 
883
    @@: ; and finally free the memory structure used
1043
    @@: ; and finally free the memory structure used
884
	stdcall kernel_free, [sockAddr]
1044
	stdcall kernel_free, [sockAddr]
885
	ret
1045
	ret
886
 
1046
 
887
  .error:
1047
  .error:
888
	DEBUGF	1, "K :   failed\n"
1048
	DEBUGF	1, "K :   failed\n"
889
	ret
1049
	ret
890
endp
1050
endp
891
 
1051
 
892
; Get socket structure address by its number
1052
; Get socket structure address by its number
893
; Scan through sockets list to find the socket with specified number.
1053
; Scan through sockets list to find the socket with specified number.
894
; This proc uses SOCKET.PID indirectly to check if socket is owned by
1054
; This proc uses SOCKET.PID indirectly to check if socket is owned by
895
; calling process.
1055
; calling process.
896
;
1056
;
897
; @param sockNum is a socket number
1057
; @param sockNum is a socket number
898
; @return socket structure address or 0 (not found) in EAX
1058
; @return socket structure address or 0 (not found) in EAX
899
;
1059
;
900
proc net_socket_num_to_addr stdcall uses ebx ecx, sockNum:DWORD
1060
proc net_socket_num_to_addr stdcall uses ebx ecx, sockNum:DWORD
901
	mov	eax, [sockNum]
1061
	mov	eax, [sockNum]
902
	; check if we got something similar to socket number
1062
	; check if we got something similar to socket number
903
	or	eax, eax
1063
	or	eax, eax
904
	jz	.error
1064
	jz	.error
905
 
1065
 
906
	; scan through sockets list
1066
	; scan through sockets list
907
	mov	ebx, net_sockets
1067
	mov	ebx, net_sockets
908
	;mov     ecx, [TASK_BASE]
1068
	;mov     ecx, [TASK_BASE]
909
	;mov     ecx, [ecx + TASKDATA.pid]
1069
	;mov     ecx, [ecx + TASKDATA.pid]
910
  .next_socket:
1070
  .next_socket:
911
	mov	ebx, [ebx + SOCKET.NextPtr]
1071
	mov	ebx, [ebx + SOCKET.NextPtr]
912
	or	ebx, ebx
1072
	or	ebx, ebx
913
	jz	.error
1073
	jz	.error
914
	cmp	[ebx + SOCKET.Number], eax
1074
	cmp	[ebx + SOCKET.Number], eax
915
	jne	.next_socket
1075
	jne	.next_socket
916
	;cmp     [ebx + SOCKET.PID], ecx
1076
	;cmp     [ebx + SOCKET.PID], ecx
917
	;jne     .next_socket
1077
	;jne     .next_socket
918
 
1078
 
919
	; okay, we found the correct one
1079
	; okay, we found the correct one
920
	mov	eax, ebx
1080
	mov	eax, ebx
921
	ret
1081
	ret
922
 
1082
 
923
  .error:
1083
  .error:
924
	xor	eax, eax
1084
	xor	eax, eax
925
	ret
1085
	ret
926
endp
1086
endp
927
 
1087
 
928
; Get socket number by its structure address
1088
; Get socket number by its structure address
929
; Scan through sockets list to find the socket with specified address.
1089
; Scan through sockets list to find the socket with specified address.
930
; This proc uses SOCKET.PID indirectly to check if socket is owned by
1090
; This proc uses SOCKET.PID indirectly to check if socket is owned by
931
; calling process.
1091
; calling process.
932
;
1092
;
933
; @param sockAddr is a socket structure address
1093
; @param sockAddr is a socket structure address
934
; @return socket number (SOCKET.Number) or 0 (not found) in EAX
1094
; @return socket number (SOCKET.Number) or 0 (not found) in EAX
935
;
1095
;
936
proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD
1096
proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD
937
	mov	eax, [sockAddr]
1097
	mov	eax, [sockAddr]
938
	; check if we got something similar to socket structure address
1098
	; check if we got something similar to socket structure address
939
	or	eax, eax
1099
	or	eax, eax
940
	jz	.error
1100
	jz	.error
941
 
1101
 
942
	; scan through sockets list
1102
	; scan through sockets list
943
	mov	ebx, net_sockets
1103
	mov	ebx, net_sockets
944
	;mov     ecx, [TASK_BASE]
1104
	;mov     ecx, [TASK_BASE]
945
	;mov     ecx, [ecx + TASKDATA.pid]
1105
	;mov     ecx, [ecx + TASKDATA.pid]
946
  .next_socket:
1106
  .next_socket:
947
	mov	ebx, [ebx + SOCKET.NextPtr]
1107
	mov	ebx, [ebx + SOCKET.NextPtr]
948
	or	ebx, ebx
1108
	or	ebx, ebx
949
	jz	.error
1109
	jz	.error
950
	cmp	ebx, eax
1110
	cmp	ebx, eax
951
	jne	.next_socket
1111
	jne	.next_socket
952
	;cmp     [ebx + SOCKET.PID], ecx
1112
	;cmp     [ebx + SOCKET.PID], ecx
953
	;jne     .next_socket
1113
	;jne     .next_socket
954
 
1114
 
955
	; okay, we found the correct one
1115
	; okay, we found the correct one
956
	mov	eax, [ebx + SOCKET.Number]
1116
	mov	eax, [ebx + SOCKET.Number]
957
	ret
1117
	ret
958
 
1118
 
959
  .error:
1119
  .error:
960
	xor	eax, eax
1120
	xor	eax, eax
961
	ret
1121
	ret
962
endp
1122
endp