Subversion Repositories Kolibri OS

Rev

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

Rev 2302 Rev 2305
Line 1... Line 1...
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2011. 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...
19
$Revision: 2302 $
19
$Revision: 2305 $
20
 
20
 
21
MAX_FRAGMENTS	equ 64
21
MAX_FRAGMENTS	equ 64
Line 22... Line 22...
22
MAX_IP		equ MAX_NET_DEVICES
22
MAX_IP		equ MAX_NET_DEVICES
-
 
23
IP_MAX_INTERFACES   equ MAX_IP
23
IP_MAX_INTERFACES   equ MAX_IP
24
 
24
 
25
struct	IPv4_header
25
struct	IPv4_Packet
26
 
26
	.VersionAndIHL		db  ?  ; Version[0-3 bits] and IHL(header length)[4-7 bits]
27
	VersionAndIHL	       db  ?  ; Version[0-3 bits] and IHL(header length)[4-7 bits]
27
	.TypeOfService		db  ?  ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0]
28
	TypeOfService	       db  ?  ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0]
28
	.TotalLength		dw  ?
29
	TotalLength	       dw  ?
29
	.Identification 	dw  ?
30
	Identification	       dw  ?
30
	.FlagsAndFragmentOffset dw  ?  ; Flags[0-2] and FragmentOffset[3-15]
31
	FlagsAndFragmentOffset dw  ?  ; Flags[0-2] and FragmentOffset[3-15]
31
	.TimeToLive		db  ?  ;
32
	TimeToLive	       db  ?  ;
32
	.Protocol		db  ?
33
	Protocol	       db  ?
33
	.HeaderChecksum 	dw  ?
-
 
-
 
34
	HeaderChecksum	       dw  ?
34
	.SourceAddress		dd  ?
35
	SourceAddress	       dd  ?
Line 35... Line 36...
35
	.DestinationAddress	dd  ?
36
	DestinationAddress     dd  ?
-
 
37
 
36
	.DataOrOptional:
38
ends
37
ends
39
 
38
 
40
struct	FRAGMENT_slot
39
struct	FRAGMENT_slot
41
 
40
	.ttl			dw  ?  ; Time to live for this entry, 0 for empty slot's
42
	ttl		       dw  ?  ; Time to live for this entry, 0 for empty slot's
41
	.id			dw  ?  ; Identification field from IP header
43
	id		       dw  ?  ; Identification field from IP header
42
	.SrcIP			dd  ?  ; .. from IP header
44
	SrcIP		       dd  ?  ; .. from IP header
Line 43... Line 45...
43
	.DstIP			dd  ?  ; .. from IP header
45
	DstIP		       dd  ?  ; .. from IP header
-
 
46
	ptr		       dd  ?  ; Pointer to first packet
44
	.ptr			dd  ?  ; Pointer to first packet
47
 
45
	.size:
48
ends
46
ends
49
 
47
 
50
struct	FRAGMENT_entry		       ; This structure will replace the ethernet header in fragmented ip packets
48
struct	FRAGMENT_entry		       ; This structure will replace the ethernet header in fragmented ip packets
51
 
49
	.PrevPtr		dd  ?  ; Pointer to previous fragment entry  (-1 for first packet)
52
	PrevPtr 	       dd  ?  ; Pointer to previous fragment entry  (-1 for first packet)
Line 50... Line 53...
50
	.NextPtr		dd  ?  ; Pointer to next fragment entry (-1 for last packet)
53
	NextPtr 	       dd  ?  ; Pointer to next fragment entry (-1 for last packet)
51
	.Owner			dd  ?  ; Pointer to structure of driver
54
	Owner		       dd  ?  ; Pointer to structure of driver
Line 63... Line 66...
63
	GATEWAY_LIST	rd  MAX_IP
66
	GATEWAY_LIST	rd  MAX_IP
Line 64... Line 67...
64
 
67
 
65
	IP_PACKETS_TX	rd  MAX_IP
68
	IP_PACKETS_TX	rd  MAX_IP
Line 66... Line 69...
66
	IP_PACKETS_RX	rd  MAX_IP
