Subversion Repositories Kolibri OS

Rev

Rev 1482 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1482 Rev 1514
Line 1... Line 1...
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  IPv4.INC                                                       ;;
6
;;  IPv4.INC                                                       ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
8
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
Line 14... Line 14...
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June 1991                                ;;
15
;;             Version 2, June 1991                                ;;
16
;;                                                                 ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 18... Line 18...
18
 
18
 
Line 19... Line -...
19
$Revision: 1482 $
-
 
20
 
-
 
21
; IP underlying protocols numbers
-
 
22
 
-
 
23
ETHER_IPv4	equ 0x0008	; Reversed from 0800 for intel
19
$Revision: 1514 $
24
 
20
 
-
 
21
MAX_FRAGMENTS	equ 64
Line 25... Line 22...
25
MAX_FRAGMENTS	equ 16
22
MAX_IP		equ MAX_NET_DEVICES
26
MAX_IP		equ MAX_NET_DEVICES
23
IP_MAX_INTERFACES   equ MAX_IP
27
 
24
 
28
struct	IPv4_Packet
25
struct	IPv4_Packet
29
	.VersionAndIHL		db  ?  ; Version[0-3 bits] and IHL(header length)[4-7 bits]
26
	.VersionAndIHL		db  ?  ; Version[0-3 bits] and IHL(header length)[4-7 bits]
30
	.TypeOfService		db  ?
27
	.TypeOfService		db  ?  ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0]
31
	.TotalLength		dw  ?
28
	.TotalLength		dw  ?
32
	.Identification 	dw  ?
29
	.Identification 	dw  ?
Line 56... Line 53...
56
	.Data:			       ; Ip header begins here (we will need the IP header to re-construct the complete packet)
53
	.Data:			       ; Ip header begins here (we will need the IP header to re-construct the complete packet)
57
ends
54
ends
Line 58... Line 55...
58
 
55
 
59
align 4
56
align 4
60
uglobal
-
 
-
 
57
uglobal
61
	BROADCAST	dd  ?
58
 
62
	IP_LIST 	rd  MAX_IP
59
	IP_LIST 	rd  MAX_IP
63
	SUBNET_LIST	rd  MAX_IP
60
	SUBNET_LIST	rd  MAX_IP
64
	DNS_LIST	rd  MAX_IP
61
	DNS_LIST	rd  MAX_IP
-
 
62
	GATEWAY_LIST	rd  MAX_IP
65
	GATEWAY_LIST	rd  MAX_IP
63
 
66
	IP_PACKETS_TX	rd  MAX_IP
64
	IP_PACKETS_TX	rd  MAX_IP
-
 
65
	IP_PACKETS_RX	rd  MAX_IP
67
	IP_PACKETS_RX	rd  MAX_IP
66
 
68
	FRAGMENT_LIST	rb  MAX_FRAGMENTS*FRAGMENT_slot.size
67
	FRAGMENT_LIST	rb  MAX_FRAGMENTS*FRAGMENT_slot.size
Line 69... Line 68...
69
endg
68
endg
Line 81... Line 80...
81
;-----------------------------------------------------------------
80
;-----------------------------------------------------------------
82
align 4
81
align 4
83
IPv4_init:
82
IPv4_init:
Line 84... Line 83...
84
 
83
 
85
	or	eax, -1
84
	or	eax, -1
86
	mov	edi, BROADCAST
85
	mov	edi, IP_LIST
87
	mov	ecx, 4*MAX_IP+1
86
	mov	ecx, 4*MAX_IP
Line 88... Line 87...
88
	rep	stosd
87
	rep	stosd
89
 
88
 
90
	xor	eax, eax
89
	inc	eax
91
	mov	edi, FRAGMENT_LIST
90
	mov	edi, FRAGMENT_LIST
Line 92... Line 91...
92
	mov	ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP
91
	mov	ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP
Line 112... Line 111...
112
;  OUT: /
111
;  OUT: /
113
;
112
;
114
;-----------------------------------------------------------------
113
;-----------------------------------------------------------------
115
align 4
114
align 4
116
IPv4_handler:	 ; TODO: implement handler for IP options
115
IPv4_handler:	 ; TODO: implement handler for IP options
117
		 ; TODO2: add code for IPv4 sockets (raw sockets)
116
		 ; TODO2: add code for raw sockets
118
 
-
 
119
	DEBUGF	1,"IP_Handler - start\n"
-
 
Line -... Line 117...
-
 
117
 
-
 
118
	DEBUGF	1,"IPv4_Handler, packet from: %u.%u.%u.%u ",\
-
 
119
	[edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1
-
 
120
	DEBUGF	1,"to: %u.%u.%u.%u\n",\
Line 120... Line 121...
120
 
121
	[edx + IPv4_Packet.DestinationAddress]:1,[edx + IPv4_Packet.DestinationAddress + 1]:1,[edx + IPv4_Packet.DestinationAddress + 2]:1,[edx + IPv4_Packet.DestinationAddress + 3]:1
121
 
122
 
Line 122... Line 123...
122
;-------------------------------------------
123
;-------------------------------------------
Line 131... Line 132...
131
	movzx	eax, [edx + IPv4_Packet.VersionAndIHL]
132
	movzx	eax, [edx + IPv4_Packet.VersionAndIHL]
132
	and	al , 0x0f					; get IHL(header length)
133
	and	al , 0x0f					; get IHL(header length)
133
	cmp	al , 0x05					; IHL!= 5*4(20 bytes)
134
	cmp	al , 0x05					; IHL!= 5*4(20 bytes)
134
	jnz	.has_options
135
	jnz	.has_options
Line 135... Line -...
135
 
-
 
136
 
136
 
137
;-------------------------------
137
;-------------------------------
Line 138... Line -...
138
; Now, re-calcualte the checksum
-
 
139
 
138
; Now, re-calculate the checksum
140
	; Re-calculate checksum
139
 
141
	push	edx ebx
140
	push	edx ebx
142
	mov	esi, edx
141
	mov	esi, edx
Line 143... Line -...
143
	call	IPv4_checksum
-
 
144
	pop	ebx edx
142
	call	IPv4_checksum
145
 
143
	pop	ebx edx
Line 146... Line 144...
146
	; now see if it was correct
144
 
Line 147... Line 145...
147
	cmp	[edx + IPv4_Packet.HeaderChecksum], 0
145
	cmp	[edx + IPv4_Packet.HeaderChecksum], 0
148
	jne	.dump						; if checksum isn't valid then dump packet
146
	jne	.dump						; if checksum isn't valid then dump packet
Line 149... Line 147...
149
 
147
 
-
 
148
	DEBUGF	1,"IPv4 Checksum is correct\n"
Line 150... Line -...
150
	DEBUGF	1,"IPv4 Checksum is correct\n"
-
 
151
 
-
 
152
;-------------------------------------------------------
-
 
153
; Time to find out what interface this packet belongs to
-
 
154
 
-
 
155
; Therefore we will scan the current list of IP's
149
 
156
 
-
 
157
	mov	eax, [edx + IPv4_Packet.DestinationAddress]
-
 
158
	mov	edi, BROADCAST
-
 
159
	mov	ecx, MAX_IP+1
-
 
Line -... Line 150...
-
 
150
;-----------------------------------
160
 
151
; Check if destination IP is correct
-
 
152
 
-
 
153
	call	NET_ptr_to_num
-
 
154
	shl	edi, 2
-
 
155
 
-
 
156
	; check if it matches local ip
161
  .find_ip_loop:
157
 
162
	cmp	eax, dword [edi]
158
	mov	eax, dword[IP_LIST+edi]
-
 
159
	cmp	[edx + IPv4_Packet.DestinationAddress], eax
163
	jz	.ip_ok
160
	je	.ip_ok
Line 164... Line 161...
164
	add	edi, 4
161
 
Line 165... Line 162...
165
	dec	ecx
162
	; check for broadcast
-
 
163
 
Line -... Line 164...
-
 
164
	mov	eax, dword[SUBNET_LIST+edi]
-
 
165
	not	eax
-
 
166
	or	eax, dword[IP_LIST+edi]
-
 
167
	cmp	[edx + IPv4_Packet.DestinationAddress], eax
-
 
168
	je	.ip_ok
166
	jnz	.find_ip_loop
169
 
Line -... Line 170...
-
 
170
	; or a special broadcast
Line 167... Line -...
167
 
-
 
168
	; it was not on the list, perhaps it's a loopback ?
171
 
-
 
172
	cmp	[edx + IPv4_Packet.DestinationAddress], -1
Line 169... Line -...
169
	not	eax
-
 
170
	test	eax, 127 shl 24 ; 127.x.x.x
-
 
171
	jz	.ip_ok
-
 
172
 
173
	je	.ip_ok
173
	;  TODO: we need to check for broadcasts (other then 255.255.255.255)
-
 
Line -... Line 174...
-
 
174
 
-
 
175
;        ; maybe it's a multicast then
Line -... Line 176...
-
 
176
;
-
 
177
;        mov     eax, [edx + IPv4_Packet.DestinationAddress]
Line -... Line 178...
-
 
178
;        and     eax, 0xff000000
-
 
179
;        cmp     eax, 224 shl 24
Line 174... Line 180...
174
 
180
;        je      .ip_ok
175
	DEBUGF	2,"Destination address does not match!\n"
181
 
Line 176... Line 182...
176
 
182
	; or a loopback address
177
	jmp	.dump
183
 
Line 178... Line 184...
178
 
184
	cmp	eax, 127 shl 24
179
 
185
	je	.ip_ok
Line 180... Line -...
180
;---------------------------------------------------
-
 
181
; Now we can update stats and find the device number
-
 
182
 
186
 
183
  .ip_ok:
187
	; or it's not meant for us..
Line 184... Line 188...
184
	call	ETH_struc2dev					; TODO: make this work on other protocols too!
188
 
185
	inc	[IP_PACKETS_RX+4*edi]
189
	DEBUGF	2,"Destination address does not match!\n"
186
	DEBUGF	1,"Packet comes from %u.%u.%u.%u\n",\
190
	jmp	.dump
187
	[edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1
191
 
188
 
192
;------------------------
189
 
193
; Now we can update stats
190
 
194
 
Line 218... Line 222...
218
	mov	edi, [edx + IPv4_Packet.DestinationAddress]	;
222
	mov	edi, [edx + IPv4_Packet.DestinationAddress]	;
219
	mov	al , [edx + IPv4_Packet.Protocol]
223
	mov	al , [edx + IPv4_Packet.Protocol]
220
	pop	edx						; Offset to data (tcp/udp/icmp/.. Packet)
224
	pop	edx						; Offset to data (tcp/udp/icmp/.. Packet)
Line 221... Line 225...
221
 
225
 
222
	cmp	al , IP_PROTO_TCP
226
	cmp	al , IP_PROTO_TCP
Line 223... Line 227...
223
	je	TCP_handler
227
	je	TCP_input
224
 
228
 
Line 225... Line 229...
225
	cmp	al , IP_PROTO_UDP
229
	cmp	al , IP_PROTO_UDP
226
	je	UDP_handler
230
	je	UDP_input
Line 227... Line 231...
227
 
231
 
Line 228... Line 232...
228
	cmp	al , IP_PROTO_ICMP
232
	cmp	al , IP_PROTO_ICMP
229
	je	ICMP_handler
233
	je	ICMP_input
Line 349... Line 353...
349
	mov	edi, esi
353
	mov	edi, esi
350
	mov	esi, [esi + FRAGMENT_entry.NextPtr]
354
	mov	esi, [esi + FRAGMENT_entry.NextPtr]
351
	cmp	esi, -1
355
	cmp	esi, -1
352
	jne	.count_bytes
356
	jne	.count_bytes
Line 353... Line 357...
353
 
357
 
354
	mov	esi, [esp+4]  ;;;
358
	mov	esi, [esp+4]
355
	mov	[edi + FRAGMENT_entry.NextPtr], esi			       ; Add this packet to the chain, this simplifies the following code
359
	mov	[edi + FRAGMENT_entry.NextPtr], esi			       ; Add this packet to the chain, this simplifies the following code
356
	mov	[esi + FRAGMENT_entry.NextPtr], -1
360
	mov	[esi + FRAGMENT_entry.NextPtr], -1
357
	mov	[esi + FRAGMENT_entry.PrevPtr], edi
361
	mov	[esi + FRAGMENT_entry.PrevPtr], edi
Line 461... Line 465...
461
 
465
 
462
;-----------------------------------------------------------------
466
;-----------------------------------------------------------------
463
;
467
;
464
; find fragment slot
468
; find fragment slot
465
;
469
;
466
; IN: pointer to fragmented packet in edx         ; TODO: the RFC says we should check protocol too
470
; IN: pointer to fragmented packet in edx
467
; OUT: pointer to slot in edi, -1 on error
471
; OUT: pointer to slot in edi, -1 on error
468
;
472
;
469
;-----------------------------------------------------------------
473
;-----------------------------------------------------------------
470
align 4
474
align 4
Line -... Line 475...
-
 
475
IPv4_find_fragment_slot:
-
 
476
 
471
IPv4_find_fragment_slot:
477
;;; TODO: the RFC says we should check protocol number too
472
 
478
 
473
	push	eax ebx ecx edx
479
	push	eax ebx ecx edx
474
	mov	ax , word [edx + IPv4_Packet.Identification]
480
	mov	ax , word [edx + IPv4_Packet.Identification]
475
	mov	ecx, MAX_FRAGMENTS
481
	mov	ecx, MAX_FRAGMENTS
Line 512... Line 518...
512
	cmp	[esi + FRAGMENT_slot.ttl], 0
518
	cmp	[esi + FRAGMENT_slot.ttl], 0
513
	je	.try_next
519
	je	.try_next
514
	dec	[esi + FRAGMENT_slot.ttl]
520
	dec	[esi + FRAGMENT_slot.ttl]
515
	jnz	.try_next
521
	jnz	.try_next
516
	DEBUGF 1,"Fragment slot timed-out!\n"
522
	DEBUGF 1,"Fragment slot timed-out!\n"
517
	; TODO: clear all entry's of timed-out slot
523
;;; TODO: clear all entry's of timed-out slot
518
  .try_next:
524
  .try_next:
519
	add	esi, 4
525
	add	esi, 4
520
	loop	.loop
526
	loop	.loop
521
	ret
527
	ret
Line 522... Line 528...
522
 
528
 
-
 
529
 
-
 
530
 
-
 
531
 
-
 
532
 
-
 
533
;------------------------------------------------------------------
-
 
534
;
-
 
535
;
-
 
536
; IN: dword [esp] = pointer to packet to be fragmented
-
 
537
;     dword [esp+4] = buffer size
-
 
538
;     edx = pointer to IPv4 header in that packet
-
 
539
;     ecx = data length
-
 
540
;     ebx = device structure
-
 
541
;
-
 
542
; OUT: /
-
 
543
;
-
 
544
;------------------------------------------------------------------
-
 
545
align 4
-
 
546
IPv4_fragment:
-
 
547
 
-
 
548
;;; TODO: write code here
-
 
549
 
-
 
550
 
-
 
551
	call	kernel_free
-
 
552
	add	esp, 4
-
 
553
 
-
 
554
	ret
523
 
555
 
524
 
556
 
525
 
557
 
526
 
558
 
527
;-----------------------------------------------------------------
559
;------------------------------------------------------------------
528
;
560
;
529
; Create_IPv4_Packet
561
; Create_IPv4_Packet
530
;
562
;
531
; IN: eax = dest ip
563
; IN: eax = dest ip
532
;     ebx = source ip
564
;     ebx = source ip
533
;     ecx = data length
565
;     ecx = data length
534
;     dx  = fragment id
566
;     dx  = fragment id  ;;;;
535
;     di  = protocol
567
;     di  = protocol
536
;
-
 
537
; OUT: eax = pointer to buffer start
568
;
538
;      ebx = pointer to device struct (needed for sending procedure)
569
; OUT: eax = pointer to buffer start
539
;      ecx = unchanged (packet size of embedded data)
570
;      ebx = pointer to device struct (needed for sending procedure)
540
;      edx = size of complete buffer
571
;      ecx = unchanged (packet size of embedded data)
541
;      esi = pointer to sending procedure
572
;      edx = size of complete buffer
Line 542... Line 573...
542
;      edi = pointer to start of data (-1 on error)
573
;      edi = pointer to start of data (0 on error)
Line 543... Line 574...
543
;
574
;
544
;----------------------------------------------------------------- ;;; TODO: create fragmented packets
575
;------------------------------------------------------------------
Line 545... Line 576...
545
align 4
576
align 4
546
IPv4_create_packet:
577
IPv4_create_packet:
547
 
578
 
548
	DEBUGF 1,"Create IPv4 Packet (size=%u)\n", ecx
579
	DEBUGF 1,"Create IPv4 Packet (size=%u)\n", ecx
549
 
580
 
550
	cmp	ecx, 1480
581
	cmp	ecx, 65500	      ; Max IPv4 packet size
Line 580... Line 611...
580
	push	dword -1
611
	push	dword -1
Line 581... Line 612...
581
 
612
 
582
  .send:
613
  .send:
583
	call	IPv4_dest_to_dev
614
	call	IPv4_dest_to_dev
584
	inc	[IP_PACKETS_TX+4*edi]
615
	inc	[IP_PACKETS_TX+4*edi]
585
	mov	edx, [ETH_DRV_LIST + 4*edi]
616
	mov	edx, [NET_DRV_LIST + 4*edi]
586
	lea	eax, [edx + ETH_DEVICE.mac]
617
	lea	eax, [edx + ETH_DEVICE.mac]
587
	mov	ebx, esp
618
	mov	ebx, esp
588
	mov	ecx, [esp+18]	 ;; 18 or  22 ??
619
	mov	ecx, [esp+18]	 ;; 18 or  22 ??
589
	add	ecx, IPv4_Packet.DataOrOptional
620
	add	ecx, IPv4_Packet.DataOrOptional
-
 
621
	mov	di , ETHER_IPv4
590
	mov	di , ETHER_IPv4
622
	;;; TODO: detect if packet is too large for ethernet, if so, call IPv4_fragment
591
	call	ETH_create_packet		   ; TODO: figure out a way to make this work with other protocols too
623
	call	ETH_create_packet		   ;;; TODO: figure out a way to make this work with other protocols too
592
	add	esp, 6
624
	add	esp, 6
593
	cmp	edi, -1
625
	test	edi, edi
Line 594... Line 626...
594
	je	.exit
626
	jz	.exit
595
 
627
 
596
	mov	[edi + IPv4_Packet.VersionAndIHL], 0x45   ; IPv4, normal length (no Optional header)
628
	mov	[edi + IPv4_Packet.VersionAndIHL], 0x45   ; IPv4, normal length (no Optional header)
597
	mov	[edi + IPv4_Packet.TypeOfService], 0
629
	mov	[edi + IPv4_Packet.TypeOfService], 0
Line 620... Line 652...
620
	ret
652
	ret
Line 621... Line 653...
621
 
653
 
622
 
654
 
623
  .not_found:
655
  .not_found:
624
	DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n"
656
	DEBUGF	1,"Create IPv4 Packet - ARP entry not found!\n"
625
	; TODO: QUEUE the packet to resend later!
657
	;;;;;;
626
  .exit:
658
  .exit:
627
	add	esp, 16
659
	add	esp, 16
628
  .exit_:
660
  .exit_:
629
	DEBUGF 1,"Create IPv4 Packet - failed\n"
661
	DEBUGF	1,"Create IPv4 Packet - failed\n"
Line 630... Line 662...
630
	or	edi, -1
662
	and	edi, 0