Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1171 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
1514 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.    ;;
1171 hidnplayr 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: 1543 $
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
1514 hidnplayr 26
	net_10ms       dd ?
27
	net_tmr_count  dw ?
1159 hidnplayr 28
endg
29
 
1259 hidnplayr 30
MAX_NET_DEVICES 	equ 16
1159 hidnplayr 31
 
1514 hidnplayr 32
ETH_QUEUE		equ 0		; 1 = enable / 0 = disable
33
 
1185 hidnplayr 34
MIN_EPHEMERAL_PORT equ 49152
35
MAX_EPHEMERAL_PORT equ 61000
1159 hidnplayr 36
 
1514 hidnplayr 37
; Ethernet protocol numbers
1519 hidnplayr 38
ETHER_ARP		equ 0x0608
39
ETHER_IPv4		equ 0x0008		; Reversed from 0800 for intel
40
ETHER_PPP_DISCOVERY	equ 0x6388
41
ETHER_PPP_SESSION	equ 0x6488
1185 hidnplayr 42
 
1514 hidnplayr 43
;Protocol family
1254 hidnplayr 44
AF_UNSPEC	equ 0
1249 hidnplayr 45
AF_UNIX 	equ 1
1159 hidnplayr 46
AF_INET4	equ 2
47
;AF_AX25         equ 3
48
;AF_IPX          equ 4
49
;AF_APPLETALK    equ 5
50
;AF_NETROM       equ 6
51
;AF_BRIDGE       equ 7
52
;AF_AAL5         equ 8
53
;AF_X25          equ 9
1514 hidnplayr 54
AF_INET6	equ 10
1159 hidnplayr 55
;AF_MAX          equ 12
56
 
1514 hidnplayr 57
; Internet protocol numbers
1159 hidnplayr 58
IP_PROTO_IP	equ 0
59
IP_PROTO_ICMP	equ 1
60
IP_PROTO_TCP	equ 6
61
IP_PROTO_UDP	equ 17
62
 
1200 hidnplayr 63
; Socket types
1514 hidnplayr 64
SOCK_STREAM	equ 1
65
SOCK_DGRAM	equ 2
66
SOCK_RAW	equ 3
1200 hidnplayr 67
 
1514 hidnplayr 68
; Socket options
1529 hidnplayr 69
SO_ACCEPTCON	equ 1
1159 hidnplayr 70
 
1529 hidnplayr 71
SOCKET_MAXDATA	equ 4096*32	; must be 4096*(power of 2) where 'power of 2' is at least 8
1254 hidnplayr 72
 
1514 hidnplayr 73
; Network driver types
74
NET_TYPE_ETH	equ 1
75
NET_TYPE_SLIP	equ 2
1254 hidnplayr 76
 
1543 hidnplayr 77
MAX_backlog	equ 20		; maximum backlog for stream sockets
1254 hidnplayr 78
 
1529 hidnplayr 79
 
1514 hidnplayr 80
virtual at 0
1254 hidnplayr 81
 
1514 hidnplayr 82
	NET_DEVICE:
1519 hidnplayr 83
 
84
	.type		dd ?	; Type field
85
	.mtu		dd ?	; Maximal Transmission Unit
86
	.name		dd ?	; Ptr to 0 terminated string
87
 
88
	.unload 	dd ?	; Ptrs to driver functions
89
	.reset		dd ?	;
90
	.transmit	dd ?	;
91
 
92
	.bytes_tx	dq ?	; Statistics, updated by the driver
93
	.bytes_rx	dq ?	;
94
	.packets_tx	dd ?	;
95
	.packets_rx	dd ?	;
96
 
1529 hidnplayr 97
;       .chksum         dd ?    ; bitmask stating available checksum routines on hardware
98
 
1514 hidnplayr 99
	.end:
1254 hidnplayr 100
 
1514 hidnplayr 101
end virtual
1254 hidnplayr 102
 
103
 
1514 hidnplayr 104
; Exactly as it says..
1318 hidnplayr 105
macro pseudo_random reg {
106
	add	reg, [esp]
107
	rol	reg, 5
108
	xor	reg, [timer_ticks]
1529 hidnplayr 109
	add	reg, [CPU_FREQ]
1318 hidnplayr 110
	imul	reg, 214013
111
	xor	reg, 0xdeadbeef
112
	rol	reg, 9
1514 hidnplayr 113
}
1318 hidnplayr 114
 
