ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

VOID ARPReceive ( PVOID  Context,
PIP_PACKET  Packet 
)

Definition at line 175 of file arp.c.

Referenced by LanReceiveWorker().

{
    PARP_HEADER Header;
    IP_ADDRESS SrcAddress;
    IP_ADDRESS DstAddress;
    PCHAR SenderHWAddress, SenderProtoAddress, TargetProtoAddress;
    PNEIGHBOR_CACHE_ENTRY NCE;
    PNDIS_PACKET NdisPacket;
    PIP_INTERFACE Interface = (PIP_INTERFACE)Context;
    ULONG BytesCopied, DataSize;
    PCHAR DataBuffer;
    
    PAGED_CODE();

    TI_DbgPrint(DEBUG_ARP, ("Called.\n"));

    Packet->Header = ExAllocatePoolWithTag(PagedPool,
                                           sizeof(ARP_HEADER),
                                           PACKET_BUFFER_TAG);
    if (!Packet->Header)
    {
        TI_DbgPrint(DEBUG_ARP, ("Unable to allocate header buffer\n"));
        Packet->Free(Packet);
        return;
    }
    Packet->MappedHeader = FALSE;

    BytesCopied = CopyPacketToBuffer((PCHAR)Packet->Header,
                                     Packet->NdisPacket,
                                     Packet->Position,
                                     sizeof(ARP_HEADER));
    if (BytesCopied != sizeof(ARP_HEADER))
    {
        TI_DbgPrint(DEBUG_ARP, ("Unable to copy in header buffer\n"));
        Packet->Free(Packet);
        return;
    }

    Header = (PARP_HEADER)Packet->Header;

    /* FIXME: Ethernet only */
    if (WN2H(Header->HWType) != 1) {
        TI_DbgPrint(DEBUG_ARP, ("Unknown ARP hardware type (0x%X).\n", WN2H(Header->HWType)));
        Packet->Free(Packet);
        return;
    }

    /* Check protocol type */
    if (Header->ProtoType != ETYPE_IPv4) {
        TI_DbgPrint(DEBUG_ARP, ("Unknown ARP protocol type (0x%X).\n", WN2H(Header->ProtoType)));
        Packet->Free(Packet);
        return;
    }

    DataSize = (2 * Header->HWAddrLen) + (2 * Header->ProtoAddrLen);
    DataBuffer = ExAllocatePool(PagedPool,
                                DataSize);
    if (!DataBuffer)
    {
        TI_DbgPrint(DEBUG_ARP, ("Unable to allocate data buffer\n"));
        Packet->Free(Packet);
        return;
    }

    BytesCopied = CopyPacketToBuffer(DataBuffer,
                                     Packet->NdisPacket,
                                     Packet->Position + sizeof(ARP_HEADER),
                                     DataSize);
    if (BytesCopied != DataSize)
    {
        TI_DbgPrint(DEBUG_ARP, ("Unable to copy in data buffer\n"));
        ExFreePool(DataBuffer);
        Packet->Free(Packet);
        return;
    }

    SenderHWAddress    = (PVOID)(DataBuffer);
    SenderProtoAddress = (PVOID)(SenderHWAddress + Header->HWAddrLen);
    TargetProtoAddress = (PVOID)(SenderProtoAddress + Header->ProtoAddrLen + Header->HWAddrLen);

    AddrInitIPv4(&DstAddress, *((PULONG)TargetProtoAddress));
    if (!AddrIsEqual(&DstAddress, &Interface->Unicast))
    {
        ExFreePool(DataBuffer);
        Packet->Free(Packet);
        return;
    }

    AddrInitIPv4(&SrcAddress, *((PULONG)SenderProtoAddress));

    /* Check if we know the sender */
    NCE = NBLocateNeighbor(&SrcAddress);
    if (NCE) {
        /* We know the sender. Update the hardware address
           and state in our neighbor address cache */
        NBUpdateNeighbor(NCE, SenderHWAddress, 0);
    } else {
        /* The packet had our protocol address as target. The sender
           may want to communicate with us soon, so add his address
           to our address cache */
        NBAddNeighbor(Interface, &SrcAddress, SenderHWAddress,
                      Header->HWAddrLen, 0, ARP_COMPLETE_TIMEOUT);
    }

    if (Header->Opcode != ARP_OPCODE_REQUEST)
    {
        ExFreePool(DataBuffer);
        Packet->Free(Packet);
        return;
    }

    /* This is a request for our address. Swap the addresses and
       send an ARP reply back to the sender */
    NdisPacket = PrepareARPPacket(
        Interface,
        Header->HWType,                  /* Hardware type */
        Header->ProtoType,               /* Protocol type */
        (UCHAR)Interface->AddressLength, /* Hardware address length */
        (UCHAR)Header->ProtoAddrLen,     /* Protocol address length */
        Interface->Address,              /* Sender's (local) hardware address */
        &Interface->Unicast.Address.IPv4Address,/* Sender's (local) protocol address */
        SenderHWAddress,                 /* Target's (remote) hardware address */
        SenderProtoAddress,              /* Target's (remote) protocol address */
        ARP_OPCODE_REPLY);               /* ARP reply */
    if (NdisPacket) {
        PC(NdisPacket)->DLComplete = ARPTransmitComplete;
        (*Interface->Transmit)(Interface->Context,
                               NdisPacket,
                               0,
                               SenderHWAddress,
                               LAN_PROTO_ARP);
    }

    ExFreePool(DataBuffer);
    Packet->Free(Packet);
}

Generated on Sat May 26 2012 04:41:13 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.