Rev 4035 | Rev 4053 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4035 | Rev 4052 | ||
---|---|---|---|
Line 33... | Line 33... | ||
33 | SourceAddress dd ? |
33 | SourceAddress dd ? |
34 | DestinationAddress dd ? |
34 | DestinationAddress dd ? |
Line 35... | Line 35... | ||
35 | 35 | ||
Line 36... | Line 36... | ||
36 | ends |
36 | ends |
Line 37... | Line 37... | ||
37 | 37 | ||
38 | struct FRAGMENT_slot |
38 | struct IPv4_FRAGMENT_slot |
39 | 39 | ||
40 | ttl dw ? ; Time to live for this entry, 0 for empty slot's |
40 | ttl dw ? ; Time to live for this entry, 0 for empty slot's |
41 | id dw ? ; Identification field from IP header |
41 | id dw ? ; Identification field from IP header |
Line 42... | Line 42... | ||
42 | SrcIP dd ? ; .. from IP header |
42 | SrcIP dd ? ; .. from IP header |
Line 43... | Line 43... | ||
43 | DstIP dd ? ; .. from IP header |
43 | DstIP dd ? ; .. from IP header |
Line 44... | Line 44... | ||
44 | ptr dd ? ; Pointer to first packet |
44 | ptr dd ? ; Pointer to first packet |
45 | 45 | ||
46 | ends |
46 | ends |
47 | 47 | ||
Line 62... | Line 62... | ||
62 | SUBNET_LIST rd NET_DEVICES_MAX |
62 | SUBNET_LIST rd NET_DEVICES_MAX |
63 | DNS_LIST rd NET_DEVICES_MAX |
63 | DNS_LIST rd NET_DEVICES_MAX |
64 | GATEWAY_LIST rd NET_DEVICES_MAX |
64 | GATEWAY_LIST rd NET_DEVICES_MAX |
65 | BROADCAST_LIST rd NET_DEVICES_MAX |
65 | BROADCAST_LIST rd NET_DEVICES_MAX |
Line 66... | Line 66... | ||
66 | 66 | ||
67 | IP_packets_tx rd NET_DEVICES_MAX |
67 | IPv4_packets_tx rd NET_DEVICES_MAX |
68 | IP_packets_rx rd NET_DEVICES_MAX |
68 | IPv4_packets_rx rd NET_DEVICES_MAX |
Line 69... | Line 69... | ||
69 | IP_packets_dumped rd NET_DEVICES_MAX |
69 | IPv4_packets_dumped rd NET_DEVICES_MAX |
Line 70... | Line 70... | ||
70 | 70 | ||
Line 71... | Line 71... | ||
71 | FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot |
71 | IPv4_FRAGMENT_LIST rb IPv4_MAX_FRAGMENTS * sizeof.IPv4_FRAGMENT_slot |
Line 82... | Line 82... | ||
82 | ;----------------------------------------------------------------- |
82 | ;----------------------------------------------------------------- |
83 | macro IPv4_init { |
83 | macro IPv4_init { |
Line 84... | Line 84... | ||
84 | 84 | ||
85 | xor eax, eax |
85 | xor eax, eax |
86 | mov edi, IP_LIST |
86 | mov edi, IP_LIST |
87 | mov ecx, 7*NET_DEVICES_MAX + (sizeof.FRAGMENT_slot*MAX_FRAGMENTS)/4 |
87 | mov ecx, 7*NET_DEVICES_MAX + (sizeof.IPv4_FRAGMENT_slot*IPv4_MAX_FRAGMENTS)/4 |
Line 88... | Line 88... | ||
88 | rep stosd |
88 | rep stosd |
Line 97... | Line 97... | ||
97 | ;----------------------------------------------------------------- |
97 | ;----------------------------------------------------------------- |
98 | macro IPv4_decrease_fragment_ttls { |
98 | macro IPv4_decrease_fragment_ttls { |
Line 99... | Line 99... | ||
99 | 99 | ||
Line 100... | Line 100... | ||
100 | local .loop, .next |
100 | local .loop, .next |
101 | 101 | ||
102 | mov esi, FRAGMENT_LIST |
102 | mov esi, IPv4_FRAGMENT_LIST |
103 | mov ecx, MAX_FRAGMENTS |
103 | mov ecx, IPv4_MAX_FRAGMENTS |
104 | .loop: |
104 | .loop: |
105 | cmp [esi + FRAGMENT_slot.ttl], 0 |
105 | cmp [esi + IPv4_FRAGMENT_slot.ttl], 0 |
106 | je .next |
106 | je .next |
107 | dec [esi + FRAGMENT_slot.ttl] |
107 | dec [esi + IPv4_FRAGMENT_slot.ttl] |
108 | jz .died |
108 | jz .died |
109 | .next: |
109 | .next: |
110 | add esi, sizeof.FRAGMENT_slot |
110 | add esi, sizeof.IPv4_FRAGMENT_slot |
111 | dec ecx |
111 | dec ecx |
Line 112... | Line 112... | ||
112 | jnz .loop |
112 | jnz .loop |
Line 261... | Line 261... | ||
261 | 261 | ||
262 | ;------------------------ |
262 | ;------------------------ |
Line 263... | Line 263... | ||
263 | ; Now we can update stats |
263 | ; Now we can update stats |
264 | 264 | ||
Line 265... | Line 265... | ||
265 | .ip_ok: |
265 | .ip_ok: |
266 | inc [IP_packets_rx + edi] |
266 | inc [IPv4_packets_rx + edi] |
Line 267... | Line 267... | ||
267 | 267 | ||
Line 302... | Line 302... | ||
302 | 302 | ||
Line 303... | Line 303... | ||
303 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: unknown protocol %u\n", al |
303 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: unknown protocol %u\n", al |
304 | 304 | ||
305 | .dump: |
305 | .dump: |
306 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n" |
306 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n" |
307 | inc [IP_packets_dumped] ; FIXME: use correct interface |
307 | inc [IPv4_packets_dumped] ; FIXME: use correct interface |
308 | call NET_packet_free |
308 | call NET_packet_free |
Line 332... | Line 332... | ||
332 | 332 | ||
333 | call IPv4_find_fragment_slot |
333 | call IPv4_find_fragment_slot |
334 | cmp esi, -1 |
334 | cmp esi, -1 |
Line 335... | Line 335... | ||
335 | je .dump |
335 | je .dump |
336 | 336 | ||
337 | mov [esi + FRAGMENT_slot.ttl], 15 ; Reset the ttl |
337 | mov [esi + IPv4_FRAGMENT_slot.ttl], 15 ; Reset the ttl |
338 | mov esi, [esi + FRAGMENT_slot.ptr] |
338 | mov esi, [esi + IPv4_FRAGMENT_slot.ptr] |
339 | or edi, -1 |
339 | or edi, -1 |
340 | .find_last_entry: ; The following routine will try to find the last entry |
340 | .find_last_entry: ; The following routine will try to find the last entry |
341 | cmp edi, [esi + FRAGMENT_entry.PrevPtr] |
341 | cmp edi, [esi + IPv4_FRAGMENT_entry.PrevPtr] |
342 | jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
342 | jne .destroy_slot ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
343 | mov edi, esi |
343 | mov edi, esi |
344 | mov esi, [esi + FRAGMENT_entry.NextPtr] |
344 | mov esi, [esi + IPv4_FRAGMENT_entry.NextPtr] |
345 | cmp esi, -1 |
345 | cmp esi, -1 |
346 | jne .find_last_entry |
346 | jne .find_last_entry |
Line 347... | Line 347... | ||
347 | ; We found the last entry (pointer is now in edi) |
347 | ; We found the last entry (pointer is now in edi) |
348 | ; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure |
348 | ; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure |
349 | 349 | ||
350 | pop eax ; pointer to packet |
350 | pop eax ; pointer to packet |
351 | mov [edi + FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry |
351 | mov [edi + IPv4_FRAGMENT_entry.NextPtr], eax ; update pointer of previous entry to the new entry |
Line 352... | Line 352... | ||
352 | mov [eax + FRAGMENT_entry.NextPtr], -1 |
352 | mov [eax + IPv4_FRAGMENT_entry.NextPtr], -1 |
353 | mov [eax + FRAGMENT_entry.PrevPtr], edi |
353 | mov [eax + IPv4_FRAGMENT_entry.PrevPtr], edi |
Line 361... | Line 361... | ||
361 | ; We have received the first fragment |
361 | ; We have received the first fragment |
Line 362... | Line 362... | ||
362 | 362 | ||
363 | .is_first_fragment: |
363 | .is_first_fragment: |
364 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: First fragment packet received!\n" |
364 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: First fragment packet received!\n" |
365 | ; try to locate a free slot.. |
365 | ; try to locate a free slot.. |
366 | mov ecx, MAX_FRAGMENTS |
366 | mov ecx, IPv4_MAX_FRAGMENTS |
367 | mov esi, FRAGMENT_LIST |
367 | mov esi, IPv4_FRAGMENT_LIST |
368 | .find_free_slot: |
368 | .find_free_slot: |
369 | cmp word [esi + FRAGMENT_slot.ttl], 0 |
369 | cmp word [esi + IPv4_FRAGMENT_slot.ttl], 0 |
370 | je .found_free_slot |
370 | je .found_free_slot |
371 | add esi, sizeof.FRAGMENT_slot |
371 | add esi, sizeof.IPv4_FRAGMENT_slot |
372 | loop .find_free_slot |
372 | loop .find_free_slot |
Line 373... | Line 373... | ||
373 | jmp .dump ; If no free slot was found, dump the packet |
373 | jmp .dump ; If no free slot was found, dump the packet |
374 | 374 | ||
375 | .found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure |
375 | .found_free_slot: ; We found a free slot, let's fill in the FRAGMENT_slot structure |
376 | mov [esi + FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl |
376 | mov [esi + IPv4_FRAGMENT_slot.ttl], 15 ; RFC recommends 15 secs as ttl |
377 | mov ax, [edx + IPv4_header.Identification] |
377 | mov ax, [edx + IPv4_header.Identification] |
378 | mov [esi + FRAGMENT_slot.id], ax |
378 | mov [esi + IPv4_FRAGMENT_slot.id], ax |
379 | mov eax, [edx + IPv4_header.SourceAddress] |
379 | mov eax, [edx + IPv4_header.SourceAddress] |
380 | mov [esi + FRAGMENT_slot.SrcIP], eax |
380 | mov [esi + IPv4_FRAGMENT_slot.SrcIP], eax |
381 | mov eax, [edx + IPv4_header.DestinationAddress] |
381 | mov eax, [edx + IPv4_header.DestinationAddress] |
382 | mov [esi + FRAGMENT_slot.DstIP], eax |
382 | mov [esi + IPv4_FRAGMENT_slot.DstIP], eax |
383 | pop eax |
383 | pop eax |
384 | mov [esi + FRAGMENT_slot.ptr], eax |
384 | mov [esi + IPv4_FRAGMENT_slot.ptr], eax |
385 | ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure |
385 | ; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure |
386 | mov [eax + FRAGMENT_entry.NextPtr], -1 |
386 | mov [eax + IPv4_FRAGMENT_entry.NextPtr], -1 |
Line 387... | Line 387... | ||
387 | mov [eax + FRAGMENT_entry.PrevPtr], -1 |
387 | mov [eax + IPv4_FRAGMENT_entry.PrevPtr], -1 |
388 | mov [eax + FRAGMENT_entry.Owner], ebx |
388 | mov [eax + IPv4_FRAGMENT_entry.Owner], ebx |
Line 399... | Line 399... | ||
399 | 399 | ||
400 | call IPv4_find_fragment_slot |
400 | call IPv4_find_fragment_slot |
401 | cmp esi, -1 |
401 | cmp esi, -1 |
Line 402... | Line 402... | ||
402 | je .dump |
402 | je .dump |
403 | 403 | ||
404 | mov esi, [esi + FRAGMENT_slot.ptr] ; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer |
404 | mov esi, [esi + IPv4_FRAGMENT_slot.ptr] ; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer |
405 | push esi |
405 | push esi |
Line 406... | Line 406... | ||
406 | xor eax, eax |
406 | xor eax, eax |
407 | or edi, -1 |
407 | or edi, -1 |
408 | 408 | ||
409 | .count_bytes: |
409 | .count_bytes: |
410 | cmp [esi + FRAGMENT_entry.PrevPtr], edi |
410 | cmp [esi + IPv4_FRAGMENT_entry.PrevPtr], edi |
411 | jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
411 | jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) |
412 | mov cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length |
412 | mov cx, [esi + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length |
413 | xchg cl, ch |
413 | xchg cl, ch |
414 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx |
414 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx |
415 | add ax, cx |
415 | add ax, cx |
416 | movzx cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length |
416 | movzx cx, [esi + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length |
417 | and cx, 0x000F |
417 | and cx, 0x000F |
418 | shl cx, 2 |
418 | shl cx, 2 |
419 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Header size=%u\n", cx |
419 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Header size=%u\n", cx |
420 | sub ax, cx |
420 | sub ax, cx |
421 | mov edi, esi |
421 | mov edi, esi |
Line 422... | Line 422... | ||
422 | mov esi, [esi + FRAGMENT_entry.NextPtr] |
422 | mov esi, [esi + IPv4_FRAGMENT_entry.NextPtr] |
423 | cmp esi, -1 |
423 | cmp esi, -1 |
424 | jne .count_bytes |
424 | jne .count_bytes |
425 | 425 | ||
426 | mov esi, [esp+4] |
426 | mov esi, [esp+4] |
Line 427... | Line 427... | ||
427 | mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code |
427 | mov [edi + IPv4_FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code |
428 | mov [esi + FRAGMENT_entry.NextPtr], -1 |
428 | mov [esi + IPv4_FRAGMENT_entry.NextPtr], -1 |
429 | mov [esi + FRAGMENT_entry.PrevPtr], edi |
429 | mov [esi + IPv4_FRAGMENT_entry.PrevPtr], edi |
430 | mov [esi + FRAGMENT_entry.Owner], ebx |
430 | mov [esi + IPv4_FRAGMENT_entry.Owner], ebx |
Line 452... | Line 452... | ||
452 | test eax, eax |
452 | test eax, eax |
453 | je .destroy_slot_pop ; If we dont have enough space to allocate the buffer, discard all packets in slot |
453 | je .destroy_slot_pop ; If we dont have enough space to allocate the buffer, discard all packets in slot |
454 | mov edx, [esp+4] ; Get pointer to first fragment entry back in edx |
454 | mov edx, [esp+4] ; Get pointer to first fragment entry back in edx |
Line 455... | Line 455... | ||
455 | 455 | ||
456 | .rebuild_packet_loop: |
456 | .rebuild_packet_loop: |
457 | movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset |
457 | movzx ecx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset |
458 | xchg cl, ch ; intel byte order |
458 | xchg cl, ch ; intel byte order |
459 | shl cx, 3 ; multiply by 8 and clear first 3 bits |
459 | shl cx, 3 ; multiply by 8 and clear first 3 bits |
Line 460... | Line 460... | ||
460 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Fragment offset=%u\n", cx |
460 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Fragment offset=%u\n", cx |
461 | 461 | ||
462 | lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment |
462 | lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment |
463 | movzx ebx, [edx + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Find header size (in ebx) of fragment |
463 | movzx ebx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Find header size (in ebx) of fragment |
Line 464... | Line 464... | ||
464 | and bx, 0x000F ; |
464 | and bx, 0x000F ; |
465 | shl bx, 2 ; |
465 | shl bx, 2 ; |
466 | 466 | ||
Line 467... | Line 467... | ||
467 | lea esi, [edx + sizeof.FRAGMENT_entry] ; Set esi to the correct begin of fragment |
467 | lea esi, [edx + sizeof.IPv4_FRAGMENT_entry] ; Set esi to the correct begin of fragment |
468 | movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment |
468 | movzx ecx, [edx + sizeof.IPv4_FRAGMENT_entry + IPv4_header.TotalLength] ; Calculate total length of fragment |
469 | xchg cl, ch ; intel byte order |
469 | xchg cl, ch ; intel byte order |
Line 481... | Line 481... | ||
481 | and cx, 3 ; |
481 | and cx, 3 ; |
482 | rep movsb ; |
482 | rep movsb ; |
Line 483... | Line 483... | ||
483 | 483 | ||
484 | push eax |
484 | push eax |
485 | push edx ; Push pointer to fragment onto stack |
485 | push edx ; Push pointer to fragment onto stack |
486 | mov ebx, [edx + FRAGMENT_entry.Owner] ; we need to remeber the owner, in case this is the last packet |
486 | mov ebx, [edx + IPv4_FRAGMENT_entry.Owner] ; we need to remeber the owner, in case this is the last packet |
487 | mov edx, [edx + FRAGMENT_entry.NextPtr] ; Set edx to the next pointer |
487 | mov edx, [edx + IPv4_FRAGMENT_entry.NextPtr] ; Set edx to the next pointer |
488 | call NET_packet_free ; free the previous fragment buffer (this uses the value from stack) |
488 | call NET_packet_free ; free the previous fragment buffer (this uses the value from stack) |
489 | pop eax |
489 | pop eax |
490 | cmp edx, -1 ; Check if it is last fragment in chain |
490 | cmp edx, -1 ; Check if it is last fragment in chain |
Line 525... | Line 525... | ||
525 | 525 | ||
Line 526... | Line 526... | ||
526 | ;;; TODO: the RFC says we should check protocol number too |
526 | ;;; TODO: the RFC says we should check protocol number too |
527 | 527 | ||
528 | push eax ebx ecx edx |
528 | push eax ebx ecx edx |
529 | mov ax, [edx + IPv4_header.Identification] |
529 | mov ax, [edx + IPv4_header.Identification] |
530 | mov ecx, MAX_FRAGMENTS |
530 | mov ecx, IPv4_MAX_FRAGMENTS |
531 | mov esi, FRAGMENT_LIST |
531 | mov esi, IPv4_FRAGMENT_LIST |
532 | mov ebx, [edx + IPv4_header.SourceAddress] |
532 | mov ebx, [edx + IPv4_header.SourceAddress] |
533 | mov edx, [edx + IPv4_header.DestinationAddress] |
533 | mov edx, [edx + IPv4_header.DestinationAddress] |
534 | .find_slot: |
534 | .find_slot: |
535 | cmp [esi + FRAGMENT_slot.id], ax |
535 | cmp [esi + IPv4_FRAGMENT_slot.id], ax |
536 | jne .try_next |
536 | jne .try_next |
537 | cmp [esi + FRAGMENT_slot.SrcIP], ebx |
537 | cmp [esi + IPv4_FRAGMENT_slot.SrcIP], ebx |
538 | jne .try_next |
538 | jne .try_next |
539 | cmp [esi + FRAGMENT_slot.DstIP], edx |
539 | cmp [esi + IPv4_FRAGMENT_slot.DstIP], edx |
540 | je .found_slot |
540 | je .found_slot |
541 | .try_next: |
541 | .try_next: |
Line 542... | Line 542... | ||
542 | add esi, sizeof.FRAGMENT_slot |
542 | add esi, sizeof.IPv4_FRAGMENT_slot |
543 | loop .find_slot |
543 | loop .find_slot |
544 | 544 | ||
Line 550... | Line 550... | ||
550 | 550 | ||
551 | ;------------------------------------------------------------------ |
551 | ;------------------------------------------------------------------ |
552 | ; |
552 | ; |
553 | ; IPv4_output |
553 | ; IPv4_output |
554 | ; |
554 | ; |
555 | ; IN: eax = dest ip |
- | |
556 | ; ebx = output device ptr/0 for automatic choice |
555 | ; IN: eax = Destination IP |
557 | ; ecx = data length |
556 | ; ecx = data length |
558 | ; edx = source ip |
557 | ; edx = Source IP |
559 | ; di = TTL shl 8 + protocol |
558 | ; di = TTL shl 8 + protocol |
560 | ; |
559 | ; |
561 | ; OUT: eax = pointer to buffer start |
560 | ; OUT: eax = pointer to buffer start |
562 | ; ebx = pointer to device struct (needed for sending procedure) |
561 | ; ebx = pointer to device struct (needed for sending procedure) |
Line 571... | Line 570... | ||
571 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_output: size=%u ip=0x%x\n", ecx, eax |
570 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_output: size=%u ip=0x%x\n", ecx, eax |
Line 572... | Line 571... | ||
572 | 571 | ||
573 | cmp ecx, 65500 ; Max IPv4 packet size |
572 | cmp ecx, 65500 ; Max IPv4 packet size |
Line 574... | Line 573... | ||
574 | ja .too_large |
573 | ja .too_large |
575 | - | ||
576 | push ecx eax edx di |
574 | |
- | 575 | push ecx di eax |
|
Line 577... | Line 576... | ||
577 | 576 | call IPv4_route ; outputs device number in edi, dest ip in eax, source IP in edx |
|
578 | call IPv4_route ; outputs device number in edi, dest ip in eax |
577 | push edx |
Line 579... | Line 578... | ||
579 | 578 | ||
580 | test edi, edi |
579 | test edi, edi |
581 | jz .loopback |
580 | jz .loopback |
582 | 581 | ||
583 | call ARP_IP_to_MAC |
582 | call ARP_IP_to_MAC |
Line 584... | Line 583... | ||
584 | test eax, 0xffff0000 ; error bits |
583 | test eax, 0xffff0000 ; error bits |
Line 585... | Line 584... | ||
585 | jnz .arp_error |
584 | jnz .arp_error |
586 | push ebx ; push the mac onto the stack |
585 | push ebx ; push the mac onto the stack |
587 | push ax |
586 | push ax |
588 | 587 | ||
589 | inc [IP_packets_tx + edi] ; update stats |
588 | inc [IPv4_packets_tx + edi] ; update stats |
590 | 589 | ||
591 | mov ebx, [NET_DRV_LIST + edi] |
590 | mov ebx, [NET_DRV_LIST + edi] |
592 | lea eax, [ebx + ETH_DEVICE.mac] |
591 | lea eax, [ebx + ETH_DEVICE.mac] |
593 | mov edx, esp |
592 | mov edx, esp |
Line 603... | Line 602... | ||
603 | mov [edi + IPv4_header.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) |
602 | mov [edi + IPv4_header.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) |
604 | mov [edi + IPv4_header.TypeOfService], 0 ; nothing special, just plain ip packet |
603 | mov [edi + IPv4_header.TypeOfService], 0 ; nothing special, just plain ip packet |
605 | mov [edi + IPv4_header.TotalLength], cx |
604 | mov [edi + IPv4_header.TotalLength], cx |
606 | mov [edi + IPv4_header.Identification], 0 ; fragment id: FIXME |
605 | mov [edi + IPv4_header.Identification], 0 ; fragment id: FIXME |
607 | mov [edi + IPv4_header.FlagsAndFragmentOffset], 0 |
606 | mov [edi + IPv4_header.FlagsAndFragmentOffset], 0 |
608 | pop word [edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol |
- | |
609 | ; [edi + IPv4_header.Protocol] |
- | |
- | 607 | ||
610 | mov [edi + IPv4_header.HeaderChecksum], 0 |
608 | mov [edi + IPv4_header.HeaderChecksum], 0 |
611 | popd [edi + IPv4_header.SourceAddress] |
609 | popd [edi + IPv4_header.SourceAddress] |
612 | popd [edi + IPv4_header.DestinationAddress] |
610 | popd [edi + IPv4_header.DestinationAddress] |
Line -... | Line 611... | ||
- | 611 | ||
- | 612 | pop word[edi + IPv4_header.TimeToLive] ; ttl shl 8 + protocol |
|
- | 613 | ; [edi + IPv4_header.Protocol] |
|
613 | 614 | ||
Line 614... | Line 615... | ||
614 | pop ecx |
615 | pop ecx |
615 | 616 | ||
616 | IPv4_checksum edi |
617 | IPv4_checksum edi |
Line 675... | Line 676... | ||
675 | jnz .arp_error |
676 | jnz .arp_error |
Line 676... | Line 677... | ||
676 | 677 | ||
677 | push ebx ; push the mac |
678 | push ebx ; push the mac |
Line 678... | Line 679... | ||
678 | push ax |
679 | push ax |
679 | 680 | ||
680 | inc [IP_packets_tx + 4*edi] |
681 | inc [IPv4_packets_tx + 4*edi] |
681 | mov ebx, [NET_DRV_LIST + 4*edi] |
682 | mov ebx, [NET_DRV_LIST + 4*edi] |
682 | lea eax, [ebx + ETH_DEVICE.mac] |
683 | lea eax, [ebx + ETH_DEVICE.mac] |
683 | mov edx, esp |
684 | mov edx, esp |
Line 855... | Line 856... | ||
855 | ;--------------------------------------------------------------------------- |
856 | ;--------------------------------------------------------------------------- |
856 | ; |
857 | ; |
857 | ; IPv4_route |
858 | ; IPv4_route |
858 | ; |
859 | ; |
859 | ; IN: eax = Destination IP |
860 | ; IN: eax = Destination IP |
860 | ; OUT: edi = device number*4 |
861 | ; edx = Source IP |
861 | ; eax = ip of gateway if nescessary, unchanged otherwise |
862 | ; OUT: eax = Destination IP (or gateway IP) |
- | 863 | ; edx = Source IP |
|
- | 864 | ; edi = device number*4 |
|
- | 865 | ; DESTROYED: |
|
- | 866 | ; ecx |
|
862 | ; |
867 | ; |
863 | ;--------------------------------------------------------------------------- |
868 | ;--------------------------------------------------------------------------- |
864 | align 4 |
869 | align 4 |
865 | IPv4_route: |
870 | IPv4_route: ; TODO: return error if no valid route found |
Line 866... | Line 871... | ||
866 | 871 | ||
867 | cmp eax, 0xffffffff |
872 | cmp eax, 0xffffffff |
Line 868... | Line 873... | ||
868 | je .broadcast |
873 | je .broadcast |
869 | - | ||
870 | xor edi, edi |
874 | |
871 | mov ecx, NET_DEVICES_MAX |
875 | xor edi, edi |
872 | .loop: |
876 | .loop: |
873 | mov ebx, [IP_LIST+edi] |
877 | mov ebx, [IP_LIST + edi] |
874 | and ebx, [SUBNET_LIST+edi] |
878 | and ebx, [SUBNET_LIST + edi] |
875 | jz .next |
879 | jz .next |
876 | mov edx, eax |
- | |
877 | and edx, [SUBNET_LIST+edi] |
880 | mov ecx, eax |
878 | 881 | and ecx, [SUBNET_LIST + edi] |
|
879 | cmp ebx, edx |
- | |
880 | jne .next |
- | |
881 | - | ||
882 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi |
- | |
883 | ret |
882 | cmp ebx, ecx |
884 | 883 | je .got_it |
|
885 | .next: |
884 | .next: |
886 | add edi, 4 |
885 | add edi, 4 |
Line 887... | Line -... | ||
887 | dec ecx |
- | |
888 | jnz .loop |
886 | cmp edi, 4*NET_DEVICES_MAX |
889 | 887 | jb .loop |
|
890 | .invalid: |
888 | |
- | 889 | mov eax, [GATEWAY_LIST + 4] ; TODO: let user (or a user space daemon) configure default route |
|
- | 890 | .broadcast: |
|
- | 891 | mov edi, 4 ; TODO: same as above |
|
- | 892 | .got_it: |
|
- | 893 | DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi |
|
- | 894 | test edx, edx |
|
- | 895 | jnz @f |
|
891 | mov eax, [GATEWAY_LIST+4] ;;; FIXME |
896 | mov edx, [IP_LIST + edi] |
Line 892... | Line 897... | ||
892 | .broadcast: |
897 | @@: |
Line 989... | Line 994... | ||
989 | .error: |
994 | .error: |
990 | mov eax, -1 |
995 | mov eax, -1 |
991 | ret |
996 | ret |
Line 992... | Line 997... | ||
992 | 997 | ||
993 | .packets_tx: |
998 | .packets_tx: |
994 | mov eax, [IP_packets_tx + eax] |
999 | mov eax, [IPv4_packets_tx + eax] |
Line 995... | Line 1000... | ||
995 | ret |
1000 | ret |
996 | 1001 | ||
997 | .packets_rx: |
1002 | .packets_rx: |
Line 998... | Line 1003... | ||
998 | mov eax, [IP_packets_rx + eax] |
1003 | mov eax, [IPv4_packets_rx + eax] |
999 | ret |
1004 | ret |
1000 | 1005 |