69
	IP_PACKETS_RX	rd  MAX_IP
67
 
70
 
Line 68... Line 71...
68
	FRAGMENT_LIST	rb  MAX_FRAGMENTS*FRAGMENT_slot.size
71
	FRAGMENT_LIST	rb  MAX_FRAGMENTS * sizeof.FRAGMENT_slot
69
endg
72
endg
Line 82... Line 85...
82
	mov	edi, IP_LIST
85
	mov	edi, IP_LIST
83
	mov	ecx, 4*MAX_IP
86
	mov	ecx, 4*MAX_IP
84
	rep	stosd
87
	rep	stosd
Line 85... Line 88...
85
 
88
 
86
	mov	edi, FRAGMENT_LIST
89
	mov	edi, FRAGMENT_LIST
87
	mov	ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP
90
	mov	ecx, sizeof.FRAGMENT_slot*MAX_FRAGMENTS/4 + 2*MAX_IP
Line 88... Line 91...
88
	rep	stosd
91
	rep	stosd
Line 198... Line 201...
198
align 4
201
align 4
199
IPv4_input:	 ; TODO: implement handler for IP options
202
IPv4_input:	 ; TODO: implement handler for IP options
200
		 ; TODO2: add code for raw sockets
203
		 ; TODO2: add code for raw sockets
Line 201... Line 204...
201
 
204
 
202
	DEBUGF	1,"IPv4_Handler, packet from: %u.%u.%u.%u ",\
205
	DEBUGF	1,"IPv4_Handler, packet from: %u.%u.%u.%u ",\