1543 hidnplayr 115
macro ntohd reg {
1318 hidnplayr 116
 
1514 hidnplayr 117
	rol	word reg, 8
118
	rol	dword reg, 16
1529 hidnplayr 119
	rol	word reg , 8
1514 hidnplayr 120
 
1318 hidnplayr 121
}
122
 
1543 hidnplayr 123
macro ntohw reg {
1514 hidnplayr 124
 
125
	rol	word reg, 8
126
 
127
}
128
 
129
 
1529 hidnplayr 130
macro packet_to_debug { 	; set esi to packet you want to print, ecx to number of bytes
131
 
132
local	.loop
133
 
134
  .loop:
135
	lodsb
136
	DEBUGF	1,"%x ", eax:2
137
	loop	@r
138
 
139
}
140
 
141
 
1159 hidnplayr 142
include "queue.inc"
1514 hidnplayr 143
 
144
include "ethernet.inc"
145
;include "slip.inc"
146
 
1187 hidnplayr 147
include "ARP.inc"
148
include "IPv4.inc"
1514 hidnplayr 149
 
150
include "icmp.inc"
151
include "udp.inc"
1249 hidnplayr 152
include "tcp.inc"
1159 hidnplayr 153
 
1514 hidnplayr 154
include "socket.inc"
155
 
156
 
157
 
158
align 4
159
uglobal
160
 
161
	NET_RUNNING	dd  ?
162
	NET_DRV_LIST	rd  MAX_NET_DEVICES
163
 
164
endg
165
 
166
 
1257 hidnplayr 167
;-----------------------------------------------------------------
1159 hidnplayr 168
;
169
; stack_init
170
;
171
;  This function calls all network init procedures
172
;
173
;  IN:  /
174
;  OUT: /
175
;
1257 hidnplayr 176
;-----------------------------------------------------------------
1159 hidnplayr 177
align 4
178
stack_init:
179
 
1514 hidnplayr 180
; Init the network drivers list
181
	xor	eax, eax
182
	mov	edi, NET_RUNNING
183
	mov	ecx, MAX_NET_DEVICES + 1
184
	rep	stosd
185
 
1529 hidnplayr 186
	ETH_init
187
;        SLIP_init
188
;        PPPOE_init
1514 hidnplayr 189
 
1529 hidnplayr 190
	IPv4_init
191
	ICMP_init
1514 hidnplayr 192
 
1529 hidnplayr 193
	ARP_init
194
	UDP_init
195
	TCP_init
1514 hidnplayr 196
 
1529 hidnplayr 197
	SOCKET_init
1514 hidnplayr 198
 
199
	mov	[net_tmr_count], 0
1159 hidnplayr 200
 
201
	ret
202
 
203
 
1257 hidnplayr 204
;-----------------------------------------------------------------
1159 hidnplayr 205
;
206
; stack_handler
207
;
1514 hidnplayr 208
;  This function is called in kernel loop
1159 hidnplayr 209
;
210
;  IN:  /
211
;  OUT: /
212
;
1257 hidnplayr 213
;-----------------------------------------------------------------
1159 hidnplayr 214
align 4
215
stack_handler:
216
 
1514 hidnplayr 217
	cmp	[NET_RUNNING], 0
1257 hidnplayr 218
	je	.exit
1159 hidnplayr 219
 
1318 hidnplayr 220
	; Test for 10ms tick
1257 hidnplayr 221
	mov	eax, [timer_ticks]
1514 hidnplayr 222
	cmp	eax, [net_10ms]
1257 hidnplayr 223
	je	.exit
1514 hidnplayr 224
	mov	[net_10ms], eax
1159 hidnplayr 225
 
1519 hidnplayr 226
	test	[net_10ms], 0x0f	; 160ms
227
	jnz	.exit
1249 hidnplayr 228
 
1529 hidnplayr 229
	TCP_timer_160ms
1159 hidnplayr 230
 
1519 hidnplayr 231
	test	[net_10ms], 0x3f	; 640ms
232
	jnz	.exit
233
 
1529 hidnplayr 234
	TCP_timer_640ms
235
	ARP_decrease_entry_ttls
236
	IPv4_decrease_fragment_ttls
1159 hidnplayr 237
 
238
  .exit:
1257 hidnplayr 239
	ret
1159 hidnplayr 240
 
241
 
1514 hidnplayr 242
 
1249 hidnplayr 243
;-----------------------------------------------------------------
244
;
1514 hidnplayr 245
; NET_Add_Device:
246
;
247
;  This function is called by the network drivers,
248
;  to register each running NIC to the kernel
249
;
250
;  IN:  Pointer to device structure in ebx
251
;  OUT: Device num in eax, -1 on error
252
;
253
;-----------------------------------------------------------------
254
align 4
255
NET_add_device:
256
 
