Subversion Repositories Kolibri OS

Rev

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