203
	[edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1
206
	[edx + IPv4_header.SourceAddress]:1,[edx + IPv4_header.SourceAddress + 1]:1,[edx + IPv4_header.SourceAddress + 2]:1,[edx + IPv4_header.SourceAddress + 3]:1
204
	DEBUGF	1,"to: %u.%u.%u.%u\n",\
207
	DEBUGF	1,"to: %u.%u.%u.%u\n",\
Line 205... Line 208...
205
	[edx + IPv4_Packet.DestinationAddress]:1,[edx + IPv4_Packet.DestinationAddress + 1]:1,[edx + IPv4_Packet.DestinationAddress + 2]:1,[edx + IPv4_Packet.DestinationAddress + 3]:1
208
	[edx + IPv4_header.DestinationAddress]:1,[edx + IPv4_header.DestinationAddress + 1]:1,[edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1
206
 
209
 
Line 207... Line 210...
207
;-------------------------------------------
210
;-------------------------------------------
208
; Check if the packet still has time to live
211
; Check if the packet still has time to live
Line 209... Line 212...
209
 
212
 
210
	cmp	byte [edx + IPv4_Packet.TimeToLive], 0
213
	cmp	byte [edx + IPv4_header.TimeToLive], 0
Line 211... Line 214...
211
	je	.dump
214
	je	.dump
212
 
215
 
213
;--------------------------------------
216
;--------------------------------------
214
; First, check if IP packet has options
217
; First, check if IP packet has options
Line 215... Line 218...
215
 
218
 
Line 233... Line 236...
233
	shl	edi, 2
236
	shl	edi, 2
Line 234... Line 237...
234
 
237
 
Line 235... Line 238...
235
	; check if it matches local ip
238
	; check if it matches local ip
236
 
239
 
237
	mov	eax, [IP_LIST+edi]
240
	mov	eax, [IP_LIST+edi]
Line 238... Line 241...
238
	cmp	[edx + IPv4_Packet.DestinationAddress], eax
241
	cmp	[edx + IPv4_header.DestinationAddress], eax
Line 239... Line 242...
239
	je	.ip_ok
242
	je	.ip_ok
240
 
243
 
241
	; check for broadcast
244
	; check for broadcast
242
 
245
 
243
	mov	eax, [SUBNET_LIST+edi]
246
	mov	eax, [SUBNET_LIST+edi]
Line 244... Line 247...
244
	not	eax
247
	not	eax
Line 245... Line 248...
245
	or	eax, [IP_LIST+edi]
248
	or	eax, [IP_LIST+edi]
246
	cmp	[edx + IPv4_Packet.DestinationAddress], eax
249
	cmp	[edx + IPv4_header.DestinationAddress], eax
Line 247... Line 250...
247
	je	.ip_ok
250
	je	.ip_ok
Line 248... Line 251...
248
 
251
 
249
	; or a special broadcast
252
	; or a special broadcast
250
 
253
 
251
	cmp	[edx + IPv4_Packet.DestinationAddress], -1
254
	cmp	[edx + IPv4_header.DestinationAddress], -1
Line 252... Line 255...
252
	je	.ip_ok
255
	je	.ip_ok
Line 275... Line 278...
275
	inc	[IP_PACKETS_RX+edi]
278
	inc	[IP_PACKETS_RX+edi]
Line 276... Line 279...
276
 
279
 
277
;----------------------------------
280
;----------------------------------
Line 278... Line 281...
278
; Check if the packet is fragmented
281
; Check if the packet is fragmented
279
 
282
 
Line 280... Line 283...
280
	test	[edx + IPv4_Packet.FlagsAndFragmentOffset], 1 shl 5	; Is 'more fragments' flag set ?
283
	test	[edx + IPv4_header.FlagsAndFragmentOffset], 1 shl 5	; Is 'more fragments' flag set ?
281
	jnz	.has_fragments						; If so, we definately have a fragmented packet
284
	jnz	.has_fragments						; If so, we definately have a fragmented packet
Line 282... Line 285...
282
 
285
 
283
	test	[edx + IPv4_Packet.FlagsAndFragmentOffset], 0xff1f	; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets
286
	test	[edx + IPv4_header.FlagsAndFragmentOffset], 0xff1f	; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets
Line 284... Line 287...
284
	jnz	.is_last_fragment
287
	jnz	.is_last_fragment
285
 
288
 
286
;-------------------------------------------------------------------
289
;-------------------------------------------------------------------
287
; No, it's just a regular IP packet, pass it to the higher protocols
290
; No, it's just a regular IP packet, pass it to the higher protocols
288
 
291
 
289
  .handle_it:							; We reach here if packet hasnt been fragmented, or when it already has been re-constructed
292
  .handle_it:							; We reach here if packet hasnt been fragmented, or when it already has been re-constructed
290
	movzx	eax, [edx + IPv4_Packet.VersionAndIHL]		; Calculate Header length by using IHL field
293
	movzx	eax, [edx + IPv4_header.VersionAndIHL]		; Calculate Header length by using IHL field
Line 291... Line 294...
291
	and	eax, 0x0000000f 				;
294
	and	eax, 0x0000000f 				;
292
	shl	eax, 2						;
295
	shl	eax, 2						;
Line 293... Line 296...
293
	movzx	ecx, [edx + IPv4_Packet.TotalLength]		; Calculate length of encapsulated Packet
296
	movzx	ecx, [edx + IPv4_header.TotalLength]		; Calculate length of encapsulated Packet
294
	xchg	cl , ch 					;
297
	xchg	cl , ch 					;
295
	sub	ecx, eax					;
298
	sub	ecx, eax					;
296
 
299
 
Line 297... Line 300...
297
	add	eax, edx
300
	add	eax, edx
298
	push	eax
301
	push	eax
Line 324... Line 327...
324
;---------------------------
327
;---------------------------
325
; Fragmented packet handler
328
; Fragmented packet handler
Line 326... Line 329...
326
 
329
 
327
 
330
 
328
  .has_fragments:
331
  .has_fragments:
329
	movzx	eax, [edx + IPv4_Packet.FlagsAndFragmentOffset]
332
	movzx	eax, [edx + IPv4_header.FlagsAndFragmentOffset]
Line 330... Line 333...
330
	xchg	al , ah
333
	xchg	al , ah
Line 331... Line 334...
331
	shl	ax , 3
334
	shl	ax , 3
332
 
335
 
Line 377... Line 380...
377
	mov	ecx, MAX_FRAGMENTS
380
	mov	ecx, MAX_FRAGMENTS
378
	mov	esi, FRAGMENT_LIST
381
	mov	esi, FRAGMENT_LIST
379
  .find_free_slot:
382
  .find_free_slot:
380
	cmp	word [esi + FRAGMENT_slot.ttl], 0
383
	cmp	word [esi + FRAGMENT_slot.ttl], 0
381
	je	.found_free_slot
384
	je	.found_free_slot
382
	add	esi, FRAGMENT_slot.size
385
	add	esi, sizeof.FRAGMENT_slot
383
	loop	.find_free_slot
386
	loop	.find_free_slot
384
	jmp	.dump						; If no free slot was found, dump the packet
387
	jmp	.dump						; If no free slot was found, dump the packet
Line 385... Line 388...
385
 
388
 
386
  .found_free_slot:						; We found a free slot, let's fill in the FRAGMENT_slot structure
389
  .found_free_slot:						; We found a free slot, let's fill in the FRAGMENT_slot structure
387
	mov	[esi + FRAGMENT_slot.ttl], 15			; RFC recommends 15 secs as ttl
390
	mov	[esi + FRAGMENT_slot.ttl], 15			; RFC recommends 15 secs as ttl
388
	mov	ax , [edx + IPv4_Packet.Identification]
391
	mov	ax , [edx + IPv4_header.Identification]
389
	mov	[esi + FRAGMENT_slot.id], ax
392
	mov	[esi + FRAGMENT_slot.id], ax
390
	mov	eax,[edx + IPv4_Packet.SourceAddress]
393
	mov	eax,[edx + IPv4_header.SourceAddress]
391
	mov	[esi + FRAGMENT_slot.SrcIP], eax
394
	mov	[esi + FRAGMENT_slot.SrcIP], eax
392
	mov	eax, [edx + IPv4_Packet.DestinationAddress]
395
	mov	eax, [edx + IPv4_header.DestinationAddress]
393
	mov	[esi + FRAGMENT_slot.DstIP], eax
396
	mov	[esi + FRAGMENT_slot.DstIP], eax
394
	pop	eax
397
	pop	eax
395
	mov	[esi + FRAGMENT_slot.ptr], eax
398
	mov	[esi + FRAGMENT_slot.ptr], eax
396
								; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure
399
								; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure
Line 418... Line 421...
418
	or	edi, -1
421
	or	edi, -1
Line 419... Line 422...
419
 
422
 
420
  .count_bytes:
423
  .count_bytes:
421
	cmp	[esi + FRAGMENT_entry.PrevPtr], edi
424
	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!)
425
	jne	.destroy_slot_pop						; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
423
	mov	cx, [esi + FRAGMENT_entry.Data + IPv4_Packet.TotalLength]	; Add total length
426
	mov	cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.TotalLength]	  ; Add total length
