Subversion Repositories Kolibri OS

Rev

Rev 1259 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1171 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  STACK.INC                                                      ;;
7
;;                                                                 ;;
8
;;  BASIC TCP/IP stack for KolibriOS                               ;;
9
;;                                                                 ;;
10
;;    Written by hidnplayr@kolibrios.org                           ;;
11
;;                                                                 ;;
12
;;     based on the work of Mike Hibbett, mikeh@oceanfree.net      ;;
13
;;     but also Paolo Franchetti                                   ;;
14
;;                                                                 ;;
15
;;          GNU GENERAL PUBLIC LICENSE                             ;;
16
;;             Version 2, June 1991                                ;;
17
;;                                                                 ;;
18
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1159 hidnplayr 19
 
1206 hidnplayr 20
$Revision: 1318 $
1159 hidnplayr 21
 
22
uglobal
23
	last_1sTick	db ?
24
	last_1hsTick	dd ?
25
endg
26
 
1259 hidnplayr 27
MAX_NET_DEVICES 	equ 16
28
QUEUE_BEFORE_SENDING	equ 1 ; 1 or 0 (enable or disable) currently only affects ethernet
1159 hidnplayr 29
 
1185 hidnplayr 30
MIN_EPHEMERAL_PORT equ 49152
31
MAX_EPHEMERAL_PORT equ 61000
1159 hidnplayr 32
 
1257 hidnplayr 33
ETHER		equ 1337     ; TODO: find another value for this (how does it work in posix ?)
1185 hidnplayr 34
ETHER_ARP	equ 0x0608
35
 
1254 hidnplayr 36
AF_UNSPEC	equ 0
1249 hidnplayr 37
AF_UNIX 	equ 1
1159 hidnplayr 38
AF_INET4	equ 2
39
;AF_AX25         equ 3
40
;AF_IPX          equ 4
41
;AF_APPLETALK    equ 5
42
;AF_NETROM       equ 6
43
;AF_BRIDGE       equ 7
44
;AF_AAL5         equ 8
45
;AF_X25          equ 9
46
;AF_INET6        equ 10
47
;AF_MAX          equ 12
48
 
49
IP_PROTO_IP	equ 0
50
IP_PROTO_ICMP	equ 1
51
IP_PROTO_TCP	equ 6
52
IP_PROTO_UDP	equ 17
53
 
1200 hidnplayr 54
; Socket types
55
SOCK_STREAM	= 1
56
SOCK_DGRAM	= 2
57
SOCK_RAW	= 3
58
 
1254 hidnplayr 59
TCB_LISTEN		equ 1
60
TCB_SYN_SENT		equ 2
61
TCB_SYN_RECEIVED	equ 3
62
TCB_ESTABLISHED 	equ 4
63
TCB_FIN_WAIT_1		equ 5
64
TCB_FIN_WAIT_2		equ 6
65
TCB_CLOSE_WAIT		equ 7
66
TCB_CLOSING		equ 8
67
TCB_LAST_ACK		equ 9
68
TCB_TIMED_WAIT		equ 10
69
TCB_CLOSED		equ 11
1159 hidnplayr 70
 
1254 hidnplayr 71
TH_FIN			equ 1 shl 0
72
TH_SYN			equ 1 shl 1
73
TH_RST			equ 1 shl 2
74
TH_PUSH 		equ 1 shl 3
75
TH_ACK			equ 1 shl 4
76
TH_URG			equ 1 shl 5
77
 
78
 
79
macro inc_INET reg {
80
 
1256 clevermous 81
	add	byte [reg + 3], 1
1254 hidnplayr 82
	adc	byte [reg + 2], 0
83
	adc	byte [reg + 1], 0
1256 clevermous 84
	adc	byte [reg], 0
1254 hidnplayr 85
 
86
}
87
 
88
 
89
macro add_INET reg {
1256 clevermous 90
	add	byte [reg + 3], cl
91
	adc	byte [reg + 2], ch
92
	adc	byte [reg + 1], 0
93
	adc	byte [reg], 0
1254 hidnplayr 94
	rol	ecx, 16
1256 clevermous 95
	add	byte [reg + 1], cl
96
	adc	byte [reg], ch
1254 hidnplayr 97
	rol	ecx, 16
98
}
99
 
1318 hidnplayr 100
 
101
macro pseudo_random reg {
102
 
103
	add	reg, [esp]
104
	rol	reg, 5
105
	xor	reg, [timer_ticks]
106
	imul	reg, 214013
107
	xor	reg, 0xdeadbeef
108
	rol	reg, 9
109
 
110
	pushd	reg
111
	mov	word [esp], 0x8080 ; kernel heap start addr      (os_stack)
112
	xor	reg, [esp]
113
	add	esp, 4
114
 
115
}
116
 
