Subversion Repositories Kolibri OS

Rev

Rev 1318 | 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: 1473 $
1159 hidnplayr 21
 
1473 hidnplayr 22
__DEBUG_LEVEL_OLD__  equ __DEBUG_LEVEL__
23
__DEBUG_LEVEL__ equ 1			; this sets the debug level for network part of kernel
24
 
1159 hidnplayr 25
uglobal
26
	last_1sTick	db ?
27
	last_1hsTick	dd ?
28
endg
29
 
1259 hidnplayr 30
MAX_NET_DEVICES 	equ 16
1473 hidnplayr 31
QUEUE_BEFORE_SENDING	equ 0		; 1 or 0 (enable or disable) currently only affects ethernet
1159 hidnplayr 32
 
1185 hidnplayr 33
MIN_EPHEMERAL_PORT equ 49152
34
MAX_EPHEMERAL_PORT equ 61000
1159 hidnplayr 35
 
1473 hidnplayr 36
ETHER		equ 1337		; TODO: find another value for this (how does it work in posix ?)
1185 hidnplayr 37
ETHER_ARP	equ 0x0608
38
 
1254 hidnplayr 39
AF_UNSPEC	equ 0
1249 hidnplayr 40
AF_UNIX 	equ 1
1159 hidnplayr 41
AF_INET4	equ 2
42
;AF_AX25         equ 3
43
;AF_IPX          equ 4
44
;AF_APPLETALK    equ 5
45
;AF_NETROM       equ 6
46
;AF_BRIDGE       equ 7
47
;AF_AAL5         equ 8
48
;AF_X25          equ 9
49
;AF_INET6        equ 10
50
;AF_MAX          equ 12
51
 
52
IP_PROTO_IP	equ 0
53
IP_PROTO_ICMP	equ 1
54
IP_PROTO_TCP	equ 6
55
IP_PROTO_UDP	equ 17
56
 
1200 hidnplayr 57
; Socket types
58
SOCK_STREAM	= 1
59
SOCK_DGRAM	= 2
60
SOCK_RAW	= 3
61
 
1254 hidnplayr 62
TCB_LISTEN		equ 1
63
TCB_SYN_SENT		equ 2
64
TCB_SYN_RECEIVED	equ 3
65
TCB_ESTABLISHED 	equ 4
66
TCB_FIN_WAIT_1		equ 5
67
TCB_FIN_WAIT_2		equ 6
68
TCB_CLOSE_WAIT		equ 7
69
TCB_CLOSING		equ 8
70
TCB_LAST_ACK		equ 9
71
TCB_TIMED_WAIT		equ 10
72
TCB_CLOSED		equ 11
1159 hidnplayr 73
 
1254 hidnplayr 74
TH_FIN			equ 1 shl 0
75
TH_SYN			equ 1 shl 1
76
TH_RST			equ 1 shl 2
77
TH_PUSH 		equ 1 shl 3
78
TH_ACK			equ 1 shl 4
79
TH_URG			equ 1 shl 5
80
 
81
 
82
macro inc_INET reg {
83
 
1256 clevermous 84
	add	byte [reg + 3], 1
1254 hidnplayr 85
	adc	byte [reg + 2], 0
86
	adc	byte [reg + 1], 0
1256 clevermous 87
	adc	byte [reg], 0
1254 hidnplayr 88
 
89
}
90
 
91
 
92
macro add_INET reg {
1256 clevermous 93
	add	byte [reg + 3], cl
94
	adc	byte [reg + 2], ch
95
	adc	byte [reg + 1], 0
96
	adc	byte [reg], 0
1254 hidnplayr 97
	rol	ecx, 16
1256 clevermous 98
	add	byte [reg + 1], cl
99
	adc	byte [reg], ch
1254 hidnplayr 100
	rol	ecx, 16
101
}
102
 
1318 hidnplayr 103
 