424
	xchg	cl, ch
427
	xchg	cl, ch
425
	DEBUGF	1,"Packet size: %u\n", cx
428
	DEBUGF	1,"Packet size: %u\n", cx
426
	add	ax, cx
429
	add	ax, cx
427
	movzx	cx, [esi + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL]	; Sub Header length
430
	movzx	cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL]	  ; Sub Header length
428
	and	cx, 0x000F
431
	and	cx, 0x000F
429
	shl	cx, 2
432
	shl	cx, 2
430
	DEBUGF	1,"Header size: %u\n", cx
433
	DEBUGF	1,"Header size: %u\n", cx
431
	sub	ax, cx
434
	sub	ax, cx
Line 438... Line 441...
438
	mov	[edi + FRAGMENT_entry.NextPtr], esi			       ; Add this packet to the chain, this simplifies the following code
441
	mov	[edi + FRAGMENT_entry.NextPtr], esi			       ; Add this packet to the chain, this simplifies the following code
439
	mov	[esi + FRAGMENT_entry.NextPtr], -1
442
	mov	[esi + FRAGMENT_entry.NextPtr], -1
440
	mov	[esi + FRAGMENT_entry.PrevPtr], edi
443
	mov	[esi + FRAGMENT_entry.PrevPtr], edi
441
	mov	[esi + FRAGMENT_entry.Owner], ebx
444
	mov	[esi + FRAGMENT_entry.Owner], ebx