1159 hidnplayr 117
include "queue.inc"
1187 hidnplayr 118
include "ARP.inc"
119
include "IPv4.inc"
1159 hidnplayr 120
include "ethernet.inc"
121
include "socket.inc"
1249 hidnplayr 122
include "tcp.inc"
1185 hidnplayr 123
include "udp.inc"
124
include "icmp.inc"
1159 hidnplayr 125
 
1257 hidnplayr 126
;-----------------------------------------------------------------
1159 hidnplayr 127
;
128
; stack_init
129
;
130
;  This function calls all network init procedures
131
;
132
;  IN:  /
133
;  OUT: /
134
;
1257 hidnplayr 135
;-----------------------------------------------------------------
1159 hidnplayr 136
align 4
137
stack_init:
138
 
139
	call	ETH_init
140
	call	IPv4_init
141
	call	ARP_init
142
	call	UDP_init
1249 hidnplayr 143
	call	TCP_init
1159 hidnplayr 144
	call	ICMP_init
145
	call	socket_init
146
 
1254 hidnplayr 147
	mov	al, 0		      ; set up 1s timer
1159 hidnplayr 148
	out	0x70, al
149
	in	al, 0x71
150
	mov	[last_1sTick], al
151
 
152
	ret
153
 
154
 
155
 
1257 hidnplayr 156
;-----------------------------------------------------------------
1159 hidnplayr 157
;
158
; stack_handler
159
;
160
;  This function calls all network init procedures
161
;
162
;  IN:  /
163
;  OUT: /
164
;
1257 hidnplayr 165
;-----------------------------------------------------------------
1159 hidnplayr 166
align 4
167
stack_handler:
168
 
1257 hidnplayr 169
	cmp	[ETH_RUNNING], 0
170
	je	.exit
1159 hidnplayr 171
 
1318 hidnplayr 172
	; Test for 10ms tick
1257 hidnplayr 173
	mov	eax, [timer_ticks]
174
	cmp	eax, [last_1hsTick]
175
	je	.exit
1159 hidnplayr 176
 
1257 hidnplayr 177
	mov	[last_1hsTick], eax
1159 hidnplayr 178
 
1257 hidnplayr 179
	call	ETH_handler		    ; handle all queued ethernet packets
1259 hidnplayr 180
if QUEUE_BEFORE_SENDING
1257 hidnplayr 181
	call	ETH_send_queued
1259 hidnplayr 182
end if
1257 hidnplayr 183
	call	TCP_send_queued
1249 hidnplayr 184
 
1159 hidnplayr 185
  .sec_tick:
186
 
1257 hidnplayr 187
	; Test for 1 second tick
188
	mov	al, 0
189
	out	0x70, al
190
	in	al, 0x71
191
	cmp	al, [last_1sTick]
192
	je	.exit
1159 hidnplayr 193
 
1257 hidnplayr 194
	mov	[last_1sTick], al
1159 hidnplayr 195
 
1257 hidnplayr 196
	call	ARP_decrease_entry_ttls
197
	call	IPv4_decrease_fragment_ttls
198
	call	TCP_decrease_socket_ttls
1159 hidnplayr 199
 
200
  .exit:
1257 hidnplayr 201
	ret
1159 hidnplayr 202
 
203
 
1249 hidnplayr 204
;-----------------------------------------------------------------
205
;
206
; checksum_1
207
;
208
;  This is the first of two functions needed to calculate the TCP checksum.
209
;
210
;  IN:  edx = start offeset for semi-checksum
211
;       esi = pointer to data
212
;       ecx = data size
213
;  OUT: edx = semi-checksum
214
;
215
;-----------------------------------------------------------------
216
align 4
217
checksum_1:
1159 hidnplayr 218
 
1249 hidnplayr 219
	xor	eax, eax
220
	shr	ecx, 1
221
	pushf
222
.loop:
223
	lodsw
224
	xchg	al, ah
225
	add	edx, eax
226
	loop	.loop
1159 hidnplayr 227
 
1249 hidnplayr 228
	popf
229
	jnc	.end
1159 hidnplayr 230
 
1251 clevermous 231
	add	dh, [esi]
232
	adc	edx, 0
1159 hidnplayr 233
 
1249 hidnplayr 234
.end:
235
 
236
	ret
237
 
238
 
239
;-----------------------------------------------------------------
240
;
241
; checksum_2
242
;
243
;  This function calculates the final ip/tcp/udp checksum for you
244
;
245
;  IN:  edx = semi-checksum
246
;  OUT: dx = checksum (in INET byte order)
247
;
248
;-----------------------------------------------------------------
249
align 4
250
checksum_2:
251
 
252
	mov	ecx, edx
253
	shr	ecx, 16
254
	and	edx, 0xffff
255
	add	edx, ecx
256
	mov	eax, edx
257
	shr	eax, 16
258
	add	edx, eax
259
 
260
	not	dx
261
	jnz	.not_zero
262
	dec	dx
263
  .not_zero:
264
	xchg	dl, dh
265
 
266
	DEBUGF 1,"Checksum: %x\n",dx
267
 
268
	ret
269
 
270
 
271
 
