Example #1
0
/*
 * @implemented
 */
NTSTATUS
NTAPI
RtlIpv4AddressToStringExA(IN struct in_addr *Address,
                          IN USHORT Port,
                          OUT PCHAR AddressString,
                          IN OUT PULONG AddressStringLength)
{
    CHAR Buffer[IPV4_ADDR_STRING_MAX_LEN+IPV4_PORT_STRING_MAX_LEN];
    ULONG Length;

    if (!Address || !AddressString || !AddressStringLength)
        return STATUS_INVALID_PARAMETER;

    Length = sprintf(Buffer, "%u.%u.%u.%u", Address->S_un.S_un_b.s_b1,
                                            Address->S_un.S_un_b.s_b2,
                                            Address->S_un.S_un_b.s_b3,
                                            Address->S_un.S_un_b.s_b4);

    if (Port) Length += sprintf(Buffer + Length, ":%u", WN2H(Port));

    if (*AddressStringLength > Length)
    {
        *AddressStringLength = Length + 1;
        strcpy(AddressString, Buffer);
        return STATUS_SUCCESS;
    }

    *AddressStringLength = Length + 1;
    return STATUS_INVALID_PARAMETER;
}
Example #2
0
/*
 * @implemented
 */
INT
WSAAPI
WSANtohs(IN SOCKET s,
         IN USHORT netshort,
         OUT USHORT FAR* lphostshort)
{
    INT ErrorCode;
    PWSSOCKET Socket;
    DPRINT("WSANtohs: %p, %lx, %p\n", s, netshort, lphostshort);
    
    /* Check for WSAStartup */
    if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS)
    {
        /* Make sure we got a parameter */
        if (!lphostshort)
        {
            /* Fail */
            SetLastError(WSAEFAULT);
            return SOCKET_ERROR;
        }

        /* Get the Socket Context */
        if ((Socket = WsSockGetSocket(s)))
        {
            /* Check which byte order to use */
            if (Socket->CatalogEntry->ProtocolInfo.iNetworkByteOrder ==
                LITTLEENDIAN)
            {
                /* No conversion needed */
                *lphostshort = netshort;
            }
            else
            {
                /* Use a swap */
                *lphostshort = WN2H(netshort);
            }

            /* Dereference the socket */
            WsSockDereference(Socket);

            /* Return success */
            return ERROR_SUCCESS;
        }
        else
        {
            /* Set the error code */
            ErrorCode = WSAENOTSOCK;
        }
    }

    /* Return with error */
    SetLastError(ErrorCode);
    return SOCKET_ERROR;
}
Example #3
0
/*
 * FUNCTION: Open an address file object
 * ARGUMENTS:
 *     Request  = Pointer to TDI request structure for this request
 *     Address  = Pointer to address to be opened
 *     Protocol = Protocol on which to open the address
 *     Shared   = Specifies if the address is opened for shared access
 *     Options  = Pointer to option buffer
 * RETURNS:
 *     Status of operation
 */