257
	DEBUGF	1,"NET_Add_Device: %x\n", ebx
258
 
259
	mov	eax, [NET_RUNNING]
260
	cmp	eax, MAX_NET_DEVICES
261
	jge	.error
262
 
263
;----------------------------------
264
; Check if device is already listed
265
	mov	eax, ebx
266
	mov	ecx, MAX_NET_DEVICES	  ; We need to check whole list because a device may be removed without re-organizing list
267
	mov	edi, NET_DRV_LIST
268
 
269
	repne	scasd			  ; See if device is already in the list
270
	jz	.error
271
 
272
;----------------------------
273
; Find empty slot in the list
274
	xor	eax, eax
275
	mov	ecx, MAX_NET_DEVICES
276
	mov	edi, NET_DRV_LIST
277
 
278
	repne	scasd
279
	jnz	.error
280
 
281
	sub	edi, 4
282
 
283
	cmp	[ebx + NET_DEVICE.type], NET_TYPE_ETH
284
	je	.ethernet
285
 
286
	cmp	[ebx + NET_DEVICE.type], NET_TYPE_SLIP
287
	je	.slip
288
 
289
	DEBUGF	1,"Unknown network device type: %u\n", [ebx + NET_DEVICE.type]
290
	jmp	.error
291
 
292
  .ethernet:
1529 hidnplayr 293
	DEBUGF	1,"Trying to add an ethernet device\n"
1514 hidnplayr 294
 
295
	inc	[ETH_RUNNING]		  ; Indicate that one more ethernet device is up and running
296
	jmp	.add_it
297
 
298
  .slip:
1529 hidnplayr 299
	DEBUGF	1,"Trying to add a slip device\n"
1514 hidnplayr 300
	;;;;
301
	jmp	.error
302
 
303
 
304
  .add_it:
305
 
306
;-----------------------------
307
; Add device to the found slot
308
	mov	[edi], ebx		  ; add device to list
309
 
310
	sub	edi, NET_DRV_LIST	  ; Calculate device number in eax
311
	mov	eax, edi		  ;
312
	shr	eax, 2
313
 
314
	inc	[NET_RUNNING]		  ; Indicate that one more network device is up and running
315
 
316
	DEBUGF	1,"Device number: %u\n",eax
317
	ret
318
 
319
  .error:
320
	or	eax, -1
321
	DEBUGF	2,"Adding network device failed\n"
322
	ret
323
 
324
 
325
 
326
;-----------------------------------------------------------------
327
;
328
; NET_Remove_Device:
329
;
330
;  This function is called by etwork drivers,
331
;  to unregister network devices from the kernel
332
;
333
;  IN:  Pointer to device structure in ebx
334
;  OUT: eax: -1 on error
335
;
336
;-----------------------------------------------------------------
337
align 4
338
NET_remove_device:
339
 
340
	cmp	[NET_RUNNING], 0
341
	je	.error
342
 
343
;----------------------------
344
; Find the driver in the list
345
 
346
	mov	eax, ebx
347
	mov	ecx, MAX_NET_DEVICES
348
	mov	edi, NET_DRV_LIST
349
 
350
	repne	scasd
351
	jnz	.error
352
 
353
;------------------------
354
; Remove it from the list
355
 
356
	xor	eax, eax
357
	mov	dword [edi-4], eax
358
 
359
	dec	[NET_RUNNING]
360
	ret
361
 
362
  .error:
363
	or	eax, -1
364
	ret
365
 
366
 
367
 
368
;-----------------------------------------------------------------
369
;
370
; NET_ptr_to_num
371
;
372
; IN:  ebx = ptr to device struct
373
; OUT: edi = -1 on error, device number otherwise
374
;
375
;-----------------------------------------------------------------
376
align 4
377
NET_ptr_to_num:
378
	push	ecx
379
 
380
	mov	ecx, MAX_NET_DEVICES
381
	mov	edi, NET_DRV_LIST
382
 
383
  .loop:
384
	cmp	ebx, [edi]
385
	jz	.found
386
	add	edi, 4
387
	dec	ecx
388
	jnz	.loop
389
 
390
	; repnz  scasd could work too if eax is used instead of ebx!
391
 
392
	or	edi, -1
393
 
394
	pop	ecx
395
	ret
396
 
397
  .found:
398
	sub	edi, NET_DRV_LIST
399
	shr	edi, 2
400
 
401
	pop	ecx
402
	ret
403
 