104
macro pseudo_random reg {
105
 
106
	add	reg, [esp]
107
	rol	reg, 5
108
	xor	reg, [timer_ticks]
109
	imul	reg, 214013
110
	xor	reg, 0xdeadbeef
111
	rol	reg, 9
112
 
113
	pushd	reg
114
	mov	word [esp], 0x8080 ; kernel heap start addr      (os_stack)
115
	xor	reg, [esp]
116
	add	esp, 4
117
 
118
}
119
 
1159 hidnplayr 120
include "queue.inc"
1187 hidnplayr 121
include "ARP.inc"
122
include "IPv4.inc"
1159 hidnplayr 123
include "ethernet.inc"
124
include "socket.inc"
1249 hidnplayr 125
include "tcp.inc"
1185 hidnplayr 126
include "udp.inc"
127
include "icmp.inc"
1159 hidnplayr 128
 
1257 hidnplayr 129
;-----------------------------------------------------------------
1159 hidnplayr 130
;
131
; stack_init
132
;
133
;  This function calls all network init procedures
134
;
135
;  IN:  /
136
;  OUT: /
137
;
1257 hidnplayr 138
;-----------------------------------------------------------------
1159 hidnplayr 139
align 4
140
stack_init:
141
 
142
	call	ETH_init
143
	call	IPv4_init
144
	call	ARP_init
145
	call	UDP_init
1249 hidnplayr 146
	call	TCP_init
1159 hidnplayr 147
	call	ICMP_init
148
	call	socket_init
149
 
1254 hidnplayr 150
	mov	al, 0		      ; set up 1s timer
1159 hidnplayr 151
	out	0x70, al
152
	in	al, 0x71
153
	mov	[last_1sTick], al
154
 
155
	ret
156
 
157
 
158
 
1257 hidnplayr 159
;-----------------------------------------------------------------
1159 hidnplayr 160
;
161
; stack_handler
162
;
163
;  This function calls all network init procedures
164
;
165
;  IN:  /
166
;  OUT: /
167
;
1257 hidnplayr 168
;-----------------------------------------------------------------
1159 hidnplayr 169
align 4
170
stack_handler:
171
 
1257 hidnplayr 172
	cmp	[ETH_RUNNING], 0
173
	je	.exit
1159 hidnplayr 174
 
1318 hidnplayr 175
	; Test for 10ms tick
1257 hidnplayr 176
	mov	eax, [timer_ticks]
177
	cmp	eax, [last_1hsTick]
178
	je	.exit
1159 hidnplayr 179
 
1257 hidnplayr 180
	mov	[last_1hsTick], eax
1159 hidnplayr 181
 
1257 hidnplayr 182
	call	ETH_handler		    ; handle all queued ethernet packets
1259 hidnplayr 183
if QUEUE_BEFORE_SENDING
1257 hidnplayr 184
	call	ETH_send_queued
1259 hidnplayr 185
end if
1257 hidnplayr 186
	call	TCP_send_queued
1249 hidnplayr 187
 
1159 hidnplayr 188
  .sec_tick:
189
 
1257 hidnplayr 190
	; Test for 1 second tick
191
	mov	al, 0
192
	out	0x70, al
193
	in	al, 0x71
194
	cmp	al, [last_1sTick]
195
	je	.exit
1159 hidnplayr 196
 
1257 hidnplayr 197
	mov	[last_1sTick], al
1159 hidnplayr 198
 
1257 hidnplayr 199
	call	ARP_decrease_entry_ttls
200
	call	IPv4_decrease_fragment_ttls
201
	call	TCP_decrease_socket_ttls
1159 hidnplayr 202
 
203
  .exit:
1257 hidnplayr 204
	ret
1159 hidnplayr 205
 
206
 
1249 hidnplayr 207
;-----------------------------------------------------------------
208
;
209
; checksum_1
210
;
211
;  This is the first of two functions needed to calculate the TCP checksum.
212
;
1473 hidnplayr 213
;  IN:  edx = start offset for semi-checksum
1249 hidnplayr 214
;       esi = pointer to data
215
;       ecx = data size
216
;  OUT: edx = semi-checksum
217
;
1473 hidnplayr 218
;
219
; Code was optimized by diamond
220
;
1249 hidnplayr 221
;-----------------------------------------------------------------
222
align 4
223
checksum_1:
1159 hidnplayr 224
 