NTSTATUS FileOpenAddress(
  PTDI_REQUEST Request,
  PTA_IP_ADDRESS Address,
  USHORT Protocol,
  BOOLEAN Shared,
  PVOID Options)
{
  PADDRESS_FILE AddrFile;

  TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol));

  /* If it's shared and has a port specified, look for a match */
  if ((Shared != FALSE) && (Address->Address[0].Address[0].sin_port != 0))
  {
    AddrFile = AddrFindShared(NULL, Address->Address[0].Address[0].sin_port, Protocol);
    if (AddrFile != NULL)
    {
        Request->Handle.AddressHandle = AddrFile;
        return STATUS_SUCCESS;
    }
  }

  AddrFile = ExAllocatePoolWithTag(NonPagedPool, sizeof(ADDRESS_FILE),
                                   ADDR_FILE_TAG);
  if (!AddrFile) {
    TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  RtlZeroMemory(AddrFile, sizeof(ADDRESS_FILE));

  AddrFile->RefCount = 1;
  AddrFile->Free = AddrFileFree;
  AddrFile->Sharers = 1;

  /* Set our default options */
  AddrFile->TTL = 128;
  AddrFile->DF = 0;
  AddrFile->BCast = 1;
  AddrFile->HeaderIncl = 1;

  /* Make sure address is a local unicast address or 0 */
  /* FIXME: IPv4 only */
  AddrFile->Family = Address->Address[0].AddressType;
  AddrFile->Address.Address.IPv4Address = Address->Address[0].Address[0].in_addr;
  AddrFile->Address.Type = IP_ADDRESS_V4;

  if (!AddrIsUnspecified(&AddrFile->Address) &&
      !AddrLocateInterface(&AddrFile->Address)) {
	  TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", A2S(&AddrFile->Address)));
	  ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG);
	  return STATUS_INVALID_ADDRESS;
  }

  TI_DbgPrint(MID_TRACE, ("Opening address %s for communication (P=%d U=%d).\n",
    A2S(&AddrFile->Address), Protocol, IPPROTO_UDP));

  /* Protocol specific handling */
  switch (Protocol) {
  case IPPROTO_TCP:
      if (Address->Address[0].Address[0].sin_port)
      {
          /* The client specified an explicit port so we force a bind to this */
          AddrFile->Port = TCPAllocatePort(Address->Address[0].Address[0].sin_port);
          
          /* Check for bind success */
          if (AddrFile->Port == 0xffff)
          {
              ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG);
              return STATUS_ADDRESS_ALREADY_EXISTS;
          }
          
          /* Sanity check */
          ASSERT(Address->Address[0].Address[0].sin_port == AddrFile->Port);
      }
      else if (!AddrIsUnspecified(&AddrFile->Address))
      {
          /* The client is trying to bind to a local address so allocate a port now too */
          AddrFile->Port = TCPAllocatePort(0);
          
          /* Check for bind success */
          if (AddrFile->Port == 0xffff)
          {
              ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG);
              return STATUS_ADDRESS_ALREADY_EXISTS;
          }
      }
      else
      {
          /* The client wants an unspecified port with an unspecified address so we wait to see what the TCP library gives us */
          AddrFile->Port = 0;
      }

      AddEntity(CO_TL_ENTITY, AddrFile, CO_TL_TCP);

      AddrFile->Send = NULL; /* TCPSendData */
      break;

  case IPPROTO_UDP:
      TI_DbgPrint(MID_TRACE,("Allocating udp port\n"));
      AddrFile->Port =
	  UDPAllocatePort(Address->Address[0].Address[0].sin_port);

      if ((Address->Address[0].Address[0].sin_port &&
           AddrFile->Port != Address->Address[0].Address[0].sin_port) ||
           AddrFile->Port == 0xffff)
      {
          ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG);
          return STATUS_ADDRESS_ALREADY_EXISTS;
      }

      TI_DbgPrint(MID_TRACE,("Setting port %d (wanted %d)\n",
                             AddrFile->Port,
                             Address->Address[0].Address[0].sin_port));

      AddEntity(CL_TL_ENTITY, AddrFile, CL_TL_UDP);

      AddrFile->Send = UDPSendDatagram;
      break;

  case IPPROTO_ICMP:
    AddrFile->Port = 0;
    AddrFile->Send = ICMPSendDatagram;

    /* FIXME: Verify this */
    AddEntity(ER_ENTITY, AddrFile, ER_ICMP);
    break;

  default:
    /* Use raw IP for all other protocols */
    AddrFile->Port = 0;
    AddrFile->Send = RawIPSendDatagram;

    /* FIXME: Verify this */
    AddEntity(CL_TL_ENTITY, AddrFile, 0);
    break;
  }

  TI_DbgPrint(MID_TRACE, ("IP protocol number for address file object is %d.\n",
    Protocol));

  TI_DbgPrint(MID_TRACE, ("Port number for address file object is %d.\n",
    WN2H(AddrFile->Port)));

  /* Set protocol */
  AddrFile->Protocol = Protocol;

  /* Initialize receive and transmit queues */
  InitializeListHead(&AddrFile->ReceiveQueue);
  InitializeListHead(&AddrFile->TransmitQueue);

  /* Initialize spin lock that protects the address file object */
  KeInitializeSpinLock(&AddrFile->Lock);

  /* Return address file object */
  Request->Handle.AddressHandle = AddrFile;

  /* Add address file to global list */
  ExInterlockedInsertTailList(
    &AddressFileListHead,
    &AddrFile->ListEntry,
    &AddressFileListLock);

  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));

  return STATUS_SUCCESS;
}
Example #4
0
/*
 * FUNCTION: Searches through address file entries to find next match
 * ARGUMENTS:
 *     SearchContext = Pointer to search context
 * RETURNS:
 *     Pointer to referenced address file, NULL if none was found
 */