404
;-----------------------------------------------------------------
405
;
1249 hidnplayr 406
; checksum_1
407
;
1482 hidnplayr 408
;  This is the first of two functions needed to calculate a checksum.
1249 hidnplayr 409
;
1473 hidnplayr 410
;  IN:  edx = start offset for semi-checksum
1249 hidnplayr 411
;       esi = pointer to data
412
;       ecx = data size
413
;  OUT: edx = semi-checksum
414
;
1473 hidnplayr 415
;
416
; Code was optimized by diamond
417
;
1249 hidnplayr 418
;-----------------------------------------------------------------
419
align 4
420
checksum_1:
1159 hidnplayr 421
 
1249 hidnplayr 422
	shr	ecx, 1
423
	pushf
1473 hidnplayr 424
	jz	.no_2
1159 hidnplayr 425
 
1473 hidnplayr 426
	shr	ecx, 1
427
	pushf
428
	jz	.no_4
429
 
430
	shr	ecx, 1
431
	pushf
432
	jz	.no_8
433
 
434
  .loop:
435
	add	dl, [esi+1]
436
	adc	dh, [esi+0]
437
 
438
	adc	dl, [esi+3]
439
	adc	dh, [esi+2]
440
 
441
	adc	dl, [esi+5]
442
	adc	dh, [esi+4]
443
 
444
	adc	dl, [esi+7]
445
	adc	dh, [esi+6]
446
 
447
	adc	edx, 0
448
	add	esi, 8
449
 
450
	dec	ecx
451
	jnz	.loop
452
 
453
	adc	edx, 0
454
 
455
  .no_8:
1249 hidnplayr 456
	popf
1473 hidnplayr 457
	jnc	.no_4
458
 
459
	add	dl, [esi+1]
460
	adc	dh, [esi+0]
461
 
462
	adc	dl, [esi+3]
463
	adc	dh, [esi+2]
464
 
465
	adc	edx, 0
466
	add	esi, 4
467
 
468
  .no_4:
469
	popf
470
	jnc	.no_2
471
 
472
	add	dl, [esi+1]
473
	adc	dh, [esi+0]
474
 
475
	adc	edx, 0
1483 hidnplayr 476
	inc	esi
477
	inc	esi
1473 hidnplayr 478
 
479
  .no_2:
480
	popf
1249 hidnplayr 481
	jnc	.end
1159 hidnplayr 482
 
1473 hidnplayr 483
	add	dh, [esi+0]
1251 clevermous 484
	adc	edx, 0
1473 hidnplayr 485
  .end:
486
	ret
1159 hidnplayr 487
 
1249 hidnplayr 488
;-----------------------------------------------------------------
489
;
490
; checksum_2
491
;
492
;  This function calculates the final ip/tcp/udp checksum for you
493
;
494
;  IN:  edx = semi-checksum
495
;  OUT: dx = checksum (in INET byte order)
496
;
497
;-----------------------------------------------------------------
498
align 4
499
checksum_2:
500
 
501
	mov	ecx, edx
502
	shr	ecx, 16
503
	and	edx, 0xffff
504
	add	edx, ecx
505
 
1482 hidnplayr 506
	mov	ecx, edx
507
	shr	ecx, 16
1529 hidnplayr 508
	add	dx, cx
