Subversion Repositories Kolibri OS

Rev

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

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