Line 442... Line 445...
442
 
445
 
443
	mov	cx, [edx + IPv4_Packet.TotalLength]			       ; Note: This time we dont substract Header length
446
	mov	cx, [edx + IPv4_header.TotalLength]			       ; Note: This time we dont substract Header length
444
	xchg	cl , ch
447
	xchg	cl , ch
445
	DEBUGF	1,"Packet size: %u\n", cx
448
	DEBUGF	1,"Packet size: %u\n", cx
446
	add	ax , cx
449
	add	ax , cx
Line 447... Line 450...
447
	DEBUGF	1,"Total Received data size: %u\n", eax
450
	DEBUGF	1,"Total Received data size: %u\n", eax
448
 
451
 
449
	push	eax
452
	push	eax
450
	mov	ax , [edx + IPv4_Packet.FlagsAndFragmentOffset]
453
	mov	ax , [edx + IPv4_header.FlagsAndFragmentOffset]
451
	xchg	al , ah
454
	xchg	al , ah
452
	shl	ax , 3
455
	shl	ax , 3
453
	add	cx , ax
456
	add	cx , ax
Line 463... Line 466...
463
	test	eax, eax
466
	test	eax, eax
464
	je	.destroy_slot_pop							; If we dont have enough space to allocate the buffer, discard all packets in slot
467
	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
468
	mov	edx, [esp+4]								; Get pointer to first fragment entry back in edx
Line 466... Line 469...
466
 
469
 
467
  .rebuild_packet_loop:
470
  .rebuild_packet_loop:
468
	movzx	ecx, [edx + FRAGMENT_entry.Data + IPv4_Packet.FlagsAndFragmentOffset]	; Calculate the fragment offset
471
	movzx	ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset]   ; Calculate the fragment offset
469
	xchg	cl , ch 								;  intel byte order
472
	xchg	cl , ch 								;  intel byte order
470
	shl	cx , 3									;   multiply by 8 and clear first 3 bits
473
	shl	cx , 3									;   multiply by 8 and clear first 3 bits
Line 471... Line 474...
471
	DEBUGF	1,"Fragment offset: %u\n", cx
474
	DEBUGF	1,"Fragment offset: %u\n", cx
472
 
475
 
473
	lea	edi, [eax + ecx]							; Notice that edi will be equal to eax for first fragment
476
	lea	edi, [eax + ecx]							; Notice that edi will be equal to eax for first fragment
474
	movzx	ebx, [edx + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL]		; Find header size (in ebx) of fragment
477
	movzx	ebx, [edx + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL]		  ; Find header size (in ebx) of fragment
Line 475... Line 478...
475
	and	bx , 0x000F								;
478
	and	bx , 0x000F								;
476
	shl	bx , 2									;
479
	shl	bx , 2									;
477
 
480
 
Line 478... Line 481...
478
	lea	esi, [edx + FRAGMENT_entry.Data]					; Set esi to the correct begin of fragment
481
	lea	esi, [edx + sizeof.FRAGMENT_entry]					  ; Set esi to the correct begin of fragment
479
	movzx	ecx, [edx + FRAGMENT_entry.Data + IPv4_Packet.TotalLength]		; Calculate total length of fragment
482
	movzx	ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.TotalLength]		  ; Calculate total length of fragment
480
	xchg	cl, ch									;  intel byte order
483
	xchg	cl, ch									;  intel byte order
Line 502... Line 505...
502
	jne	.rebuild_packet_loop
505
	jne	.rebuild_packet_loop
Line 503... Line 506...
503
 
506
 
504
	pop	ecx
507
	pop	ecx
505
	xchg	cl, ch
508
	xchg	cl, ch
506
	mov	edx, eax
509
	mov	edx, eax
507
	mov	[edx + IPv4_Packet.TotalLength], cx
510
	mov	[edx + IPv4_header.TotalLength], cx
Line 508... Line 511...
508
	add	esp, 8
511
	add	esp, 8
Line 509... Line 512...
509
 
512
 
Line 548... Line 551...
548
IPv4_find_fragment_slot:
551
IPv4_find_fragment_slot:
Line 549... Line 552...
549
 