PADDRESS_FILE AddrSearchNext(
    PAF_SEARCH SearchContext)
{
    PLIST_ENTRY CurrentEntry;
    PIP_ADDRESS IPAddress;
    KIRQL OldIrql;
    PADDRESS_FILE Current = NULL;
    BOOLEAN Found = FALSE;
    PADDRESS_FILE StartingAddrFile;
    
    TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);

    if (SearchContext->Next == &AddressFileListHead)
    {
        TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
        return NULL;
    }

    /* Save this pointer so we can dereference it later */
    StartingAddrFile = CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry);

    CurrentEntry = SearchContext->Next;

    while (CurrentEntry != &AddressFileListHead) {
        Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_FILE, ListEntry);

        IPAddress = &Current->Address;

        TI_DbgPrint(DEBUG_ADDRFILE, ("Comparing: ((%d, %d, %s), (%d, %d, %s)).\n",
            WN2H(Current->Port),
            Current->Protocol,
            A2S(IPAddress),
            WN2H(SearchContext->Port),
            SearchContext->Protocol,
            A2S(SearchContext->Address)));

        /* See if this address matches the search criteria */
        if ((Current->Port    == SearchContext->Port) &&
            (Current->Protocol == SearchContext->Protocol) &&
            (AddrReceiveMatch(IPAddress, SearchContext->Address))) {
            /* We've found a match */
            Found = TRUE;
            break;
        }
        CurrentEntry = CurrentEntry->Flink;
    }

    if (Found)
    {
        SearchContext->Next = CurrentEntry->Flink;

        if (SearchContext->Next != &AddressFileListHead)
        {
            /* Reference the next address file to prevent the link from disappearing behind our back */
            ReferenceObject(CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry));
        }

        /* Reference the returned address file before dereferencing the starting
         * address file because it may be that Current == StartingAddrFile */
        ReferenceObject(Current);
    }
    else
        Current = NULL;

    DereferenceObject(StartingAddrFile);

    TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);

    return Current;
}
Example #5
0
VOID
LogActiveObjects(VOID)
{
#ifdef LOG_OBJECTS
    PLIST_ENTRY CurrentEntry;
    KIRQL OldIrql;
    PADDRESS_FILE AddrFile;
    PCONNECTION_ENDPOINT Conn;

    DbgPrint("----------- TCP/IP Active Object Dump -------------\n");
    
    TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);

    CurrentEntry = AddressFileListHead.Flink;
    while (CurrentEntry != &AddressFileListHead)
    {
        AddrFile = CONTAINING_RECORD(CurrentEntry, ADDRESS_FILE, ListEntry);

        DbgPrint("Address File (%s, %d, %d) @ 0x%p | Ref count: %d | Sharers: %d\n",
                 A2S(&AddrFile->Address), WN2H(AddrFile->Port), AddrFile->Protocol,
                 AddrFile, AddrFile->RefCount, AddrFile->Sharers);
        DbgPrint("\tListener: ");
        if (AddrFile->Listener == NULL)
            DbgPrint("<None>\n");
        else
            DbgPrint("0x%p\n", AddrFile->Listener);
        DbgPrint("\tAssociated endpoints: ");
        if (AddrFile->Connection == NULL)
            DbgPrint("<None>\n");
        else
        {
            Conn = AddrFile->Connection;
            while (Conn)
            {
                DbgPrint("0x%p ", Conn);
                Conn = Conn->Next;
            }
            DbgPrint("\n");
        }
        
        CurrentEntry = CurrentEntry->Flink;
    }
    
    TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
    
    TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
    
    CurrentEntry = ConnectionEndpointListHead.Flink;
    while (CurrentEntry != &ConnectionEndpointListHead)
    {
        Conn = CONTAINING_RECORD(CurrentEntry, CONNECTION_ENDPOINT, ListEntry);
        
        DbgPrint("Connection @ 0x%p | Ref count: %d\n", Conn, Conn->RefCount);
        DbgPrint("\tPCB: ");
        if (Conn->SocketContext == NULL)
            DbgPrint("<None>\n");
        else
        {
            DbgPrint("0x%p\n", Conn->SocketContext);
            LibTCPDumpPcb(Conn->SocketContext);
        }
        DbgPrint("\tPacket queue status: %s\n", IsListEmpty(&Conn->PacketQueue) ? "Empty" : "Not Empty");
        DbgPrint("\tRequest lists: Connect: %s | Recv: %s | Send: %s | Shutdown: %s | Listen: %s\n",
                 IsListEmpty(&Conn->ConnectRequest) ? "Empty" : "Not Empty",
                 IsListEmpty(&Conn->ReceiveRequest) ? "Empty" : "Not Empty",
                 IsListEmpty(&Conn->SendRequest) ? "Empty" : "Not Empty",
                 IsListEmpty(&Conn->ShutdownRequest) ? "Empty" : "Not Empty",
                 IsListEmpty(&Conn->ListenRequest) ? "Empty" : "Not Empty");
        DbgPrint("\tSend shutdown: %s\n", Conn->SendShutdown ? "Yes" : "No");
        DbgPrint("\tReceive shutdown: %s\n", Conn->ReceiveShutdown ? "Yes" : "No");
        if (Conn->ReceiveShutdown) DbgPrint("\tReceive shutdown status: 0x%x\n", Conn->ReceiveShutdownStatus);
        DbgPrint("\tClosing: %s\n", Conn->Closing ? "Yes" : "No");
        
        CurrentEntry = CurrentEntry->Flink;
    }
    
    TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);

    DbgPrint("---------------------------------------------------\n");