1249 hidnplayr 225
	shr	ecx, 1
226
	pushf
1473 hidnplayr 227
	jz	.no_2
1159 hidnplayr 228
 
1473 hidnplayr 229
	shr	ecx, 1
230
	pushf
231
	jz	.no_4
232
 
233
	shr	ecx, 1
234
	pushf
235
	jz	.no_8
236
 
237
  .loop:
238
	add	dl, [esi+1]
239
	adc	dh, [esi+0]
240
 
241
	adc	dl, [esi+3]
242
	adc	dh, [esi+2]
243
 
244
	adc	dl, [esi+5]
245
	adc	dh, [esi+4]
246
 
247
	adc	dl, [esi+7]
248
	adc	dh, [esi+6]
249
 
250
	adc	edx, 0
251
	add	esi, 8
252
 
253
	dec	ecx
254
	jnz	.loop
255
 
256
	adc	edx, 0
257
 
258
  .no_8:
1249 hidnplayr 259
	popf
1473 hidnplayr 260
	jnc	.no_4
261
 
262
	add	dl, [esi+1]
263
	adc	dh, [esi+0]
264
 
265
	adc	dl, [esi+3]
266
	adc	dh, [esi+2]
267
 
268
	adc	edx, 0
269
	add	esi, 4
270
 
271
  .no_4:
272
	popf
273
	jnc	.no_2
274
 
275
	add	dl, [esi+1]
276
	adc	dh, [esi+0]
277
 
278
	adc	edx, 0
279
 
280
	inc	ecx
281
	inc	ecx
282
 
283
  .no_2:
284
	popf
1249 hidnplayr 285
	jnc	.end
1159 hidnplayr 286
 
1473 hidnplayr 287
	add	dh, [esi+0]
1251 clevermous 288
	adc	edx, 0
1473 hidnplayr 289
  .end:
290
	ret
1159 hidnplayr 291
 
1249 hidnplayr 292
 
1473 hidnplayr 293
 
294
 
295
 
296
;IN: 12 bytes of pseudoheader pushed onto the stack
297
;    edx = start offset
298
;
299
; OUT: pseudochecksum in edx
300
 
301
 
302
align 4
303
checksum_pseudoheader:
304
 
305
	add	dl, [esp+5]
306
	adc	dh, [esp+4]
307
 
308
	adc	dl, [esp+7]
309
	adc	dh, [esp+6]
310
 
311
	adc	dl, [esp+9]
312
	adc	dh, [esp+8]
313
 
314
	adc	dl, [esp+11]
315
	adc	dh, [esp+10]
316
 
317
	adc	dl, [esp+13]
318
	adc	dh, [esp+12]
319
 
320
	adc	dl, [esp+15]
321
	adc	dh, [esp+14]
322
 
323
	adc	edx,0
324
	ret	12
325
 
326
 
327
 
328
 
329
 
330
align 4
331
checksum_ip_header:
332
 
333
; This is the fast procedure to create or check a IP header without options
334
;
335
; To create a new checksum, the checksum field must be set to 0 before computation
336
;
337
; To check an existing checksum, leave the checksum as is, and it will be 0 after this procedure, if it was correct
338
 
339
	xor	edx, edx
340
 
341
	add	dl, [esi+1]
342
	adc	dh, [esi+0]
343
 
344
	adc	dl, [esi+3]
345
	adc	dh, [esi+2]
346
 
347
	adc	dl, [esi+5]
348
	adc	dh, [esi+4]
349
 
350
	adc	dl, [esi+7]
351
	adc	dh, [esi+6]
352
 
353
	adc	dl, [esi+9]
354
	adc	dh, [esi+8]
355
 
356
; we skip 11th and 12th byte, they are the checksum bytes and should be 0 for re-calculation
357
 
358
	adc	dl, [esi+13]
359
	adc	dh, [esi+12]
360
 
361
	adc	dl, [esi+15]
362
	adc	dh, [esi+14]
363
 
364
	adc	dl, [esi+17]
365
	adc	dh, [esi+16]