552
 
Line 550... Line 553...
550
;;; TODO: the RFC says we should check protocol number too
553
;;; TODO: the RFC says we should check protocol number too
551
 
554
 
552
	push	eax ebx ecx edx
555
	push	eax ebx ecx edx
553
	mov	ax , [edx + IPv4_Packet.Identification]
556
	mov	ax , [edx + IPv4_header.Identification]
554
	mov	ecx, MAX_FRAGMENTS
557
	mov	ecx, MAX_FRAGMENTS
555
	mov	esi, FRAGMENT_LIST
558
	mov	esi, FRAGMENT_LIST
556
	mov	ebx, [edx + IPv4_Packet.SourceAddress]
559
	mov	ebx, [edx + IPv4_header.SourceAddress]
557
	mov	edx, [edx + IPv4_Packet.DestinationAddress]
560
	mov	edx, [edx + IPv4_header.DestinationAddress]
558
  .find_slot:
561
  .find_slot:
559
	cmp	[esi + FRAGMENT_slot.id], ax
562
	cmp	[esi + FRAGMENT_slot.id], ax
560
	jne	.try_next
563
	jne	.try_next
561
	cmp	[esi + FRAGMENT_slot.SrcIP], ebx
564
	cmp	[esi + FRAGMENT_slot.SrcIP], ebx
562
	jne	.try_next
565
	jne	.try_next
563
	cmp	[esi + FRAGMENT_slot.DstIP], edx
566
	cmp	[esi + FRAGMENT_slot.DstIP], edx
564
	je	.found_slot
567
	je	.found_slot
565
  .try_next:
568
  .try_next:
566
	add	esi, FRAGMENT_slot.size
569
	add	esi, sizeof.FRAGMENT_slot
567
	loop	.find_slot
570
	loop	.find_slot
568
;        pop     edx ebx
571
;        pop     edx ebx
Line 615... Line 618...
615
	inc	[IP_PACKETS_TX+edi]
618
	inc	[IP_PACKETS_TX+edi]
616
	mov	ebx, [NET_DRV_LIST+edi]
619
	mov	ebx, [NET_DRV_LIST+edi]
617
	lea	eax, [ebx + ETH_DEVICE.mac]
620
	lea	eax, [ebx + ETH_DEVICE.mac]
618
	mov	edx, esp
621
	mov	edx, esp
619
	mov	ecx, [esp + 18]
622
	mov	ecx, [esp + 18]
620
	add	ecx, IPv4_Packet.DataOrOptional
623
	add	ecx, sizeof.IPv4_header
621
	mov	di , ETHER_IPv4
624
	mov	di , ETHER_IPv4
622
	call	ETH_output
625
	call	ETH_output
623
	jz	.error
626
	jz	.error
Line 624... Line 627...
624
 
627
 
Line 625... Line 628...
625
	add	esp, 6	; pop the mac
628
	add	esp, 6	; pop the mac
626
 
629
 
627
	mov	[edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header)
630
	mov	[edi + IPv4_header.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header)
628
	mov	[edi + IPv4_Packet.TypeOfService], 0	; nothing special, just plain ip packet
631
	mov	[edi + IPv4_header.TypeOfService], 0	; nothing special, just plain ip packet
629
	mov	[edi + IPv4_Packet.TotalLength], cx
632
	mov	[edi + IPv4_header.TotalLength], cx
630
	rol	[edi + IPv4_Packet.TotalLength], 8	; internet byte order
633
	rol	[edi + IPv4_header.TotalLength], 8	; internet byte order
