Subversion Repositories Kolibri OS

Rev

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