1159 hidnplayr 272
;----------------------------------------------------------------
273
;
1171 hidnplayr 274
;  System function to work with network devices (73)
1159 hidnplayr 275
;
276
;----------------------------------------------------------------
277
align 4
278
sys_network:
279
 
1196 hidnplayr 280
	cmp	ebx, -1
281
	jne	@f
282
 
283
	mov	eax, [ETH_RUNNING]
284
	jmp	.return
285
 
286
   @@:
1159 hidnplayr 287
	cmp	bh, MAX_NET_DEVICES		 ; Check if device number exists
288
	jge	.doesnt_exist
289
 
290
	mov	esi, ebx
291
	and	esi, 0x0000ff00
292
	shr	esi, 6
293
 
294
	cmp	dword [esi + ETH_DRV_LIST], 0 ; check if driver is running
295
	je	.doesnt_exist
296
 
297
	test	bl, bl			; 0 = Get device type (ethernet/token ring/...)
298
	jnz	@f
1196 hidnplayr 299
					 ; todo
1192 hidnplayr 300
	xor	eax, eax
301
	jmp	.return
1159 hidnplayr 302
 
303
 
304
  @@:
305
	dec	bl			; 1 = Get device name
306
	jnz	@f
307
 
308
	mov	esi, [esi + ETH_DRV_LIST]
309
	mov	esi, [esi + ETH_DEVICE.name]
310
	mov	edi, ecx
311
 
312
	mov	ecx, 64 ; max length
313
	repnz	movsb
314
 
1192 hidnplayr 315
	xor	eax, eax
316
	jmp	.return
1159 hidnplayr 317
 
1192 hidnplayr 318
  @@:
1159 hidnplayr 319
 
1192 hidnplayr 320
	dec	bl			; 2 = Reset the device
321
	jnz	@f
322
 
323
	mov	esi, [esi + ETH_DRV_LIST]
324
	call	[esi + ETH_DEVICE.reset]
325
	jmp	.return
326
 
1159 hidnplayr 327
  @@:
1192 hidnplayr 328
 
329
	dec	bl			; 3 = Stop driver for this device
330
	jnz	@f
331
 
332
	mov	esi, [esi + ETH_DRV_LIST]
333
	call	[esi + ETH_DEVICE.unload]
334
	jmp	.return
335
 
336
  @@:
1249 hidnplayr 337
	dec	bl			; 4 = Get driver pointer
338
	jnz	@f
1192 hidnplayr 339
 
1249 hidnplayr 340
	; ..;
341
 
342
 
343
  @@:
344
;  ...                                   ; 5 Get driver name
345
 
1159 hidnplayr 346
  .doesnt_exist:
347
	DEBUGF	1,"sys_network: invalid device/function specified!\n"
348
	mov	eax, -1
349
 
1192 hidnplayr 350
  .return:
351
	mov	[esp+28+4], eax
1159 hidnplayr 352
	ret
353
 
354
 
355
;----------------------------------------------------------------
356
;
1171 hidnplayr 357
;  System Function To work with Protocols  (75)
1159 hidnplayr 358
;
359
;----------------------------------------------------------------
360
align 4
361
sys_protocols:
362
	cmp	bh, MAX_NET_DEVICES		; Check if device number exists
363
	jge	.doesnt_exist
364
 
365
	mov	esi, ebx
366
	and	esi, 0x0000ff00
367
	shr	esi, 6
1171 hidnplayr 368
	cmp	dword [esi + ETH_DRV_LIST], 0	; check if driver is running TODO: check other lists too
1159 hidnplayr 369
	je	.doesnt_exist
370
 
371
	push	.return 			; return address (we will be using jumps instead of calls)
372
 
373
	mov	eax, ebx			; set ax to protocol number
374
	shr	eax, 16 			;
375
 
376
	cmp	ax , IP_PROTO_IP
377
	je	IPv4_API
378
 
379
	cmp	ax , IP_PROTO_ICMP
380
	je	ICMP_API
381
 
382
	cmp	ax , IP_PROTO_UDP
383
	je	UDP_API
384
 
1171 hidnplayr 385
	cmp	ax , IP_PROTO_TCP
1254 hidnplayr 386
	je	TCP_API
1159 hidnplayr 387
 
1171 hidnplayr 388
	cmp	ax , ETHER_ARP
1159 hidnplayr 389
	je	ARP_API
390
 
1185 hidnplayr 391
	cmp	ax , ETHER
1159 hidnplayr 392
	je	ETH_API
393
 
1171 hidnplayr 394
	add	esp, 4				 ; if we reached here, no function was called, so we need to balance stack
1159 hidnplayr 395
 
396
  .doesnt_exist:
1171 hidnplayr 397
	DEBUGF	1,"sys_protocols: protocol %u doesnt exist on device %u!\n",ax, bh
1159 hidnplayr 398
	mov	eax, -1
399
 
400
  .return:
1171 hidnplayr 401
	mov	[esp+28+4], eax
1257 hidnplayr 402
	ret