631
	mov	[edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000
634
	mov	[edi + IPv4_header.FlagsAndFragmentOffset], 0x0000
632
	mov	[edi + IPv4_Packet.HeaderChecksum], 0
635
	mov	[edi + IPv4_header.HeaderChecksum], 0
633
	pop	word [edi + IPv4_Packet.TimeToLive]	; ttl shl 8 + protocol
636
	pop	word [edi + IPv4_header.TimeToLive]	; ttl shl 8 + protocol
634
;               [edi + IPv4_Packet.Protocol]
637
;               [edi + IPv4_header.Protocol]
635
	popw	[edi + IPv4_Packet.Identification]	; fragment id
638
	popw	[edi + IPv4_header.Identification]	; fragment id
Line 636... Line 639...
636
	popd	[edi + IPv4_Packet.SourceAddress]
639
	popd	[edi + IPv4_header.SourceAddress]
Line 637... Line 640...
637
	popd	[edi + IPv4_Packet.DestinationAddress]
640
	popd	[edi + IPv4_header.DestinationAddress]
638
 
641
 
639
	pop	ecx
642
	pop	ecx
640
 
643
 
Line 641... Line 644...
641
	IPv4_checksum edi
644
	IPv4_checksum edi
642
	add	edi, IPv4_Packet.DataOrOptional
645
	add	edi, sizeof.IPv4_header
Line 692... Line 695...
692
	inc	[IP_PACKETS_TX+edi]
695
	inc	[IP_PACKETS_TX+edi]
693
	mov	ebx, [NET_DRV_LIST+edi]
696
	mov	ebx, [NET_DRV_LIST+edi]
694
	lea	eax, [ebx + ETH_DEVICE.mac]
697
	lea	eax, [ebx + ETH_DEVICE.mac]
695
	mov	edx, esp
698
	mov	edx, esp
696
	mov	ecx, [esp + 6+4]
699
	mov	ecx, [esp + 6+4]
697
	add	ecx, IPv4_Packet.DataOrOptional
700
	add	ecx, sizeof.IPv4_header
698
	mov	di, ETHER_IPv4
701
	mov	di, ETHER_IPv4
699
	call	ETH_output
702
	call	ETH_output
700
	jz	.error
703
	jz	.error
Line 701... Line 704...
701
 
704
 
Line 709... Line 712...
709
 
712
 
710
	push	edi ecx
713
	push	edi ecx
711
	rep	movsb
714
	rep	movsb
Line 712... Line 715...
712
	pop	ecx edi
715
	pop	ecx edi
713
 
716
 
714
;        [edi + IPv4_Packet.VersionAndIHL]              ; IPv4, normal length (no Optional header)
717
;        [edi + IPv4_header.VersionAndIHL]              ; IPv4, normal length (no Optional header)
715
;        [edi + IPv4_Packet.TypeOfService]              ; nothing special, just plain ip packet
718
;        [edi + IPv4_header.TypeOfService]              ; nothing special, just plain ip packet
716
;        [edi + IPv4_Packet.TotalLength]
719
;        [edi + IPv4_header.TotalLength]
717
;        [edi + IPv4_Packet.TotalLength]                ; internet byte order
720
;        [edi + IPv4_header.TotalLength]                ; internet byte order
718
;        [edi + IPv4_Packet.FlagsAndFragmentOffset]
721
;        [edi + IPv4_header.FlagsAndFragmentOffset]
719
 
722
 
720
	mov	[edi + IPv4_Packet.HeaderChecksum], 0
723
	mov	[edi + IPv4_header.HeaderChecksum], 0
721
 
724
 
722
;        [edi + IPv4_Packet.TimeToLive]                 ; ttl shl 8 + protocol
725
;        [edi + IPv4_header.TimeToLive]                 ; ttl shl 8 + protocol
723
;        [edi + IPv4_Packet.Protocol]
726
;        [edi + IPv4_header.Protocol]
724
;        [edi + IPv4_Packet.Identification]             ; fragment id
727
;        [edi + IPv4_header.Identification]             ; fragment id
Line 725... Line 728...
725
;        [edi + IPv4_Packet.SourceAddress]
728
;        [edi + IPv4_header.SourceAddress]
726
;        [edi + IPv4_Packet.DestinationAddress]
729
;        [edi + IPv4_header.DestinationAddress]
727
 
730
 
728
	IPv4_checksum edi			;;;; todo: checksum for IP packet with options!
731
	IPv4_checksum edi			;;;; todo: checksum for IP packet with options!
729
	add	edi, IPv4_Packet.DataOrOptional
732
	add	edi, sizeof.IPv4_header
Line 730... Line 733...
730
	DEBUGF	1,"IPv4 Packet for device %x created successfully\n", ebx
733
	DEBUGF	1,"IPv4 Packet for device %x created successfully\n", ebx
Line 758... Line 761...
758
 
761
 
Line 759... Line 762...
759
	DEBUGF 1,"IPv4_fragment\n"
762
	DEBUGF 1,"IPv4_fragment\n"
Line 760... Line 763...
760
 
763
 
761
	and	ecx, not 111b	; align 4
764
	and	ecx, not 111b	; align 4
Line 762... Line 765...
762
 
765
 
763
	cmp	ecx, IPv4_Packet.DataOrOptional + 8	; must be able to put at least 8 bytes
766
	cmp	ecx, sizeof.IPv4_header + 8	; must be able to put at least 8 bytes
764
	jb	.err2
767
	jb	.err2
765
 
768
 
766
	push	esi ecx
769
	push	esi ecx
767
	mov	eax, [esi + IPv4_Packet.DestinationAddress]
770
	mov	eax, [esi + IPv4_header.DestinationAddress]
Line 777... Line 780...
777
	lea	eax, [ebx + ETH_DEVICE.mac]
780
	lea	eax, [ebx + ETH_DEVICE.mac]
778
	push	eax
781
	push	eax
Line 779... Line 782...
779
 
782
 
780
 
783
 
781
	push	esi				; ptr to ip header
784
	push	esi				; ptr to ip header
782
	sub	ecx, IPv4_Packet.DataOrOptional ; substract header size
785
	sub	ecx, sizeof.IPv4_header 	; substract header size
Line 783... Line 786...
783
	push	ecx				; max data size
786
	push	ecx				; max data size
784
	push	dword 0 			; offset
787
	push	dword 0 			; offset
Line 800... Line 803...
800
	mov	ecx, 5	; 5 dwords: TODO: use IHL field of the header!
803
	mov	ecx, 5	; 5 dwords: TODO: use IHL field of the header!
801
	rep	movsd
804
	rep	movsd
Line 802... Line 805...
802
 
805
 
803
; copy data
806
; copy data
804
	mov	esi, [esp + 2*4]
807
	mov	esi, [esp + 2*4]
805
	add	esi, IPv4_Packet.DataOrOptional
808
	add	esi, sizeof.IPv4_header
Line 806... Line 809...
806
	add	esi, [esp]	; offset
809
	add	esi, [esp]	; offset
807
 
810
 
808
	mov	ecx, [esp + 1*4]
811
	mov	ecx, [esp + 1*4]
Line 809... Line 812...
809
	DEBUGF 1,"IPv4_fragment - copying data (%u bytes)\n", ecx
812
	DEBUGF 1,"IPv4_fragment - copying data (%u bytes)\n", ecx
810
	rep	movsb
813
	rep	movsb
811
 
814
 
812
; now, correct header
815
; now, correct header
813
	mov	ecx, [esp + 1*4]
816
	mov	ecx, [esp + 1*4]
Line 814... Line 817...
814
	add	ecx, IPv4_Packet.DataOrOptional
817
	add	ecx, sizeof.IPv4_header
815
	xchg	cl, ch
818
	xchg	cl, ch
Line 816... Line 819...
816
	mov	[edi + IPv4_Packet.TotalLength], cx
819
	mov	[edi + IPv4_header.TotalLength], cx
817
 
820
 
818
	mov	ecx, [esp]		; offset
821
	mov	ecx, [esp]		; offset
819
	xchg	cl, ch
822
	xchg	cl, ch
820
 
823
 
Line 821... Line 824...
821
;        cmp     dword[esp + 4*4], 0     ; last fragment?;<<<<<<
824
;        cmp     dword[esp + 4*4], 0     ; last fragment?;<<<<<<
Line 822... Line 825...
822
;        je      .last_fragment
825
;        je      .last_fragment
823
	or	cx, 1 shl 2		; more fragments
826
	or	cx, 1 shl 2		; more fragments
Line 824... Line 827...
824
;  .last_fragment:
827
;  .last_fragment: