Subversion Repositories Kolibri OS

Rev

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

Rev 2301 Rev 2302
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...
19
$Revision: 2301 $
19
$Revision: 2302 $
20
 
20
 
21
MAX_FRAGMENTS	equ 64
21
MAX_FRAGMENTS	equ 64
Line 232... Line 232...
232
	call	NET_ptr_to_num
232
	call	NET_ptr_to_num
233
	shl	edi, 2
233
	shl	edi, 2
Line 234... Line 234...
234
 
234
 
Line 235... Line 235...
235
	; check if it matches local ip
235
	; check if it matches local ip
236
 
236
 
237
	mov	eax, dword[IP_LIST+edi]
237
	mov	eax, [IP_LIST+edi]
Line 238... Line 238...
238
	cmp	[edx + IPv4_Packet.DestinationAddress], eax
238
	cmp	[edx + IPv4_Packet.DestinationAddress], eax
Line 285... Line 285...
285
 
285
 
286
;-------------------------------------------------------------------
286
;-------------------------------------------------------------------
Line 287... Line 287...
287
; No, it's just a regular IP packet, pass it to the higher protocols
287
; No, it's just a regular IP packet, pass it to the higher protocols
288
 
288
 
289
  .handle_it:							; We reach here if packet hasnt been fragmented, or when it already has been re-constructed
289
  .handle_it:							; We reach here if packet hasnt been fragmented, or when it already has been re-constructed
290
	movzx	eax, byte [edx + IPv4_Packet.VersionAndIHL]	; Calculate Header length by using IHL field
290
	movzx	eax, [edx + IPv4_Packet.VersionAndIHL]		; Calculate Header length by using IHL field
291
	and	eax, 0x0000000f 				;
291
	and	eax, 0x0000000f 				;
292
	shl	eax, 2						;
292
	shl	eax, 2						;
293
	movzx	ecx, word [edx + IPv4_Packet.TotalLength]	; Calculate length of encapsulated Packet
293
	movzx	ecx, [edx + IPv4_Packet.TotalLength]		; Calculate length of encapsulated Packet
Line 294... Line 294...
294
	xchg	cl , ch 					;
294
	xchg	cl , ch 					;
295
	sub	ecx, eax					;
295
	sub	ecx, eax					;
Line 343... Line 343...
343
 
343
 
344
	call	IPv4_find_fragment_slot
344
	call	IPv4_find_fragment_slot
345
	cmp	esi, -1
345
	cmp	esi, -1
Line 346... Line 346...
346
	je	.dump
346
	je	.dump
347
 
347
 
348
	mov	word [esi + FRAGMENT_slot.ttl], 15		; Reset the ttl
348
	mov	[esi + FRAGMENT_slot.ttl], 15			; Reset the ttl
349
	mov	esi, [esi + FRAGMENT_slot.ptr]
349
	mov	esi, [esi + FRAGMENT_slot.ptr]
350
	or	edi, -1
350
	or	edi, -1
351
  .find_last_entry:						; The following routine will try to find the last entry
351
  .find_last_entry:						; The following routine will try to find the last entry
Line 382... Line 382...
382
	add	esi, FRAGMENT_slot.size
382
	add	esi, FRAGMENT_slot.size
383
	loop	.find_free_slot
383
	loop	.find_free_slot
384
	jmp	.dump						; If no free slot was found, dump the packet
384
	jmp	.dump						; If no free slot was found, dump the packet
Line 385... Line 385...
385
 
385
 
386
  .found_free_slot:						; We found a free slot, let's fill in the FRAGMENT_slot structure
386
  .found_free_slot:						; We found a free slot, let's fill in the FRAGMENT_slot structure
387
	mov	word [esi + FRAGMENT_slot.ttl], 15		; RFC recommends 15 secs as ttl
387
	mov	[esi + FRAGMENT_slot.ttl], 15			; RFC recommends 15 secs as ttl
388
	mov	ax , word [edx + IPv4_Packet.Identification]
388
	mov	ax , [edx + IPv4_Packet.Identification]
389
	mov	word [esi + FRAGMENT_slot.id], ax
389
	mov	[esi + FRAGMENT_slot.id], ax
390
	mov	eax, dword [edx + IPv4_Packet.SourceAddress]
390
	mov	eax,[edx + IPv4_Packet.SourceAddress]
391
	mov	dword [esi + FRAGMENT_slot.SrcIP], eax
391
	mov	[esi + FRAGMENT_slot.SrcIP], eax
392
	mov	eax, dword [edx + IPv4_Packet.DestinationAddress]
392
	mov	eax, [edx + IPv4_Packet.DestinationAddress]
393
	mov	dword [esi + FRAGMENT_slot.DstIP], eax
393
	mov	[esi + FRAGMENT_slot.DstIP], eax
394
	pop	eax
394
	pop	eax
395
	mov	dword [esi + FRAGMENT_slot.ptr], eax
395
	mov	[esi + FRAGMENT_slot.ptr], eax
396
								; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure
396
								; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure
397
	mov	[eax + FRAGMENT_entry.NextPtr], -1
397
	mov	[eax + FRAGMENT_entry.NextPtr], -1
398
	mov	[eax + FRAGMENT_entry.PrevPtr], -1
398
	mov	[eax + FRAGMENT_entry.PrevPtr], -1
Line 418... Line 418...
418
	or	edi, -1
418
	or	edi, -1
Line 419... Line 419...
419
 
419
 
420
  .count_bytes:
420
  .count_bytes:
421
	cmp	[esi + FRAGMENT_entry.PrevPtr], edi
421
	cmp	[esi + FRAGMENT_entry.PrevPtr], edi
422
	jne	.destroy_slot_pop						  ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
422
	jne	.destroy_slot_pop						; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
423
	mov	cx, word [esi + FRAGMENT_entry.Data + IPv4_Packet.TotalLength]	  ; Add total length
423
	mov	cx, [esi + FRAGMENT_entry.Data + IPv4_Packet.TotalLength]	; Add total length
424
	xchg	cl, ch
424
	xchg	cl, ch
425
	DEBUGF	1,"Packet size: %u\n", cx
425
	DEBUGF	1,"Packet size: %u\n", cx
426
	add	ax, cx
426
	add	ax, cx
427
	movzx	cx, byte [esi + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL]  ; Sub Header length
427
	movzx	cx, [esi + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL]	; Sub Header length
428
	and	cx, 0x000F
428
	and	cx, 0x000F
429
	shl	cx, 2
429
	shl	cx, 2
430
	DEBUGF	1,"Header size: %u\n", cx
430
	DEBUGF	1,"Header size: %u\n", cx
431
	sub	ax, cx
431
	sub	ax, cx
Line 463... Line 463...
463
	test	eax, eax
463
	test	eax, eax
464
	je	.destroy_slot_pop							; If we dont have enough space to allocate the buffer, discard all packets in slot
464
	je	.destroy_slot_pop							; If we dont have enough space to allocate the buffer, discard all packets in slot
465
	mov	edx, [esp+4]								; Get pointer to first fragment entry back in edx
465
	mov	edx, [esp+4]								; Get pointer to first fragment entry back in edx
Line 466... Line 466...
466
 
466
 
467
  .rebuild_packet_loop:
467
  .rebuild_packet_loop:
468
	movzx	ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.FlagsAndFragmentOffset]	; Calculate the fragment offset
468
	movzx	ecx, [edx + FRAGMENT_entry.Data + IPv4_Packet.FlagsAndFragmentOffset]	; Calculate the fragment offset
469
	xchg	cl , ch 									;  intel byte order
469
	xchg	cl , ch 								;  intel byte order
470
	shl	cx , 3										;   multiply by 8 and clear first 3 bits
470
	shl	cx , 3									;   multiply by 8 and clear first 3 bits
Line 471... Line 471...
471
	DEBUGF	1,"Fragment offset: %u\n", cx
471
	DEBUGF	1,"Fragment offset: %u\n", cx
472
 
472
 
473
	lea	edi, [eax + ecx]								; Notice that edi will be equal to eax for first fragment
473
	lea	edi, [eax + ecx]							; Notice that edi will be equal to eax for first fragment
474
	movzx	ebx, byte [edx + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL]		; Find header size (in ebx) of fragment
474
	movzx	ebx, [edx + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL]		; Find header size (in ebx) of fragment
Line 475... Line 475...
475
	and	bx , 0x000F									;
475
	and	bx , 0x000F								;
476
	shl	bx , 2										;
476
	shl	bx , 2									;
477
 
477
 
Line 478... Line 478...
478
	lea	esi, [edx + FRAGMENT_entry.Data]						; Set esi to the correct begin of fragment
478
	lea	esi, [edx + FRAGMENT_entry.Data]					; Set esi to the correct begin of fragment
479
	movzx	ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] 		; Calculate total length of fragment
479
	movzx	ecx, [edx + FRAGMENT_entry.Data + IPv4_Packet.TotalLength]		; Calculate total length of fragment
