Subversion Repositories Kolibri OS

Rev

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