#endif
}
Example #6
0
/*
 * @implemented
 */
USHORT
WSAAPI
ntohs(IN USHORT netshort)
{
    return WN2H(netshort);
}
unsigned short L2PNet_ntohs( unsigned short netshort )
{
    return WN2H(netshort);
}
Example #8
0
File: arp.c Project: GYGit/reactos
VOID ARPReceive(
    PVOID Context,
    PIP_PACKET Packet)
/*
 * FUNCTION: Receives an ARP packet
 * ARGUMENTS:
 *     Context = Pointer to context information (IP_INTERFACE)
 *     Packet  = Pointer to packet
 */
{
    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, Interface);
    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);
}
Example #9
0
File: arp.c Project: GYGit/reactos
BOOLEAN ARPTransmit(PIP_ADDRESS Address, PVOID LinkAddress,
                    PIP_INTERFACE Interface)
/*
 * FUNCTION: Creates an ARP request and transmits it on a network
 * ARGUMENTS:
 *     Address = Pointer to IP address to resolve
 * RETURNS:
 *     TRUE if the request was successfully sent, FALSE if not
 */
{
    PNDIS_PACKET NdisPacket;
    UCHAR ProtoAddrLen;
    USHORT ProtoType;

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

    /* If Address is NULL then the caller wants an
     * gratuitous ARP packet sent */
    if (!Address)
        Address = &Interface->Unicast;

    switch (Address->Type) {
        case IP_ADDRESS_V4:
            ProtoType    = (USHORT)ETYPE_IPv4; /* IPv4 */
            ProtoAddrLen = 4;                  /* Length of IPv4 address */
            break;
        case IP_ADDRESS_V6:
            ProtoType    = (USHORT)ETYPE_IPv6; /* IPv6 */
            ProtoAddrLen = 16;                 /* Length of IPv6 address */
            break;
        default:
	    TI_DbgPrint(DEBUG_ARP,("Bad Address Type %x\n", Address->Type));
	    DbgBreakPoint();
            /* Should not happen */
            return FALSE;
    }

    NdisPacket = PrepareARPPacket(
        Interface,
        WN2H(0x0001),                    /* FIXME: Ethernet only */
        ProtoType,                       /* Protocol type */
        (UCHAR)Interface->AddressLength, /* Hardware address length */
        (UCHAR)ProtoAddrLen,             /* Protocol address length */
        Interface->Address,              /* Sender's (local) hardware address */
        &Interface->Unicast.Address.IPv4Address,/* Sender's (local) protocol address */
        LinkAddress,                     /* Target's (remote) hardware address */
        &Address->Address.IPv4Address,   /* Target's (remote) protocol address */
        ARP_OPCODE_REQUEST);             /* ARP request */

    if( !NdisPacket ) return FALSE;

    ASSERT_KM_POINTER(NdisPacket);
    ASSERT_KM_POINTER(PC(NdisPacket));
    PC(NdisPacket)->DLComplete = ARPTransmitComplete;

    TI_DbgPrint(DEBUG_ARP,("Sending ARP Packet\n"));

    (*Interface->Transmit)(Interface->Context, NdisPacket,
        0, NULL, LAN_PROTO_ARP);

    return TRUE;
}