366
 
367
	adc	dl, [esi+19]
368
	adc	dh, [esi+18]
369
 
370
	adc	edx, 0
371
 
372
	call	checksum_2
373
 
374
	neg	word [esi+10]		; zero will stay zero so we jsut get the checksum
375
	add	word [esi+10], dx	;  , else we will get (new checksum - old checksum) in the end, wich should be 0 :)
376
 
1249 hidnplayr 377
	ret
378
 
379
 
1473 hidnplayr 380
 
381
 
382
 
383
 
384
 
385
 
386
align 4
387
checksum_udp:
388
 
389
; This is the fast procedure to create or check a IP header without options
390
;
391
; To create a new checksum, the checksum field must be set to 0 before computation
392
;
393
; To check an existing checksum, leave the checksum as is, and it will be 0 after this procedure, if it was correct
394
 
395
	xor	edx, edx
396
 
397
	add	dl, [esi+1]
398
	adc	dh, [esi+0]
399
 
400
	adc	dl, [esi+3]
401
	adc	dh, [esi+2]
402
 
403
	adc	dl, [esi+5]
404
	adc	dh, [esi+4]
405
 
406
	adc	dl, [esi+7]
407
	adc	dh, [esi+6]
408
 
409
	adc	dl, [esi+9]
410
	adc	dh, [esi+8]
411
 
412
; we skip 11th and 12th byte, they are the checksum bytes and should be 0 for re-calculation
413
 
414
	adc	dl, [esi+13]
415
	adc	dh, [esi+12]
416
 
417
	adc	dl, [esi+15]
418
	adc	dh, [esi+14]
419
 
420
	adc	dl, [esi+17]
421
	adc	dh, [esi+16]
422
 
423
	adc	dl, [esi+19]
424
	adc	dh, [esi+18]
425
 
426
	adc	edx, 0
427
 
428
	call	checksum_2
429
 
430
	neg	word [esi+10]		; zero will stay zero so we jsut get the checksum
431
	add	word [esi+10], dx	;  , else we will get (new checksum - old checksum) in the end, wich should be 0 :)
432
 
433
	ret
434
 
435
 
436
 
1249 hidnplayr 437
;-----------------------------------------------------------------
438
;
439
; checksum_2
440
;
441
;  This function calculates the final ip/tcp/udp checksum for you
442
;
443
;  IN:  edx = semi-checksum
444
;  OUT: dx = checksum (in INET byte order)
445
;
446
;-----------------------------------------------------------------
447
align 4
448
checksum_2:
449
 
450
	mov	ecx, edx
451
	shr	ecx, 16
452
	and	edx, 0xffff
453
	add	edx, ecx
454
	mov	eax, edx
455
	shr	eax, 16
456
	add	edx, eax
457
 
458
	not	dx
459
	jnz	.not_zero
460
	dec	dx
461
  .not_zero:
462
	xchg	dl, dh
463
 
464
	DEBUGF 1,"Checksum: %x\n",dx
465
 
466
	ret
467
 
468
 
469
 
1159 hidnplayr 470
;----------------------------------------------------------------
471
;
1171 hidnplayr 472
;  System function to work with network devices (73)
1159 hidnplayr 473
;
474
;----------------------------------------------------------------
475
align 4
476
sys_network:
477
 
1196 hidnplayr 478
	cmp	ebx, -1
479
	jne	@f
480
 
481
	mov	eax, [ETH_RUNNING]
482
	jmp	.return
483
 
484
   @@:
1159 hidnplayr 485
	cmp	bh, MAX_NET_DEVICES		 ; Check if device number exists
486
	jge	.doesnt_exist
487
 
488
	mov	esi, ebx
489
	and	esi, 0x0000ff00
490
	shr	esi, 6
491
 
492
	cmp	dword [esi + ETH_DRV_LIST], 0 ; check if driver is running
493
	je	.doesnt_exist
494
 
495
	test	bl, bl			; 0 = Get device type (ethernet/token ring/...)
496
	jnz	@f
1196 hidnplayr 497
					 ; todo
1192 hidnplayr 498
	xor	eax, eax
499
	jmp	.return
1159 hidnplayr 500
 
501
 
502
  @@:
503
	dec	bl			; 1 = Get device name
504
	jnz	@f
505
 
506
	mov	esi, [esi + ETH_DRV_LIST]
507
	mov	esi, [esi + ETH_DEVICE.name]
508
	mov	edi, ecx
509
 
510
	mov	ecx, 64 ; max length
511
	repnz	movsb
512
 
1192 hidnplayr 513
	xor	eax, eax
514
	jmp	.return
1159 hidnplayr 515
 
1192 hidnplayr 516
  @@:
1159 hidnplayr 517
 
1192 hidnplayr 518
	dec	bl			; 2 = Reset the device
519
	jnz	@f
520
 
521
	mov	esi, [esi + ETH_DRV_LIST]
522
	call	[esi + ETH_DEVICE.reset]
523
	jmp	.return
524
 
1159 hidnplayr 525
  @@:
1192 hidnplayr 526
 
527
	dec	bl			; 3 = Stop driver for this device
528
	jnz	@f
529
 
530
	mov	esi, [esi + ETH_DRV_LIST]
531
	call	[esi + ETH_DEVICE.unload]
532
	jmp	.return
533
 
534
  @@:
1249 hidnplayr 535
	dec	bl			; 4 = Get driver pointer
536
	jnz	@f
1192 hidnplayr 537
 
1249 hidnplayr 538
	; ..;
539
 
540
 
541
  @@:
542
;  ...                                   ; 5 Get driver name
543
 
1159 hidnplayr 544
  .doesnt_exist:
545
	DEBUGF	1,"sys_network: invalid device/function specified!\n"
546
	mov	eax, -1
547
 
1192 hidnplayr 548
  .return:
549
	mov	[esp+28+4], eax
1159 hidnplayr 550
	ret
551
 
552
 
553
;----------------------------------------------------------------
554
;
1171 hidnplayr 555
;  System Function To work with Protocols  (75)
1159 hidnplayr 556
;
557
;----------------------------------------------------------------
558
align 4
559
sys_protocols:
560
	cmp	bh, MAX_NET_DEVICES		; Check if device number exists
561
	jge	.doesnt_exist
562
 
563
	mov	esi, ebx
564
	and	esi, 0x0000ff00
565
	shr	esi, 6
1171 hidnplayr 566
	cmp	dword [esi + ETH_DRV_LIST], 0	; check if driver is running TODO: check other lists too
1159 hidnplayr 567
	je	.doesnt_exist
568
 
569
	push	.return 			; return address (we will be using jumps instead of calls)
570
 
571
	mov	eax, ebx			; set ax to protocol number
572
	shr	eax, 16 			;
573
 
574
	cmp	ax , IP_PROTO_IP
575
	je	IPv4_API
576
 
577
	cmp	ax , IP_PROTO_ICMP
578
	je	ICMP_API
579
 
580
	cmp	ax , IP_PROTO_UDP
581
	je	UDP_API
582
 
1171 hidnplayr 583
	cmp	ax , IP_PROTO_TCP
1254 hidnplayr 584
	je	TCP_API
1159 hidnplayr 585
 
1171 hidnplayr 586
	cmp	ax , ETHER_ARP
1159 hidnplayr 587
	je	ARP_API
588
 
1185 hidnplayr 589
	cmp	ax , ETHER
1159 hidnplayr 590
	je	ETH_API
591
 
1171 hidnplayr 592
	add	esp, 4				 ; if we reached here, no function was called, so we need to balance stack
1159 hidnplayr 593
 
594
  .doesnt_exist:
1171 hidnplayr 595
	DEBUGF	1,"sys_protocols: protocol %u doesnt exist on device %u!\n",ax, bh
1159 hidnplayr 596
	mov	eax, -1
597
 
598
  .return:
1171 hidnplayr 599
	mov	[esp+28+4], eax
1257 hidnplayr 600
	ret
1473 hidnplayr 601
 
602
 
603
__DEBUG_LEVEL__ equ __DEBUG_LEVEL_OLD__