Subversion Repositories Kolibri OS

Rev

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