480
	xchg	cl, ch										;  intel byte order
480
	xchg	cl, ch									;  intel byte order
Line 499... Line 499...
499
	call	kernel_free									; free the previous fragment buffer (this uses the value from stack)
499
	call	kernel_free								; free the previous fragment buffer (this uses the value from stack)
500
	pop	eax
500
	pop	eax
501
	cmp	edx, -1 									; Check if it is last fragment in chain
501
	cmp	edx, -1 								; Check if it is last fragment in chain
502
	jne	.rebuild_packet_loop
502
	jne	.rebuild_packet_loop
Line 503... Line 503...
503
 
503
 
504
	pop	ecx										;
504
	pop	ecx
505
	xchg	cl, ch
505
	xchg	cl, ch
506
	mov	edx, eax
506
	mov	edx, eax
507
	mov	word [edx + IPv4_Packet.TotalLength], cx
507
	mov	[edx + IPv4_Packet.TotalLength], cx
Line 508... Line 508...
508
	add	esp, 8
508
	add	esp, 8
Line 509... Line 509...
509
 
509
 
Line 548... Line 548...
548
IPv4_find_fragment_slot:
548
IPv4_find_fragment_slot:
Line 549... Line 549...
549
 
549
 
Line 550... Line 550...
550
;;; TODO: the RFC says we should check protocol number too
550
;;; TODO: the RFC says we should check protocol number too
551
 
551
 
552
	push	eax ebx ecx edx
552
	push	eax ebx ecx edx
553
	mov	ax , word [edx + IPv4_Packet.Identification]
553
	mov	ax , [edx + IPv4_Packet.Identification]
554
	mov	ecx, MAX_FRAGMENTS
554
	mov	ecx, MAX_FRAGMENTS
555
	mov	esi, FRAGMENT_LIST
555
	mov	esi, FRAGMENT_LIST
556
	mov	ebx, dword [edx + IPv4_Packet.SourceAddress]
556
	mov	ebx, [edx + IPv4_Packet.SourceAddress]
557
	mov	edx, dword [edx + IPv4_Packet.DestinationAddress]
557
	mov	edx, [edx + IPv4_Packet.DestinationAddress]
558
  .find_slot:
558
  .find_slot:
559
	cmp	word [esi + FRAGMENT_slot.id], ax
559
	cmp	[esi + FRAGMENT_slot.id], ax
560
	jne	.try_next
560
	jne	.try_next
561
	cmp	dword [esi + FRAGMENT_slot.SrcIP], ebx
561
	cmp	[esi + FRAGMENT_slot.SrcIP], ebx
562
	jne	.try_next
562
	jne	.try_next
563
	cmp	dword [esi + FRAGMENT_slot.DstIP], edx
563
	cmp	[esi + FRAGMENT_slot.DstIP], edx
564
	je	.found_slot
564
	je	.found_slot
565
  .try_next:
565
  .try_next:
566
	add	esi, FRAGMENT_slot.size
566
	add	esi, FRAGMENT_slot.size
Line 628... Line 628...
628
	mov	[edi + IPv4_Packet.TypeOfService], 0	; nothing special, just plain ip packet
628
	mov	[edi + IPv4_Packet.TypeOfService], 0	; nothing special, just plain ip packet
629
	mov	[edi + IPv4_Packet.TotalLength], cx
629
	mov	[edi + IPv4_Packet.TotalLength], cx
630
	rol	[edi + IPv4_Packet.TotalLength], 8	; internet byte order
630
	rol	[edi + IPv4_Packet.TotalLength], 8	; internet byte order
631
	mov	[edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000
631
	mov	[edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000
632
	mov	[edi + IPv4_Packet.HeaderChecksum], 0
632
	mov	[edi + IPv4_Packet.HeaderChecksum], 0
633
	popw	word [edi + IPv4_Packet.TimeToLive]	; ttl shl 8 + protocol
633
	pop	word [edi + IPv4_Packet.TimeToLive]	; ttl shl 8 + protocol
634
;               [edi + IPv4_Packet.Protocol]
634
;               [edi + IPv4_Packet.Protocol]
635
	popw	[edi + IPv4_Packet.Identification]	; fragment id
635
	popw	[edi + IPv4_Packet.Identification]	; fragment id
636
	popd	[edi + IPv4_Packet.SourceAddress]
636
	popd	[edi + IPv4_Packet.SourceAddress]
637
	popd	[edi + IPv4_Packet.DestinationAddress]
637
	popd	[edi + IPv4_Packet.DestinationAddress]