509
	test	dx, dx		; it seems that ZF is not set when CF is set :(
1249 hidnplayr 510
	not	dx
511
	jnz	.not_zero
512
	dec	dx
513
  .not_zero:
514
	xchg	dl, dh
515
 
1529 hidnplayr 516
	DEBUGF 1,"Checksum: %x\n", dx
1249 hidnplayr 517
 
518
	ret
519
 
520
 
521
 
1159 hidnplayr 522
;----------------------------------------------------------------
523
;
1171 hidnplayr 524
;  System function to work with network devices (73)
1159 hidnplayr 525
;
526
;----------------------------------------------------------------
527
align 4
528
sys_network:
529
 
1196 hidnplayr 530
	cmp	ebx, -1
531
	jne	@f
532
 
1514 hidnplayr 533
	mov	eax, [NET_RUNNING]
1196 hidnplayr 534
	jmp	.return
535
 
536
   @@:
1159 hidnplayr 537
	cmp	bh, MAX_NET_DEVICES		 ; Check if device number exists
538
	jge	.doesnt_exist
539
 
540
	mov	esi, ebx
541
	and	esi, 0x0000ff00
542
	shr	esi, 6
543
 
1514 hidnplayr 544
	cmp	dword [esi + NET_DRV_LIST], 0 ; check if driver is running
1159 hidnplayr 545
	je	.doesnt_exist
546
 
1514 hidnplayr 547
	test	bl, bl			 ; 0 = Get device type (ethernet/token ring/...)
1159 hidnplayr 548
	jnz	@f
1514 hidnplayr 549
 
1192 hidnplayr 550
	xor	eax, eax
551
	jmp	.return
1159 hidnplayr 552
 
553
 
554
  @@:
555
	dec	bl			; 1 = Get device name
556
	jnz	@f
557
 
1514 hidnplayr 558
	mov	esi, [esi + NET_DRV_LIST]
1519 hidnplayr 559
	mov	esi, [esi + NET_DEVICE.name]
1159 hidnplayr 560
	mov	edi, ecx
561
 
562
	mov	ecx, 64 ; max length
563
	repnz	movsb
564
 
1192 hidnplayr 565
	xor	eax, eax
566
	jmp	.return
1159 hidnplayr 567
 
1192 hidnplayr 568
  @@:
1159 hidnplayr 569
 
1192 hidnplayr 570
	dec	bl			; 2 = Reset the device
571
	jnz	@f
572
 
1514 hidnplayr 573
	mov	esi, [esi + NET_DRV_LIST]
1519 hidnplayr 574
	call	[esi + NET_DEVICE.reset]
1192 hidnplayr 575
	jmp	.return
576
 
1159 hidnplayr 577
  @@:
1192 hidnplayr 578
 
579
	dec	bl			; 3 = Stop driver for this device
580
	jnz	@f
581
 
1514 hidnplayr 582
	mov	esi, [esi + NET_DRV_LIST]
1519 hidnplayr 583
	call	[esi + NET_DEVICE.unload]
1192 hidnplayr 584
	jmp	.return
585
 
586
  @@:
1249 hidnplayr 587
	dec	bl			; 4 = Get driver pointer
588
	jnz	@f
1192 hidnplayr 589
 
1249 hidnplayr 590
	; ..;
591
 
592
 
593
  @@:
594
;  ...                                   ; 5 Get driver name
595
 
1159 hidnplayr 596
  .doesnt_exist:
597
	DEBUGF	1,"sys_network: invalid device/function specified!\n"
598
	mov	eax, -1
599
 
1192 hidnplayr 600
  .return:
601
	mov	[esp+28+4], eax
1159 hidnplayr 602
	ret
603
 
604
 
605
;----------------------------------------------------------------
606
;
1514 hidnplayr 607
;  System function to work with protocols  (75)
1159 hidnplayr 608
;
609
;----------------------------------------------------------------
610
align 4
611
sys_protocols:
612
	cmp	bh, MAX_NET_DEVICES		; Check if device number exists
613
	jge	.doesnt_exist
614
 
615
	mov	esi, ebx
616
	and	esi, 0x0000ff00
1514 hidnplayr 617
	shr	esi, 6				; now we have the device num * 4 in esi
618
	cmp	dword [esi + NET_DRV_LIST], 0	; check if driver is running
1159 hidnplayr 619
	je	.doesnt_exist
620
 
621
	push	.return 			; return address (we will be using jumps instead of calls)
622
 
623
	mov	eax, ebx			; set ax to protocol number
624
	shr	eax, 16 			;
625
 
626
	cmp	ax , IP_PROTO_IP
627
	je	IPv4_API
628
 
629
	cmp	ax , IP_PROTO_ICMP
630
	je	ICMP_API
631
 
632
	cmp	ax , IP_PROTO_UDP
633
	je	UDP_API
634
 
1171 hidnplayr 635
	cmp	ax , IP_PROTO_TCP
1254 hidnplayr 636
	je	TCP_API
1159 hidnplayr 637
 
1171 hidnplayr 638
	cmp	ax , ETHER_ARP
1159 hidnplayr 639
	je	ARP_API
640
 
1519 hidnplayr 641
	cmp	ax , 1337  ;;;;;
1159 hidnplayr 642
	je	ETH_API
643
 
1171 hidnplayr 644
	add	esp, 4				 ; if we reached here, no function was called, so we need to balance stack
1159 hidnplayr 645
 
646
  .doesnt_exist:
1519 hidnplayr 647
	DEBUGF	1,"sys_protocols: protocol %u doesnt exist on device %u!\n", ax, bh
1159 hidnplayr 648
	mov	eax, -1
649
 
650
  .return:
1171 hidnplayr 651
	mov	[esp+28+4], eax
1257 hidnplayr 652
	ret
1473 hidnplayr 653
 
654
 
655
__DEBUG_LEVEL__ equ __DEBUG_LEVEL_OLD__