Exemple #1
0
/**
  Parse the DHCP ACK to get Dns4 server information.

  @param  Instance         The DNS instance.
  @param  DnsServerCount   Retrieved Dns4 server Ip count.
  @param  DnsServerList    Retrieved Dns4 server Ip list.

  @retval EFI_SUCCESS           The Dns4 information is got from the DHCP ACK.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory.
  @retval EFI_NO_MEDIA          There was a media error.
  @retval Others                Other errors as indicated.

**/
EFI_STATUS
GetDns4ServerFromDhcp4 (
  IN  DNS_INSTANCE               *Instance,
  OUT UINT32                     *DnsServerCount,
  OUT EFI_IPv4_ADDRESS           **DnsServerList
  )
{
  EFI_STATUS                          Status;
  EFI_HANDLE                          Image;
  EFI_HANDLE                          Controller;
  BOOLEAN                             MediaPresent;
  EFI_HANDLE                          MnpChildHandle;  
  EFI_MANAGED_NETWORK_PROTOCOL        *Mnp;
  EFI_MANAGED_NETWORK_CONFIG_DATA     MnpConfigData;
  EFI_HANDLE                          Dhcp4Handle;  
  EFI_DHCP4_PROTOCOL                  *Dhcp4;
  EFI_IP4_CONFIG2_PROTOCOL            *Ip4Config2;
  UINTN                               DataSize;
  VOID                                *Data;
  EFI_IP4_CONFIG2_INTERFACE_INFO      *InterfaceInfo;
  EFI_DHCP4_PACKET                    SeedPacket;
  EFI_DHCP4_PACKET_OPTION             *ParaList[2];
  DNS4_SERVER_INFOR                   DnsServerInfor;

  EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN    Token;
  BOOLEAN                             IsDone;
  UINTN                               Index;
  
  Image                      = Instance->Service->ImageHandle;
  Controller                 = Instance->Service->ControllerHandle;

  MnpChildHandle             = NULL;
  Mnp                        = NULL;
  
  Dhcp4Handle                = NULL;
  Dhcp4                      = NULL;

  Ip4Config2                 = NULL;
  DataSize                   = 0;
  Data                       = NULL;
  InterfaceInfo              = NULL;

  ZeroMem ((UINT8 *) ParaList, sizeof (ParaList));

  ZeroMem (&MnpConfigData, sizeof (EFI_MANAGED_NETWORK_CONFIG_DATA));
  
  ZeroMem (&DnsServerInfor, sizeof (DNS4_SERVER_INFOR));
  
  ZeroMem (&Token, sizeof (EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN));
  
  DnsServerInfor.ServerCount = DnsServerCount;

  IsDone = FALSE;

  //
  // Check media.
  //
  MediaPresent = TRUE;
  NetLibDetectMedia (Controller, &MediaPresent);
  if (!MediaPresent) {
    return EFI_NO_MEDIA;
  }

  //
  // Start the auto configuration if UseDefaultSetting.
  //
  if (Instance->Dns4CfgData.UseDefaultSetting) {
    Status = DnsStartIp4 (Controller, Image);
    if (EFI_ERROR(Status)) {
      return Status;
    }
  }
  
  //
  // Create a Mnp child instance, get the protocol and config for it.
  //
  Status = NetLibCreateServiceChild (
             Controller,
             Image,
             &gEfiManagedNetworkServiceBindingProtocolGuid,
             &MnpChildHandle
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->OpenProtocol (
                  MnpChildHandle,
                  &gEfiManagedNetworkProtocolGuid,
                  (VOID **) &Mnp,
                  Image,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }
  
  MnpConfigData.ReceivedQueueTimeoutValue = 0;
  MnpConfigData.TransmitQueueTimeoutValue = 0;
  MnpConfigData.ProtocolTypeFilter        = IP4_ETHER_PROTO;
  MnpConfigData.EnableUnicastReceive      = TRUE;
  MnpConfigData.EnableMulticastReceive    = TRUE;
  MnpConfigData.EnableBroadcastReceive    = TRUE;
  MnpConfigData.EnablePromiscuousReceive  = FALSE;
  MnpConfigData.FlushQueuesOnReset        = TRUE;
  MnpConfigData.EnableReceiveTimestamps   = FALSE;
  MnpConfigData.DisableBackgroundPolling  = FALSE;

  Status = Mnp->Configure(Mnp, &MnpConfigData);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }
  
  //
  // Create a DHCP4 child instance and get the protocol.
  //
  Status = NetLibCreateServiceChild (
             Controller,
             Image,
             &gEfiDhcp4ServiceBindingProtocolGuid,
             &Dhcp4Handle
             );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  Status = gBS->OpenProtocol (
                  Dhcp4Handle,
                  &gEfiDhcp4ProtocolGuid,
                  (VOID **) &Dhcp4,
                  Image,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Get Ip4Config2 instance info.
  //
  Status = gBS->HandleProtocol (Controller, &gEfiIp4Config2ProtocolGuid, (VOID **) &Ip4Config2);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }
  
  Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeInterfaceInfo, &DataSize, Data);
  if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
    goto ON_EXIT;
  }

  Data = AllocateZeroPool (DataSize);
  if (Data == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeInterfaceInfo, &DataSize, Data);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  InterfaceInfo = (EFI_IP4_CONFIG2_INTERFACE_INFO *)Data;
  
  //
  // Build required Token.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  DhcpCommonNotify,
                  &IsDone,
                  &Token.CompletionEvent
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }
  
  SetMem (&Token.RemoteAddress, sizeof (EFI_IPv4_ADDRESS), 0xff);
  
  Token.RemotePort = 67;

  Token.ListenPointCount = 1;
  
  Token.ListenPoints = AllocateZeroPool (Token.ListenPointCount * sizeof (EFI_DHCP4_LISTEN_POINT));
  if (Token.ListenPoints == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  if (Instance->Dns4CfgData.UseDefaultSetting) {
    CopyMem (&(Token.ListenPoints[0].ListenAddress), &(InterfaceInfo->StationAddress), sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&(Token.ListenPoints[0].SubnetMask), &(InterfaceInfo->SubnetMask), sizeof (EFI_IPv4_ADDRESS));
  } else {
    CopyMem (&(Token.ListenPoints[0].ListenAddress), &(Instance->Dns4CfgData.StationIp), sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&(Token.ListenPoints[0].SubnetMask), &(Instance->Dns4CfgData.SubnetMask), sizeof (EFI_IPv4_ADDRESS));
  }
  
  Token.ListenPoints[0].ListenPort = 68;
  
  Token.TimeoutValue = DNS_TIME_TO_GETMAP;

  DnsInitSeedPacket (&SeedPacket, InterfaceInfo);

  ParaList[0] = AllocateZeroPool (sizeof (EFI_DHCP4_PACKET_OPTION));
  if (ParaList[0] == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }
  
  ParaList[0]->OpCode  = DHCP4_TAG_TYPE;
  ParaList[0]->Length  = 1;
  ParaList[0]->Data[0] = DHCP4_MSG_INFORM;
  
  ParaList[1] = AllocateZeroPool (sizeof (EFI_DHCP4_PACKET_OPTION));
  if (ParaList[1] == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }
  
  ParaList[1]->OpCode  = DHCP4_TAG_PARA_LIST;
  ParaList[1]->Length  = 1;
  ParaList[1]->Data[0] = DHCP4_TAG_DNS_SERVER;

  Status = Dhcp4->Build (Dhcp4, &SeedPacket, 0, NULL, 2, ParaList, &Token.Packet); 

  Token.Packet->Dhcp4.Header.Xid      = HTONL(NET_RANDOM (NetRandomInitSeed ()));
  
  Token.Packet->Dhcp4.Header.Reserved = HTONS ((UINT16)0x8000);
  
  if (Instance->Dns4CfgData.UseDefaultSetting) {
    CopyMem (&(Token.Packet->Dhcp4.Header.ClientAddr), &(InterfaceInfo->StationAddress), sizeof (EFI_IPv4_ADDRESS));
  } else {
    CopyMem (&(Token.Packet->Dhcp4.Header.ClientAddr), &(Instance->Dns4CfgData.StationIp), sizeof (EFI_IPv4_ADDRESS));
  }
  
  CopyMem (Token.Packet->Dhcp4.Header.ClientHwAddr, &(InterfaceInfo->HwAddress), InterfaceInfo->HwAddressSize); 
  
  Token.Packet->Dhcp4.Header.HwAddrLen = (UINT8)(InterfaceInfo->HwAddressSize);

  //
  // TransmitReceive Token
  //
  Status = Dhcp4->TransmitReceive (Dhcp4, &Token);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Poll the packet
  //
  do {
    Status = Mnp->Poll (Mnp);
  } while (!IsDone);
  
  //
  // Parse the ACK to get required information if received done.
  //
  if (IsDone && !EFI_ERROR (Token.Status)) {
    for (Index = 0; Index < Token.ResponseCount; Index++) {
      Status = ParseDhcp4Ack (Dhcp4, &Token.ResponseList[Index], &DnsServerInfor);
      if (!EFI_ERROR (Status)) {
        break;
      }
    }

    *DnsServerList = DnsServerInfor.ServerList;
  } else {
    Status = Token.Status;
  }
  
ON_EXIT:

  if (Data != NULL) {
    FreePool (Data);
  }

  for (Index = 0; Index < 2; Index++) {
    if (ParaList[Index] != NULL) {
      FreePool (ParaList[Index]);
    }
  }

  if (Token.ListenPoints) {
    FreePool (Token.ListenPoints);
  }

  if (Token.Packet) {
    FreePool (Token.Packet);
  }
  
  if (Token.ResponseList != NULL) {
    FreePool (Token.ResponseList);
  }
  
  if (Token.CompletionEvent != NULL) {
    gBS->CloseEvent (Token.CompletionEvent);
  }
  
  if (Dhcp4 != NULL) {
    Dhcp4->Stop (Dhcp4);
    Dhcp4->Configure (Dhcp4, NULL);

    gBS->CloseProtocol (
           Dhcp4Handle,
           &gEfiDhcp4ProtocolGuid,
           Image,
           Controller
           );
  }
  
  if (Dhcp4Handle != NULL) {
    NetLibDestroyServiceChild (
      Controller,
      Image,
      &gEfiDhcp4ServiceBindingProtocolGuid,
      Dhcp4Handle
      );
  }

  if (Mnp != NULL) {
    Mnp->Configure (Mnp, NULL);

    gBS->CloseProtocol (
           MnpChildHandle,
           &gEfiManagedNetworkProtocolGuid,
           Image,
           Controller
           );
  }
  
  NetLibDestroyServiceChild (
    Controller,
    Image,
    &gEfiManagedNetworkServiceBindingProtocolGuid,
    MnpChildHandle
    );
  
  return Status;
}
Exemple #2
0
uint16_t compress_tcp_packet(socket_internal_t *current_socket,
                             uint8_t *current_tcp_packet,
                             ipv6_hdr_t *temp_ipv6_header,
                             uint8_t flags,
                             uint8_t payload_length)
{
    socket_t *current_tcp_socket = &current_socket->socket_values;
    tcp_hc_context_t *tcp_context = &current_tcp_socket->tcp_control.tcp_context;
    tcp_cb_t *tcp_cb = &current_tcp_socket->tcp_control;
    tcp_hdr_t full_tcp_header;
    uint16_t packet_size = 0;

    /* Connection establisment phase, use FULL_HEADER TCP */
    if (tcp_context->hc_type == FULL_HEADER) {
        /* draft-aayadi-6lowpan-tcphc-01: 5.1 Full header TCP segment.
         * Establishing Connection */

        /* Move tcp packet 3 bytes to add padding and Context ID */
        memmove(current_tcp_packet + 3, current_tcp_packet,
                ((((tcp_hdr_t *)current_tcp_packet)->data_offset) * 4) +
                payload_length);

        /* 1 padding byte with value 0x01 to introduce full header TCP_HC
         * segment */
        memset(current_tcp_packet, 0x01, 1);

        /* Adding Context ID */
        uint16_t current_context = HTONS(tcp_context->context_id);
        memcpy(current_tcp_packet + 1, &current_context, 2);

        /* Return correct header length (+3) */
        packet_size = ((((tcp_hdr_t *)(current_tcp_packet + 3))->data_offset) * 4) + 3 +
                      payload_length;

        /* Update the tcp context fields */
        update_tcp_hc_context(false, current_socket, (tcp_hdr_t *)(current_tcp_packet + 3));

        /* Convert TCP packet to network byte order */
        switch_tcp_packet_byte_order((tcp_hdr_t *)(current_tcp_packet + 3));

        return packet_size;
    }
    /* Check for header compression type: COMPRESSED_HEADER */
    else if (tcp_context->hc_type == COMPRESSED_HEADER) {
        /* draft-aayadi-6lowpan-tcphc-01: 5.1 Compressed header TCP segment. */

        /* Temporary variable for TCP_HC_Header Bytes */
        uint16_t tcp_hc_header = 0x0000;

        /* Save TCP_Header to refresh TCP Context values after compressing the
         * packet */
        memcpy(&full_tcp_header, current_tcp_packet, TCP_HDR_LEN);

        /* Temporary variable for storing TCP header beginning */
        uint8_t *tcp_packet_begin = current_tcp_packet;

        /* Position for first TCP header value, TCP_HC_Header and Context ID */
        current_tcp_packet += 4;

        /* Packet size value */
        packet_size += 4;

        /* 5.2.  LOWPAN_TCPHC Format */

        /* First 3 bits of TCP_HC_Header are not exactly specified. In this
         * implementation they are (1|1|0) * for compressed headers and the
         * CID is always 16 bits (1) */
        /* (1|1|0|1) = D */
        tcp_hc_header |= 0xD000;

        /*----------------------------------*/
        /*|     Sequence number handling   |*/
        /*----------------------------------*/
        if (full_tcp_header.seq_nr == tcp_context->seq_snd) {
            /* Nothing to do, Seq = (0|0) */
        }
        /* If the 24 most significant bits haven't changed from previous
         * packet, don't transmit them */
        else if ((full_tcp_header.seq_nr & 0xFFFFFF00) == (tcp_context->seq_snd &
                 0xFFFFFF00)) {
            /* Seq = (0|1) */
            tcp_hc_header |= 0x0400;

            /* Copy first 8 less significant bits of sequence number into
             * buffer */
            *current_tcp_packet = (uint8_t)(full_tcp_header.seq_nr & 0x000000FF);
            current_tcp_packet += 1;
            packet_size += 1;
        }
        /* If the 16 most significant bits haven't changed from previous packet,
         * don't transmit them */
        else if ((full_tcp_header.seq_nr & 0xFFFF0000) == (tcp_context->seq_snd & 0xFFFF0000)) {
            /* Seq = (1|0) */
            tcp_hc_header |= 0x0800;

            /* Copy first 16 less significant bits of sequence number into buffer */
            *((uint16_t *)current_tcp_packet) =
                HTONS((uint16_t)(full_tcp_header.seq_nr & 0x0000FFFF));
            current_tcp_packet += 2;
            packet_size += 2;
        }
        /* Sending uncompressed sequence number */
        else {
            /* Seq = (1|1) */
            tcp_hc_header |= 0x0C00;

            /* Copy all bits of sequence number into buffer */
            uint32_t cur_seq_no = HTONL(full_tcp_header.seq_nr);
            memcpy(current_tcp_packet, &cur_seq_no, 4);
            current_tcp_packet += 4;
            packet_size += 4;
        }

        /*----------------------------------*/
        /*| Acknowledgment number handling |*/
        /*----------------------------------*/
        if ((IS_TCP_ACK(full_tcp_header.reserved_flags) &&
             (tcp_cb->tcp_context.ack_snd == full_tcp_header.ack_nr))) {
            tcp_context->ack_snd = tcp_context->seq_rcv;
        }

        if (full_tcp_header.ack_nr == tcp_context->ack_snd) {
            /* Nothing to do, Ack = (0|0) */
        }
        /* If the 24 most significant bits haven't changed from previous packet,
         * don't transmit them */
        else if ((full_tcp_header.ack_nr & 0xFFFFFF00) == (tcp_context->ack_snd &
                 0xFFFFFF00)) {
            /* Ack = (0|1) */
            tcp_hc_header |= 0x0100;

            /* Copy first 8 less significant bits of acknowledgment number into
             * buffer */
            *current_tcp_packet = (uint8_t)(full_tcp_header.ack_nr & 0x000000FF);
            current_tcp_packet += 1;
            packet_size += 1;
        }
        /* If the 16 most significant bits haven't changed from previous packet,
         * don't transmit them */
        else if ((full_tcp_header.ack_nr & 0xFFFF0000) == (tcp_context->ack_snd &
                 0xFFFF0000)) {
            /* Ack = (1|0) */
            tcp_hc_header |= 0x0200;

            /* Copy first 16 less significant bits of acknowledgment number
             * into buffer */
            *((uint16_t *)current_tcp_packet) =
                HTONS((uint16_t)(full_tcp_header.ack_nr & 0x0000FFFF));
            current_tcp_packet += 2;
            packet_size += 2;
        }
        /* Sending uncompressed acknowledgment number */
        else {
            /* Ack = (1|1) */
            tcp_hc_header |= 0x0300;

            /* Copy all bits of acknowledgment number into buffer */
            uint32_t cur_ack_nr = HTONL(full_tcp_header.ack_nr);
            memcpy(current_tcp_packet, &cur_ack_nr, 4);
            current_tcp_packet += 4;
            packet_size += 4;
        }

        /*----------------------------------*/
        /*|         Window handling        |*/
        /*----------------------------------*/
        if (full_tcp_header.window == tcp_context->wnd_snd) {
            /* Nothing to do, Wnd = (0|0) */
        }
        /* If the 8 most significant bits haven't changed from previous packet,
         * don't transmit them */
        else if ((full_tcp_header.window & 0xFF00) == (tcp_context->wnd_snd & 0xFF00)) {
            /* Wnd = (0|1) */
            tcp_hc_header |= 0x0040;

            /* Copy first 8 less significant bits of window size into buffer */
            *current_tcp_packet = (uint8_t)(full_tcp_header.window & 0x00FF);
            current_tcp_packet += 1;
            packet_size += 1;
        }
        /* If the 8 less significant bits haven't changed from previous packet,
         * don't transmit them */
        else if ((full_tcp_header.window & 0x00FF) == (tcp_context->wnd_snd &
                 0x00FF)) {
            /* Wnd = (1|0) */
            tcp_hc_header |= 0x0080;

            /* Copy first 8 most significant bits of window size into buffer */
            *current_tcp_packet = (uint8_t)(full_tcp_header.window & 0xFF00);
            current_tcp_packet += 1;
            packet_size += 1;
        }
        /* Sending uncompressed window */
        else {
            /* Wnd = (1|1) */
            tcp_hc_header |= 0x00C0;

            /* Copy all bits of window size into buffer */
            uint16_t cur_window = HTONS(full_tcp_header.window);
            memcpy(current_tcp_packet, &cur_window, 2);
            current_tcp_packet += 2;
            packet_size += 2;
        }

        /* FIN flag */
        if (IS_TCP_FIN(full_tcp_header.reserved_flags)) {
            /* F = (1) */
            tcp_hc_header |= 0x0008;
        }

        /* Copy checksum into buffer */
        uint16_t cur_chk_sum = HTONS(full_tcp_header.checksum);
        memcpy(current_tcp_packet, &cur_chk_sum, 2);
        current_tcp_packet += 2;
        packet_size += 2;

        /* Copy TCP_HC Bytes into buffer */
        uint16_t cur_tcp_hc_header = HTONS(tcp_hc_header);
        memcpy(tcp_packet_begin, &cur_tcp_hc_header, 2);

        /* Copy TCP_HC Context ID into buffer */
        uint16_t cur_context_id = HTONS(tcp_context->context_id);
        memcpy(tcp_packet_begin + 2, &cur_context_id, 2);

        /* Move payload to end of tcp header */
        memmove(current_tcp_packet, tcp_packet_begin + TCP_HDR_LEN,
                payload_length);

        /* Adding TCP payload length to TCP_HC header length */
        packet_size += payload_length;

        update_tcp_hc_context(false, current_socket, &full_tcp_header);

        return packet_size;
    }
    /* Check for header compression type: MOSTLY_COMPRESSED_HEADER */
    else if (tcp_context->hc_type == MOSTLY_COMPRESSED_HEADER) {
        /* draft-aayadi-6lowpan-tcphc-01: 5.1 Compressed header TCP segment. */

        /* Temporary variable for TCP_HC_Header Bytes */
        uint16_t tcp_hc_header = 0x0000;

        /* Save TCP_Header to refresh TCP Context values after compressing the
         * packet */
        memcpy(&full_tcp_header, current_tcp_packet, TCP_HDR_LEN);

        /* Temporary variable for storing TCP header beginning */
        uint8_t *tcp_packet_begin = current_tcp_packet;

        /* Position for first TCP header value, TCP_HC_Header and Context ID */
        current_tcp_packet += 4;

        /* Packet size value */
        packet_size += 4;

        /* 5.2.  LOWPAN_TCPHC Format */

        /* First 3 bits of TCP_HC_Header are not exactly specified. In this
         * implementation they are (1|0|0) for mostly compressed headers and
         * the CID is always 16 bits (1) */
        /* (1|0|0|1) = 9 */
        tcp_hc_header |= 0x9000;

        /*----------------------------------*/
        /*|     Sequence number handling   |*/
        /*----------------------------------*/
        /* Sending uncompressed sequence number */
        /* Seq = (1|1) */
        tcp_hc_header |= 0x0C00;

        /* Copy all bits of sequence number into buffer */
        uint32_t cur_seq_no = HTONL(full_tcp_header.seq_nr);
        memcpy(current_tcp_packet, &cur_seq_no, 4);
        current_tcp_packet += 4;
        packet_size += 4;

        /*----------------------------------*/
        /*| Acknowledgment number handling |*/
        /*----------------------------------*/
        /* Ack = (1|1) */
        tcp_hc_header |= 0x0300;

        /* Copy all bits of acknowledgment number into buffer */
        uint32_t cur_ack_nr = HTONL(full_tcp_header.ack_nr);
        memcpy(current_tcp_packet, &cur_ack_nr, 4);
        current_tcp_packet += 4;
        packet_size += 4;

        /*----------------------------------*/
        /*|         Window handling        |*/
        /*----------------------------------*/
        /* Wnd = (1|1) */
        tcp_hc_header |= 0x00C0;

        /* Copy all bits of window size into buffer */
        uint16_t cur_window = HTONS(full_tcp_header.window);
        memcpy(current_tcp_packet, &cur_window, 2);
        current_tcp_packet += 2;
        packet_size += 2;

        /* FIN flag */
        if (IS_TCP_FIN(full_tcp_header.reserved_flags)) {
            /* F = (1) */
            tcp_hc_header |= 0x0008;
        }

        /* Copy checksum into buffer */
        uint16_t cur_chk_sum = HTONS(full_tcp_header.checksum);
        memcpy(current_tcp_packet, &cur_chk_sum, 2);
        current_tcp_packet += 2;
        packet_size += 2;

        /* Copy TCP_HC Bytes into buffer */
        uint16_t cur_tcp_hc_header = HTONS(tcp_hc_header);
        memcpy(tcp_packet_begin, &cur_tcp_hc_header, 2);

        /* Copy TCP_HC Context ID into buffer */
        uint16_t cur_context_id = HTONS(tcp_context->context_id);
        memcpy(tcp_packet_begin + 2, &cur_context_id, 2);

        /* Move payload to end of tcp header */
        memmove(current_tcp_packet, tcp_packet_begin + TCP_HDR_LEN,
                payload_length);

        /* Adding TCP payload length to TCP_HC header length */
        packet_size += payload_length;

        update_tcp_hc_context(false, current_socket, &full_tcp_header);
        return packet_size;
    }

    return 0;
}
Exemple #3
0
/*
 * TCP input routine, follows pages 65-76 of the
 * protocol specification dated September, 1981 very closely.
 */
void
tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
{
  	struct ip save_ip, *ip;
	register struct tcpiphdr *ti;
	caddr_t optp = NULL;
	int optlen = 0;
	int len, tlen, off;
        register struct tcpcb *tp = NULL;
	register int tiflags;
        struct socket *so = NULL;
	int todrop, acked, ourfinisacked, needoutput = 0;
	int iss = 0;
	u_long tiwin;
	int ret;
    struct ex_list *ex_ptr;
    Slirp *slirp;

	DEBUG_CALL("tcp_input");
	DEBUG_ARGS((dfd," m = %8lx  iphlen = %2d  inso = %lx\n",
		    (long )m, iphlen, (long )inso ));

	/*
	 * If called with m == 0, then we're continuing the connect
	 */
	if (m == NULL) {
		so = inso;
		slirp = so->slirp;

		/* Re-set a few variables */
		tp = sototcpcb(so);
		m = so->so_m;
                so->so_m = NULL;
		ti = so->so_ti;
		tiwin = ti->ti_win;
		tiflags = ti->ti_flags;

		goto cont_conn;
	}
	slirp = m->slirp;

	/*
	 * Get IP and TCP header together in first mbuf.
	 * Note: IP leaves IP header in first mbuf.
	 */
	ti = mtod(m, struct tcpiphdr *);
	if (iphlen > sizeof(struct ip )) {
	  ip_stripoptions(m, (struct mbuf *)0);
	  iphlen=sizeof(struct ip );
	}
	/* XXX Check if too short */


	/*
	 * Save a copy of the IP header in case we want restore it
	 * for sending an ICMP error message in response.
	 */
	ip=mtod(m, struct ip *);
	save_ip = *ip;
	save_ip.ip_len+= iphlen;

	/*
	 * Checksum extended TCP header and data.
	 */
	tlen = ((struct ip *)ti)->ip_len;
        tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = NULL;
        memset(&ti->ti_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr));
	ti->ti_x1 = 0;
	ti->ti_len = htons((u_int16_t)tlen);
	len = sizeof(struct ip ) + tlen;
	if(cksum(m, len)) {
	  goto drop;
	}

	/*
	 * Check that TCP offset makes sense,
	 * pull out TCP options and adjust length.		XXX
	 */
	off = ti->ti_off << 2;
	if (off < sizeof (struct tcphdr) || off > tlen) {
	  goto drop;
	}
	tlen -= off;
	ti->ti_len = tlen;
	if (off > sizeof (struct tcphdr)) {
	  optlen = off - sizeof (struct tcphdr);
	  optp = mtod(m, caddr_t) + sizeof (struct tcpiphdr);
	}
	tiflags = ti->ti_flags;

	/*
	 * Convert TCP protocol specific fields to host format.
	 */
	NTOHL(ti->ti_seq);
	NTOHL(ti->ti_ack);
	NTOHS(ti->ti_win);
	NTOHS(ti->ti_urp);

	/*
	 * Drop TCP, IP headers and TCP options.
	 */
	m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
	m->m_len  -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);

    if (slirp->restricted) {
        for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
            if (ex_ptr->ex_fport == ti->ti_dport &&
                ti->ti_dst.s_addr == ex_ptr->ex_addr.s_addr) {
                break;
            }
        }
        if (!ex_ptr)
            goto drop;
    }
	/*
	 * Locate pcb for segment.
	 */
findso:
	so = slirp->tcp_last_so;
	if (so->so_fport != ti->ti_dport ||
	    so->so_lport != ti->ti_sport ||
	    so->so_laddr.s_addr != ti->ti_src.s_addr ||
	    so->so_faddr.s_addr != ti->ti_dst.s_addr) {
		so = solookup(&slirp->tcb, ti->ti_src, ti->ti_sport,
			       ti->ti_dst, ti->ti_dport);
		if (so)
			slirp->tcp_last_so = so;
	}

	/*
	 * If the state is CLOSED (i.e., TCB does not exist) then
	 * all data in the incoming segment is discarded.
	 * If the TCB exists but is in CLOSED state, it is embryonic,
	 * but should either do a listen or a connect soon.
	 *
	 * state == CLOSED means we've done socreate() but haven't
	 * attached it to a protocol yet...
	 *
	 * XXX If a TCB does not exist, and the TH_SYN flag is
	 * the only flag set, then create a session, mark it
	 * as if it was LISTENING, and continue...
	 */
        if (so == NULL) {
	  if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN)
	    goto dropwithreset;

	  if ((so = socreate(slirp)) == NULL)
	    goto dropwithreset;
	  if (tcp_attach(so) < 0) {
	    free(so); /* Not sofree (if it failed, it's not insqued) */
	    goto dropwithreset;
	  }

	  sbreserve(&so->so_snd, TCP_SNDSPACE);
	  sbreserve(&so->so_rcv, TCP_RCVSPACE);

	  so->so_laddr = ti->ti_src;
	  so->so_lport = ti->ti_sport;
	  so->so_faddr = ti->ti_dst;
	  so->so_fport = ti->ti_dport;

	  if ((so->so_iptos = tcp_tos(so)) == 0)
	    so->so_iptos = ((struct ip *)ti)->ip_tos;

	  tp = sototcpcb(so);
	  tp->t_state = TCPS_LISTEN;
	}

        /*
         * If this is a still-connecting socket, this probably
         * a retransmit of the SYN.  Whether it's a retransmit SYN
	 * or something else, we nuke it.
         */
        if (so->so_state & SS_ISFCONNECTING)
                goto drop;

	tp = sototcpcb(so);

	/* XXX Should never fail */
        if (tp == NULL)
		goto dropwithreset;
	if (tp->t_state == TCPS_CLOSED)
		goto drop;

	tiwin = ti->ti_win;

	/*
	 * Segment received on connection.
	 * Reset idle time and keep-alive timer.
	 */
	tp->t_idle = 0;
	if (SO_OPTIONS)
	   tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL;
	else
	   tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE;

	/*
	 * Process options if not in LISTEN state,
	 * else do it below (after getting remote address).
	 */
	if (optp && tp->t_state != TCPS_LISTEN)
		tcp_dooptions(tp, (u_char *)optp, optlen, ti);

	/*
	 * Header prediction: check for the two common cases
	 * of a uni-directional data xfer.  If the packet has
	 * no control flags, is in-sequence, the window didn't
	 * change and we're not retransmitting, it's a
	 * candidate.  If the length is zero and the ack moved
	 * forward, we're the sender side of the xfer.  Just
	 * free the data acked & wake any higher level process
	 * that was blocked waiting for space.  If the length
	 * is non-zero and the ack didn't move, we're the
	 * receiver side.  If we're getting packets in-order
	 * (the reassembly queue is empty), add the data to
	 * the socket buffer and note that we need a delayed ack.
	 *
	 * XXX Some of these tests are not needed
	 * eg: the tiwin == tp->snd_wnd prevents many more
	 * predictions.. with no *real* advantage..
	 */
	if (tp->t_state == TCPS_ESTABLISHED &&
	    (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK &&
	    ti->ti_seq == tp->rcv_nxt &&
	    tiwin && tiwin == tp->snd_wnd &&
	    tp->snd_nxt == tp->snd_max) {
		if (ti->ti_len == 0) {
			if (SEQ_GT(ti->ti_ack, tp->snd_una) &&
			    SEQ_LEQ(ti->ti_ack, tp->snd_max) &&
			    tp->snd_cwnd >= tp->snd_wnd) {
				/*
				 * this is a pure ack for outstanding data.
				 */
				if (tp->t_rtt &&
				    SEQ_GT(ti->ti_ack, tp->t_rtseq))
					tcp_xmit_timer(tp, tp->t_rtt);
				acked = ti->ti_ack - tp->snd_una;
				sbdrop(&so->so_snd, acked);
				tp->snd_una = ti->ti_ack;
				m_freem(m);

				/*
				 * If all outstanding data are acked, stop
				 * retransmit timer, otherwise restart timer
				 * using current (possibly backed-off) value.
				 * If process is waiting for space,
				 * wakeup/selwakeup/signal.  If data
				 * are ready to send, let tcp_output
				 * decide between more output or persist.
				 */
				if (tp->snd_una == tp->snd_max)
					tp->t_timer[TCPT_REXMT] = 0;
				else if (tp->t_timer[TCPT_PERSIST] == 0)
					tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;

				/*
				 * This is called because sowwakeup might have
				 * put data into so_snd.  Since we don't so sowwakeup,
				 * we don't need this.. XXX???
				 */
				if (so->so_snd.sb_cc)
					(void) tcp_output(tp);

				return;
			}
		} else if (ti->ti_ack == tp->snd_una &&
		    tcpfrag_list_empty(tp) &&
		    ti->ti_len <= sbspace(&so->so_rcv)) {
			/*
			 * this is a pure, in-sequence data packet
			 * with nothing on the reassembly queue and
			 * we have enough buffer space to take it.
			 */
			tp->rcv_nxt += ti->ti_len;
			/*
			 * Add data to socket buffer.
			 */
			if (so->so_emu) {
				if (tcp_emu(so,m)) sbappend(so, m);
			} else
				sbappend(so, m);

			/*
			 * If this is a short packet, then ACK now - with Nagel
			 *	congestion avoidance sender won't send more until
			 *	he gets an ACK.
			 *
			 * It is better to not delay acks at all to maximize
			 * TCP throughput.  See RFC 2581.
			 */
			tp->t_flags |= TF_ACKNOW;
			tcp_output(tp);
			return;
		}
	} /* header prediction */
	/*
	 * Calculate amount of space in receive window,
	 * and then do TCP input processing.
	 * Receive window is amount of space in rcv queue,
	 * but not less than advertised window.
	 */
	{ int win;
          win = sbspace(&so->so_rcv);
	  if (win < 0)
	    win = 0;
	  tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt));
	}

	switch (tp->t_state) {

	/*
	 * If the state is LISTEN then ignore segment if it contains an RST.
	 * If the segment contains an ACK then it is bad and send a RST.
	 * If it does not contain a SYN then it is not interesting; drop it.
	 * Don't bother responding if the destination was a broadcast.
	 * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
	 * tp->iss, and send a segment:
	 *     <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK>
	 * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss.
	 * Fill in remote peer address fields if not previously specified.
	 * Enter SYN_RECEIVED state, and process any other fields of this
	 * segment in this state.
	 */
	case TCPS_LISTEN: {

	  if (tiflags & TH_RST)
	    goto drop;
	  if (tiflags & TH_ACK)
	    goto dropwithreset;
	  if ((tiflags & TH_SYN) == 0)
	    goto drop;

	  /*
	   * This has way too many gotos...
	   * But a bit of spaghetti code never hurt anybody :)
	   */

	  /*
	   * If this is destined for the control address, then flag to
	   * tcp_ctl once connected, otherwise connect
	   */
	  if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
	      slirp->vnetwork_addr.s_addr) {
	    if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr &&
		so->so_faddr.s_addr != slirp->vnameserver_addr.s_addr) {
		/* May be an add exec */
		for (ex_ptr = slirp->exec_list; ex_ptr;
		     ex_ptr = ex_ptr->ex_next) {
		  if(ex_ptr->ex_fport == so->so_fport &&
		     so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
		    so->so_state |= SS_CTL;
		    break;
		  }
		}
		if (so->so_state & SS_CTL) {
		    goto cont_input;
		}
	    }
	    /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */
	  }

	  if (so->so_emu & EMU_NOCONNECT) {
	    so->so_emu &= ~EMU_NOCONNECT;
	    goto cont_input;
	  }

	  if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) {
	    u_char code=ICMP_UNREACH_NET;
	    DEBUG_MISC((dfd," tcp fconnect errno = %d-%s\n",
			errno,strerror(errno)));
	    if(errno == ECONNREFUSED) {
	      /* ACK the SYN, send RST to refuse the connection */
	      tcp_respond(tp, ti, m, ti->ti_seq+1, (tcp_seq)0,
			  TH_RST|TH_ACK);
	    } else {
	      if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
	      HTONL(ti->ti_seq);             /* restore tcp header */
	      HTONL(ti->ti_ack);
	      HTONS(ti->ti_win);
	      HTONS(ti->ti_urp);
	      m->m_data -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
	      m->m_len  += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
	      *ip=save_ip;
	      icmp_error(m, ICMP_UNREACH,code, 0,strerror(errno));
	    }
	    tp = tcp_close(tp);
	    m_free(m);
	  } else {
	    /*
	     * Haven't connected yet, save the current mbuf
	     * and ti, and return
	     * XXX Some OS's don't tell us whether the connect()
	     * succeeded or not.  So we must time it out.
	     */
	    so->so_m = m;
	    so->so_ti = ti;
	    tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
	    tp->t_state = TCPS_SYN_RECEIVED;
	  }
	  return;

	cont_conn:
	  /* m==NULL
	   * Check if the connect succeeded
	   */
	  if (so->so_state & SS_NOFDREF) {
	    tp = tcp_close(tp);
	    goto dropwithreset;
	  }
	cont_input:
	  tcp_template(tp);

	  if (optp)
	    tcp_dooptions(tp, (u_char *)optp, optlen, ti);

	  if (iss)
	    tp->iss = iss;
	  else
	    tp->iss = slirp->tcp_iss;
	  slirp->tcp_iss += TCP_ISSINCR/2;
	  tp->irs = ti->ti_seq;
	  tcp_sendseqinit(tp);
	  tcp_rcvseqinit(tp);
	  tp->t_flags |= TF_ACKNOW;
	  tp->t_state = TCPS_SYN_RECEIVED;
	  tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
	  goto trimthenstep6;
	} /* case TCPS_LISTEN */

	/*
	 * If the state is SYN_SENT:
	 *	if seg contains an ACK, but not for our SYN, drop the input.
	 *	if seg contains a RST, then drop the connection.
	 *	if seg does not contain SYN, then drop it.
	 * Otherwise this is an acceptable SYN segment
	 *	initialize tp->rcv_nxt and tp->irs
	 *	if seg contains ack then advance tp->snd_una
	 *	if SYN has been acked change to ESTABLISHED else SYN_RCVD state
	 *	arrange for segment to be acked (eventually)
	 *	continue processing rest of data/controls, beginning with URG
	 */
	case TCPS_SYN_SENT:
		if ((tiflags & TH_ACK) &&
		    (SEQ_LEQ(ti->ti_ack, tp->iss) ||
		     SEQ_GT(ti->ti_ack, tp->snd_max)))
			goto dropwithreset;

		if (tiflags & TH_RST) {
			if (tiflags & TH_ACK)
				tp = tcp_drop(tp,0); /* XXX Check t_softerror! */
			goto drop;
		}

		if ((tiflags & TH_SYN) == 0)
			goto drop;
		if (tiflags & TH_ACK) {
			tp->snd_una = ti->ti_ack;
			if (SEQ_LT(tp->snd_nxt, tp->snd_una))
				tp->snd_nxt = tp->snd_una;
		}

		tp->t_timer[TCPT_REXMT] = 0;
		tp->irs = ti->ti_seq;
		tcp_rcvseqinit(tp);
		tp->t_flags |= TF_ACKNOW;
		if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) {
			soisfconnected(so);
			tp->t_state = TCPS_ESTABLISHED;

			(void) tcp_reass(tp, (struct tcpiphdr *)0,
				(struct mbuf *)0);
			/*
			 * if we didn't have to retransmit the SYN,
			 * use its rtt as our initial srtt & rtt var.
			 */
			if (tp->t_rtt)
				tcp_xmit_timer(tp, tp->t_rtt);
		} else
			tp->t_state = TCPS_SYN_RECEIVED;

trimthenstep6:
		/*
		 * Advance ti->ti_seq to correspond to first data byte.
		 * If data, trim to stay within window,
		 * dropping FIN if necessary.
		 */
		ti->ti_seq++;
		if (ti->ti_len > tp->rcv_wnd) {
			todrop = ti->ti_len - tp->rcv_wnd;
			m_adj(m, -todrop);
			ti->ti_len = tp->rcv_wnd;
			tiflags &= ~TH_FIN;
		}
		tp->snd_wl1 = ti->ti_seq - 1;
		tp->rcv_up = ti->ti_seq;
		goto step6;
	} /* switch tp->t_state */
	/*
	 * States other than LISTEN or SYN_SENT.
	 * Check that at least some bytes of segment are within
	 * receive window.  If segment begins before rcv_nxt,
	 * drop leading data (and SYN); if nothing left, just ack.
	 */
	todrop = tp->rcv_nxt - ti->ti_seq;
	if (todrop > 0) {
		if (tiflags & TH_SYN) {
			tiflags &= ~TH_SYN;
			ti->ti_seq++;
			if (ti->ti_urp > 1)
				ti->ti_urp--;
			else
				tiflags &= ~TH_URG;
			todrop--;
		}
		/*
		 * Following if statement from Stevens, vol. 2, p. 960.
		 */
		if (todrop > ti->ti_len
		    || (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) {
			/*
			 * Any valid FIN must be to the left of the window.
			 * At this point the FIN must be a duplicate or out
			 * of sequence; drop it.
			 */
			tiflags &= ~TH_FIN;

			/*
			 * Send an ACK to resynchronize and drop any data.
			 * But keep on processing for RST or ACK.
			 */
			tp->t_flags |= TF_ACKNOW;
			todrop = ti->ti_len;
		}
		m_adj(m, todrop);
		ti->ti_seq += todrop;
		ti->ti_len -= todrop;
		if (ti->ti_urp > todrop)
			ti->ti_urp -= todrop;
		else {
			tiflags &= ~TH_URG;
			ti->ti_urp = 0;
		}
	}
	/*
	 * If new data are received on a connection after the
	 * user processes are gone, then RST the other end.
	 */
	if ((so->so_state & SS_NOFDREF) &&
	    tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) {
		tp = tcp_close(tp);
		goto dropwithreset;
	}

	/*
	 * If segment ends after window, drop trailing data
	 * (and PUSH and FIN); if nothing left, just ACK.
	 */
	todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd);
	if (todrop > 0) {
		if (todrop >= ti->ti_len) {
			/*
			 * If a new connection request is received
			 * while in TIME_WAIT, drop the old connection
			 * and start over if the sequence numbers
			 * are above the previous ones.
			 */
			if (tiflags & TH_SYN &&
			    tp->t_state == TCPS_TIME_WAIT &&
			    SEQ_GT(ti->ti_seq, tp->rcv_nxt)) {
				iss = tp->rcv_nxt + TCP_ISSINCR;
				tp = tcp_close(tp);
				goto findso;
			}
			/*
			 * If window is closed can only take segments at
			 * window edge, and have to drop data and PUSH from
			 * incoming segments.  Continue processing, but
			 * remember to ack.  Otherwise, drop segment
			 * and ack.
			 */
			if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) {
				tp->t_flags |= TF_ACKNOW;
			} else {
				goto dropafterack;
			}
		}
		m_adj(m, -todrop);
		ti->ti_len -= todrop;
		tiflags &= ~(TH_PUSH|TH_FIN);
	}

	/*
	 * If the RST bit is set examine the state:
	 *    SYN_RECEIVED STATE:
	 *	If passive open, return to LISTEN state.
	 *	If active open, inform user that connection was refused.
	 *    ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES:
	 *	Inform user that connection was reset, and close tcb.
	 *    CLOSING, LAST_ACK, TIME_WAIT STATES
	 *	Close the tcb.
	 */
	if (tiflags&TH_RST) switch (tp->t_state) {

	case TCPS_SYN_RECEIVED:
	case TCPS_ESTABLISHED:
	case TCPS_FIN_WAIT_1:
	case TCPS_FIN_WAIT_2:
	case TCPS_CLOSE_WAIT:
		tp->t_state = TCPS_CLOSED;
		tp = tcp_close(tp);
		goto drop;

	case TCPS_CLOSING:
	case TCPS_LAST_ACK:
	case TCPS_TIME_WAIT:
		tp = tcp_close(tp);
		goto drop;
	}

	/*
	 * If a SYN is in the window, then this is an
	 * error and we send an RST and drop the connection.
	 */
	if (tiflags & TH_SYN) {
		tp = tcp_drop(tp,0);
		goto dropwithreset;
	}

	/*
	 * If the ACK bit is off we drop the segment and return.
	 */
	if ((tiflags & TH_ACK) == 0) goto drop;

	/*
	 * Ack processing.
	 */
	switch (tp->t_state) {
	/*
	 * In SYN_RECEIVED state if the ack ACKs our SYN then enter
	 * ESTABLISHED state and continue processing, otherwise
	 * send an RST.  una<=ack<=max
	 */
	case TCPS_SYN_RECEIVED:

		if (SEQ_GT(tp->snd_una, ti->ti_ack) ||
		    SEQ_GT(ti->ti_ack, tp->snd_max))
			goto dropwithreset;
		tp->t_state = TCPS_ESTABLISHED;
		/*
		 * The sent SYN is ack'ed with our sequence number +1
		 * The first data byte already in the buffer will get
		 * lost if no correction is made.  This is only needed for
		 * SS_CTL since the buffer is empty otherwise.
		 * tp->snd_una++; or:
		 */
		tp->snd_una=ti->ti_ack;
		if (so->so_state & SS_CTL) {
		  /* So tcp_ctl reports the right state */
		  ret = tcp_ctl(so);
		  if (ret == 1) {
		    soisfconnected(so);
		    so->so_state &= ~SS_CTL;   /* success XXX */
		  } else if (ret == 2) {
		    so->so_state &= SS_PERSISTENT_MASK;
		    so->so_state |= SS_NOFDREF; /* CTL_CMD */
		  } else {
		    needoutput = 1;
		    tp->t_state = TCPS_FIN_WAIT_1;
		  }
		} else {
		  soisfconnected(so);
		}

		(void) tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0);
		tp->snd_wl1 = ti->ti_seq - 1;
		/* Avoid ack processing; snd_una==ti_ack  =>  dup ack */
		goto synrx_to_est;
		/* fall into ... */

	/*
	 * In ESTABLISHED state: drop duplicate ACKs; ACK out of range
	 * ACKs.  If the ack is in the range
	 *	tp->snd_una < ti->ti_ack <= tp->snd_max
	 * then advance tp->snd_una to ti->ti_ack and drop
	 * data from the retransmission queue.  If this ACK reflects
	 * more up to date window information we update our window information.
	 */
	case TCPS_ESTABLISHED:
	case TCPS_FIN_WAIT_1:
	case TCPS_FIN_WAIT_2:
	case TCPS_CLOSE_WAIT:
	case TCPS_CLOSING:
	case TCPS_LAST_ACK:
	case TCPS_TIME_WAIT:

		if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) {
			if (ti->ti_len == 0 && tiwin == tp->snd_wnd) {
			  DEBUG_MISC((dfd," dup ack  m = %lx  so = %lx \n",
				      (long )m, (long )so));
				/*
				 * If we have outstanding data (other than
				 * a window probe), this is a completely
				 * duplicate ack (ie, window info didn't
				 * change), the ack is the biggest we've
				 * seen and we've seen exactly our rexmt
				 * threshold of them, assume a packet
				 * has been dropped and retransmit it.
				 * Kludge snd_nxt & the congestion
				 * window so we send only this one
				 * packet.
				 *
				 * We know we're losing at the current
				 * window size so do congestion avoidance
				 * (set ssthresh to half the current window
				 * and pull our congestion window back to
				 * the new ssthresh).
				 *
				 * Dup acks mean that packets have left the
				 * network (they're now cached at the receiver)
				 * so bump cwnd by the amount in the receiver
				 * to keep a constant cwnd packets in the
				 * network.
				 */
				if (tp->t_timer[TCPT_REXMT] == 0 ||
				    ti->ti_ack != tp->snd_una)
					tp->t_dupacks = 0;
				else if (++tp->t_dupacks == TCPREXMTTHRESH) {
					tcp_seq onxt = tp->snd_nxt;
					u_int win =
					    min(tp->snd_wnd, tp->snd_cwnd) / 2 /
						tp->t_maxseg;

					if (win < 2)
						win = 2;
					tp->snd_ssthresh = win * tp->t_maxseg;
					tp->t_timer[TCPT_REXMT] = 0;
					tp->t_rtt = 0;
					tp->snd_nxt = ti->ti_ack;
					tp->snd_cwnd = tp->t_maxseg;
					(void) tcp_output(tp);
					tp->snd_cwnd = tp->snd_ssthresh +
					       tp->t_maxseg * tp->t_dupacks;
					if (SEQ_GT(onxt, tp->snd_nxt))
						tp->snd_nxt = onxt;
					goto drop;
				} else if (tp->t_dupacks > TCPREXMTTHRESH) {
					tp->snd_cwnd += tp->t_maxseg;
					(void) tcp_output(tp);
					goto drop;
				}
			} else
				tp->t_dupacks = 0;
			break;
		}
	synrx_to_est:
		/*
		 * If the congestion window was inflated to account
		 * for the other side's cached packets, retract it.
		 */
		if (tp->t_dupacks > TCPREXMTTHRESH &&
		    tp->snd_cwnd > tp->snd_ssthresh)
			tp->snd_cwnd = tp->snd_ssthresh;
		tp->t_dupacks = 0;
		if (SEQ_GT(ti->ti_ack, tp->snd_max)) {
			goto dropafterack;
		}
		acked = ti->ti_ack - tp->snd_una;

		/*
		 * If transmit timer is running and timed sequence
		 * number was acked, update smoothed round trip time.
		 * Since we now have an rtt measurement, cancel the
		 * timer backoff (cf., Phil Karn's retransmit alg.).
		 * Recompute the initial retransmit timer.
		 */
		if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq))
			tcp_xmit_timer(tp,tp->t_rtt);

		/*
		 * If all outstanding data is acked, stop retransmit
		 * timer and remember to restart (more output or persist).
		 * If there is more data to be acked, restart retransmit
		 * timer, using current (possibly backed-off) value.
		 */
		if (ti->ti_ack == tp->snd_max) {
			tp->t_timer[TCPT_REXMT] = 0;
			needoutput = 1;
		} else if (tp->t_timer[TCPT_PERSIST] == 0)
			tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
		/*
		 * When new data is acked, open the congestion window.
		 * If the window gives us less than ssthresh packets
		 * in flight, open exponentially (maxseg per packet).
		 * Otherwise open linearly: maxseg per window
		 * (maxseg^2 / cwnd per packet).
		 */
		{
		  register u_int cw = tp->snd_cwnd;
		  register u_int incr = tp->t_maxseg;

		  if (cw > tp->snd_ssthresh)
		    incr = incr * incr / cw;
		  tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<<tp->snd_scale);
		}
		if (acked > so->so_snd.sb_cc) {
			tp->snd_wnd -= so->so_snd.sb_cc;
			sbdrop(&so->so_snd, (int )so->so_snd.sb_cc);
			ourfinisacked = 1;
		} else {
			sbdrop(&so->so_snd, acked);
			tp->snd_wnd -= acked;
			ourfinisacked = 0;
		}
		tp->snd_una = ti->ti_ack;
		if (SEQ_LT(tp->snd_nxt, tp->snd_una))
			tp->snd_nxt = tp->snd_una;

		switch (tp->t_state) {

		/*
		 * In FIN_WAIT_1 STATE in addition to the processing
		 * for the ESTABLISHED state if our FIN is now acknowledged
		 * then enter FIN_WAIT_2.
		 */
		case TCPS_FIN_WAIT_1:
			if (ourfinisacked) {
				/*
				 * If we can't receive any more
				 * data, then closing user can proceed.
				 * Starting the timer is contrary to the
				 * specification, but if we don't get a FIN
				 * we'll hang forever.
				 */
				if (so->so_state & SS_FCANTRCVMORE) {
					tp->t_timer[TCPT_2MSL] = TCP_MAXIDLE;
				}
				tp->t_state = TCPS_FIN_WAIT_2;
			}
			break;

	 	/*
		 * In CLOSING STATE in addition to the processing for
		 * the ESTABLISHED state if the ACK acknowledges our FIN
		 * then enter the TIME-WAIT state, otherwise ignore
		 * the segment.
		 */
		case TCPS_CLOSING:
			if (ourfinisacked) {
				tp->t_state = TCPS_TIME_WAIT;
				tcp_canceltimers(tp);
				tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
			}
			break;

		/*
		 * In LAST_ACK, we may still be waiting for data to drain
		 * and/or to be acked, as well as for the ack of our FIN.
		 * If our FIN is now acknowledged, delete the TCB,
		 * enter the closed state and return.
		 */
		case TCPS_LAST_ACK:
			if (ourfinisacked) {
				tp = tcp_close(tp);
				goto drop;
			}
			break;

		/*
		 * In TIME_WAIT state the only thing that should arrive
		 * is a retransmission of the remote FIN.  Acknowledge
		 * it and restart the finack timer.
		 */
		case TCPS_TIME_WAIT:
			tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
			goto dropafterack;
		}
	} /* switch(tp->t_state) */

step6:
	/*
	 * Update window information.
	 * Don't look at window if no ACK: TAC's send garbage on first SYN.
	 */
	if ((tiflags & TH_ACK) &&
	    (SEQ_LT(tp->snd_wl1, ti->ti_seq) ||
	    (tp->snd_wl1 == ti->ti_seq && (SEQ_LT(tp->snd_wl2, ti->ti_ack) ||
	    (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) {
		tp->snd_wnd = tiwin;
		tp->snd_wl1 = ti->ti_seq;
		tp->snd_wl2 = ti->ti_ack;
		if (tp->snd_wnd > tp->max_sndwnd)
			tp->max_sndwnd = tp->snd_wnd;
		needoutput = 1;
	}

	/*
	 * Process segments with URG.
	 */
	if ((tiflags & TH_URG) && ti->ti_urp &&
	    TCPS_HAVERCVDFIN(tp->t_state) == 0) {
		/*
		 * This is a kludge, but if we receive and accept
		 * random urgent pointers, we'll crash in
		 * soreceive.  It's hard to imagine someone
		 * actually wanting to send this much urgent data.
		 */
		if (ti->ti_urp + so->so_rcv.sb_cc > so->so_rcv.sb_datalen) {
			ti->ti_urp = 0;
			tiflags &= ~TH_URG;
			goto dodata;
		}
		/*
		 * If this segment advances the known urgent pointer,
		 * then mark the data stream.  This should not happen
		 * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since
		 * a FIN has been received from the remote side.
		 * In these states we ignore the URG.
		 *
		 * According to RFC961 (Assigned Protocols),
		 * the urgent pointer points to the last octet
		 * of urgent data.  We continue, however,
		 * to consider it to indicate the first octet
		 * of data past the urgent section as the original
		 * spec states (in one of two places).
		 */
		if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) {
			tp->rcv_up = ti->ti_seq + ti->ti_urp;
			so->so_urgc =  so->so_rcv.sb_cc +
				(tp->rcv_up - tp->rcv_nxt); /* -1; */
			tp->rcv_up = ti->ti_seq + ti->ti_urp;

		}
	} else
		/*
		 * If no out of band data is expected,
		 * pull receive urgent pointer along
		 * with the receive window.
		 */
		if (SEQ_GT(tp->rcv_nxt, tp->rcv_up))
			tp->rcv_up = tp->rcv_nxt;
dodata:

	/*
	 * Process the segment text, merging it into the TCP sequencing queue,
	 * and arranging for acknowledgment of receipt if necessary.
	 * This process logically involves adjusting tp->rcv_wnd as data
	 * is presented to the user (this happens in tcp_usrreq.c,
	 * case PRU_RCVD).  If a FIN has already been received on this
	 * connection then we just ignore the text.
	 */
	if ((ti->ti_len || (tiflags&TH_FIN)) &&
	    TCPS_HAVERCVDFIN(tp->t_state) == 0) {
		TCP_REASS(tp, ti, m, so, tiflags);
		/*
		 * Note the amount of data that peer has sent into
		 * our window, in order to estimate the sender's
		 * buffer size.
		 */
		len = so->so_rcv.sb_datalen - (tp->rcv_adv - tp->rcv_nxt);
	} else {
		m_free(m);
		tiflags &= ~TH_FIN;
	}

	/*
	 * If FIN is received ACK the FIN and let the user know
	 * that the connection is closing.
	 */
	if (tiflags & TH_FIN) {
		if (TCPS_HAVERCVDFIN(tp->t_state) == 0) {
			/*
			 * If we receive a FIN we can't send more data,
			 * set it SS_FDRAIN
                         * Shutdown the socket if there is no rx data in the
			 * buffer.
			 * soread() is called on completion of shutdown() and
			 * will got to TCPS_LAST_ACK, and use tcp_output()
			 * to send the FIN.
			 */
			sofwdrain(so);

			tp->t_flags |= TF_ACKNOW;
			tp->rcv_nxt++;
		}
		switch (tp->t_state) {

	 	/*
		 * In SYN_RECEIVED and ESTABLISHED STATES
		 * enter the CLOSE_WAIT state.
		 */
		case TCPS_SYN_RECEIVED:
		case TCPS_ESTABLISHED:
		  if(so->so_emu == EMU_CTL)        /* no shutdown on socket */
		    tp->t_state = TCPS_LAST_ACK;
		  else
		    tp->t_state = TCPS_CLOSE_WAIT;
		  break;

	 	/*
		 * If still in FIN_WAIT_1 STATE FIN has not been acked so
		 * enter the CLOSING state.
		 */
		case TCPS_FIN_WAIT_1:
			tp->t_state = TCPS_CLOSING;
			break;

	 	/*
		 * In FIN_WAIT_2 state enter the TIME_WAIT state,
		 * starting the time-wait timer, turning off the other
		 * standard timers.
		 */
		case TCPS_FIN_WAIT_2:
			tp->t_state = TCPS_TIME_WAIT;
			tcp_canceltimers(tp);
			tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
			break;

		/*
		 * In TIME_WAIT state restart the 2 MSL time_wait timer.
		 */
		case TCPS_TIME_WAIT:
			tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
			break;
		}
	}

	/*
	 * If this is a small packet, then ACK now - with Nagel
	 *      congestion avoidance sender won't send more until
	 *      he gets an ACK.
	 *
	 * See above.
	 */
	if (ti->ti_len && (unsigned)ti->ti_len <= 5 &&
	    ((struct tcpiphdr_2 *)ti)->first_char == (char)27) {
		tp->t_flags |= TF_ACKNOW;
	}

	/*
	 * Return any desired output.
	 */
	if (needoutput || (tp->t_flags & TF_ACKNOW)) {
		(void) tcp_output(tp);
	}
	return;

dropafterack:
	/*
	 * Generate an ACK dropping incoming segment if it occupies
	 * sequence space, where the ACK reflects our state.
	 */
	if (tiflags & TH_RST)
		goto drop;
	m_freem(m);
	tp->t_flags |= TF_ACKNOW;
	(void) tcp_output(tp);
	return;

dropwithreset:
	/* reuses m if m!=NULL, m_free() unnecessary */
	if (tiflags & TH_ACK)
		tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST);
	else {
		if (tiflags & TH_SYN) ti->ti_len++;
		tcp_respond(tp, ti, m, ti->ti_seq+ti->ti_len, (tcp_seq)0,
		    TH_RST|TH_ACK);
	}

	return;

drop:
	/*
	 * Drop space held by incoming segment and return.
	 */
	m_free(m);

	return;
}
Exemple #4
0
static int send_packet(void)
{
    netdev_hlist_t *hlist = NULL;
    netdev_hlist_t header1 = {NULL, NULL, NETDEV_PROTO_UNKNOWN, "header 1,", 9};
    netdev_hlist_t header2 = {NULL, NULL, NETDEV_PROTO_UNKNOWN, "header 2,", 9};
    char payload[] = "payload";

    netdev_hlist_add(&hlist, &header2);
    netdev_hlist_add(&hlist, &header1);

    printf("Sending \"%s%s%s\" to", (char *)header1.header, (char *)header2.header,
           payload);

    switch (dev_address_len) {
        case 1:
            do {
                uint8_t dest = NETDEV_TEST_RECEIVER;

                printf(" %" PRIu8 "\n", dest);
                dev->driver->send_data(dev, &dest, dev_address_len,
                                       hlist, payload, strlen(payload));
            }
            while (0);

            break;

        case 2:
            do {
                uint16_t dest = NETDEV_TEST_RECEIVER;

                printf(" %" PRIu16 "\n", dest);
                dev->driver->send_data(dev, &dest, dev_address_len,
                                       hlist, payload, strlen(payload));
            }
            while (0);

            break;

        case 3:
            do {
                uint16_t dest_int = HTONS(NETDEV_TEST_RECEIVER);
                uint8_t dest[dev_address_len];

                memset(dest, 0, dev_address_len - sizeof(uint16_t));
                memcpy(&(dest[dev_address_len - sizeof(uint16_t)]), &dest_int,
                       sizeof(uint16_t));

                for (size_t i = 0; i < dev_address_len; i++) {
                    printf(" %02x", dest[i]);
                }

                puts("");

                dev->driver->send_data(dev, &dest, dev_address_len,
                                       hlist, payload, strlen(payload));
            }
            while (0);

        case 4:
            do {
                uint32_t dest = NETDEV_TEST_RECEIVER;

                printf(" %" PRIu32 "\n", dest);
                dev->driver->send_data(dev, &dest, dev_address_len, hlist,
                                       payload, strlen(payload));
            }
            while (0);

            break;

        case 8:
            do {
                uint64_t dest = NETDEV_TEST_RECEIVER;

                printf(" %" PRIu64 "\n", dest);
                dev->driver->send_data(dev, &dest, dev_address_len,
                                       hlist, payload, strlen(payload));
            }
            while (0);

            break;

        default:
            do {
                uint32_t dest_int = HTONL(NETDEV_TEST_RECEIVER);
                uint8_t dest[dev_address_len];

                memset(dest, 0, dev_address_len - sizeof(uint32_t));
                memcpy(&(dest[dev_address_len - sizeof(uint32_t)]), &dest_int,
                       sizeof(uint32_t));

                for (size_t i = 0; i < dev_address_len; i++) {
                    printf(" %02x", dest[i]);
                }

                puts("");

                dev->driver->send_data(dev, &dest, dev_address_len,
                                       hlist, payload, strlen(payload));
            }
            while (0);

            break;
    }

    return 1;
}
Exemple #5
0
void NssDate::marshall()
{
    HTONL(tv_sec);
    HTONL(tv_usec);
}
Exemple #6
0
int thttpd_main(int argc, char **argv)
{
  int num_ready;
  int cnum;
  FAR struct connect_s *conn;
  FAR httpd_conn *hc;
  httpd_sockaddr sa;
  struct timeval tv;
#ifdef CONFIG_THTTPD_DIR
  int ret;
#endif

  nvdbg("THTTPD started\n");

  /* Setup host address */

#ifdef  CONFIG_NET_IPv6
#  error "IPv6 support not yet implemented"
#else
  sa.sin_family      = AF_INET;
  sa.sin_port        = HTONS(CONFIG_THTTPD_PORT);
  sa.sin_addr.s_addr = HTONL(CONFIG_THTTPD_IPADDR);
#endif

  /* Initialize the fdwatch package to handle all of the configured
   * socket descriptors
   */

  fw = fdwatch_initialize(CONFIG_NSOCKET_DESCRIPTORS);
  if (!fw)
    {
      ndbg("fdwatch initialization failure\n");
      exit(1);
    }

  /* Switch directories again if requested */

#ifdef CONFIG_THTTPD_DATADIR
  if (chdir(CONFIG_THTTPD_DATADIR) < 0)
    {
      ndbg("chdir to %s: %d\n", CONFIG_THTTPD_DATADIR, errno);
      exit(1);
    }
#endif

  /* Initialize the timer package */

  tmr_init();

  /* Initialize the HTTP layer */

  nvdbg("Calling httpd_initialize()\n");
  hs = httpd_initialize(&sa);
  if (!hs)
    {
      ndbg("httpd_initialize() failed\n");
      exit(1);
    }

  /* Set up the occasional timer */

  if (tmr_create(NULL, occasional, JunkClientData, CONFIG_THTTPD_OCCASIONAL_MSEC * 1000L, 1) == NULL)
    {
      ndbg("tmr_create(occasional) failed\n");
      exit(1);
    }

  /* Set up the idle timer */

  if (tmr_create(NULL, idle, JunkClientData, 5 * 1000L, 1) == NULL)
    {
      ndbg("tmr_create(idle) failed\n");
      exit(1);

    }

  /* Initialize our connections table */

  connects = NEW(struct connect_s, AVAILABLE_FDS);
  if (connects == NULL)
    {
      ndbg("Out of memory allocating a struct connect_s\n");
      exit(1);
    }

  for (cnum = 0; cnum < AVAILABLE_FDS; ++cnum)
    {
      connects[cnum].conn_state  = CNST_FREE;
      connects[cnum].next        = &connects[cnum + 1];
      connects[cnum].hc          = NULL;
    }

  connects[AVAILABLE_FDS-1].next = NULL;      /* End of link list */
  free_connections               = connects;  /* Beginning of the link list */

  if (hs != NULL)
    {
      if (hs->listen_fd != -1)
        {
          fdwatch_add_fd(fw, hs->listen_fd, NULL);
        }
    }

  /* Main loop */

  nvdbg("Entering the main loop\n");
  (void)gettimeofday(&tv, NULL);
  for (;;)
    {
      /* Do the fd watch */

      num_ready = fdwatch(fw, tmr_mstimeout(&tv));
      if (num_ready < 0)
        {
          if (errno == EINTR || errno == EAGAIN)
            {
              /* Not errors... try again */

              continue;
            }

          ndbg("fdwatch failed: %d\n", errno);
          exit(1);
        }

      (void)gettimeofday(&tv, NULL);

      if (num_ready == 0)
        {
          /* No fd's are ready - run the timers */

          tmr_run(&tv);
          continue;
        }

      /* Is it a new connection? */

      if (fdwatch_check_fd(fw, hs->listen_fd))
        {
          if (!handle_newconnect(&tv, hs->listen_fd))
            {
              /* Go around the loop and do another fdwatch, rather than
               * dropping through and processing existing connections.  New
               * connections always get priority.
               */

              continue;
            }
        }

      /* Find the connections that need servicing */

      while ((conn = (struct connect_s*)fdwatch_get_next_client_data(fw)) != (struct connect_s*)-1)
        {
          if (conn)
            {
              hc = conn->hc;
              if (fdwatch_check_fd(fw, hc->conn_fd))
                {
                  nvdbg("Handle conn_state %d\n", conn->conn_state);
                  switch (conn->conn_state)
                    {
                      case CNST_READING:
                        {
                          handle_read(conn, &tv);

                          /* If a GET request was received and a file is ready to
                           * be sent, then fall through to send the file.
                           */

                          if (conn->conn_state != CNST_SENDING)
                            {
                              break;
                            }
                        }

                      case CNST_SENDING:
                        {
                          /* Send a file -- this really should be performed on a
                           * separate thread to keep the serve from locking up during
                           * the write.
                           */

                          handle_send(conn, &tv);
                        }
                        break;

                      case CNST_LINGERING:
                        {
                          /* Linger close the connection */

                          handle_linger(conn, &tv);
                        }
                        break;
                    }
                }
            }
        }
      tmr_run(&tv);
    }

  /* The main loop terminated */

  shut_down();
  ndbg("Exiting\n");
  exit(0);
}
Exemple #7
0
int dds_publisher_main(int argc, char *argv[])
#endif
{
	DDS_DataWriterQos 	wr_qos;
	DDS_DataReaderQos	rd_qos;
	DDS_ReturnCode_t	error;	
	struct in_addr addr;

	/* Configure the network */
	/* Set up our host address */
	addr.s_addr = HTONL(CONFIG_EXAMPLES_UDP_IPADDR);
	netlib_sethostaddr("eth0", &addr);

	/* Set up the default router address */
	addr.s_addr = HTONL(CONFIG_EXAMPLES_UDP_DRIPADDR);
	netlib_setdraddr("eth0", &addr);

	/* Setup the subnet mask */
	addr.s_addr = HTONL(CONFIG_EXAMPLES_UDP_NETMASK);
	netlib_setnetmask("eth0", &addr);

  	/* Start the application */
  	printf("Network configured, starting DDS chat:\n");

	sprintf (user_name, ".pid.%u", getpid ());

	//DDS_entity_name ("ROS 2.0 embedded");
	DDS_entity_name ("Technicolor Chatroom");

#ifdef DDS_SECURITY
	if (cert_path || key_path || engine_id)
		enable_security ();
#endif
	part = DDS_DomainParticipantFactory_create_participant (domain_id, NULL, NULL, 0);
	if (!part) {
		printf ("Can't create participant!\r\n");
		exit (1);
	}
	if (verbose)
		printf ("DDS Domain Participant created.\r\n");

	ts = Imu_type_new ();
	if (!ts) {
		printf ("Can't create chat message type!\r\n");
		exit (1);
	}
	error = DDS_DynamicTypeSupport_register_type (ts, part, "simple_msgs::dds_::Imu_");
	if (error) {
		printf ("Can't register chat message type.\r\n");
		exit (1);
	}
	if (verbose)
		printf ("DDS Topic type ('%s') registered.\r\n", "simple_msgs::dds_::Imu_");

	topic = DDS_DomainParticipant_create_topic (part, "imu", "simple_msgs::dds_::Imu_", NULL, NULL, 0);
	if (!topic) {
		printf ("Can't register chat message type.\r\n");
		exit (1);
	}
	if (verbose)
		printf ("DDS imu Topic created.\r\n");

	td = DDS_DomainParticipant_lookup_topicdescription (part, "imu");
	if (!td) {
		printf ("Can't get topicdescription.\r\n");
		exit (1);
	}
	pub = DDS_DomainParticipant_create_publisher (part, NULL, NULL, 0);
	if (!pub) {
		printf ("DDS_DomainParticipant_create_publisher () failed!\r\n");
		exit (1);
	}
	DDS_Publisher_get_default_datawriter_qos (pub, &wr_qos);
#ifdef TRANSIENT_LOCAL
	wr_qos.durability.kind = DDS_TRANSIENT_LOCAL_DURABILITY_QOS;
#endif
#ifdef RELIABLE
	wr_qos.reliability.kind = DDS_RELIABLE_RELIABILITY_QOS;
#endif
#ifdef KEEP_ALL
	wr_qos.history.kind = DDS_KEEP_ALL_HISTORY_QOS;
	wr_qos.history.depth = DDS_LENGTH_UNLIMITED;
	wr_qos.resource_limits.max_samples_per_instance = HISTORY;
	wr_qos.resource_limits.max_instances = HISTORY * 10;
	wr_qos.resource_limits.max_samples = HISTORY * 4;
#else
	wr_qos.history.kind = DDS_KEEP_LAST_HISTORY_QOS;
	wr_qos.history.depth = HISTORY;
#endif
	/* Create a Data Writer. */
	dw = DDS_Publisher_create_datawriter (pub, topic, &wr_qos, NULL, 0);
	if (!dw) {
		printf ("Unable to create chat message writer.\r\n");
		exit (1);
	}
	if (verbose)
		printf ("DDS Chat message writer created.\r\n");

	sub = DDS_DomainParticipant_create_subscriber (part, NULL, NULL, 0); 
	if (!sub) {
		printf ("DDS_DomainParticipant_create_subscriber () returned an error!\r\n");
		exit (1);
	}
	if (verbose)
		printf ("DDS Subscriber created.\r\n");

	DDS_Subscriber_get_default_datareader_qos (sub, &rd_qos);
#ifdef TRANSIENT_LOCAL
	rd_qos.durability.kind = DDS_TRANSIENT_LOCAL_DURABILITY_QOS;
#endif
#ifdef RELIABLE
	rd_qos.reliability.kind = DDS_RELIABLE_RELIABILITY_QOS;
#endif
#ifdef KEEP_ALL
	rd_qos.history.kind = DDS_KEEP_ALL_HISTORY_QOS;
	rd_qos.history.depth = DDS_LENGTH_UNLIMITED;
	rd_qos.resource_limits.max_samples_per_instance = HISTORY;
	rd_qos.resource_limits.max_instances = HISTORY * 10;
	rd_qos.resource_limits.max_samples = HISTORY * 4;
#else
	rd_qos.history.kind = DDS_KEEP_LAST_HISTORY_QOS;
	rd_qos.history.depth = HISTORY;
#endif
	dr = DDS_Subscriber_create_datareader (sub, td, &rd_qos,
#ifndef WAITSETS
			 &msg_listener, DDS_DATA_AVAILABLE_STATUS);
#else
			 NULL, 0);
#endif
	if (!dr) {
		printf ("DDS_DomainParticipant_create_datareader () returned an error!\r\n");
		exit (1);
	}
	if (verbose)
		printf ("DDS Chat message reader created.\r\n");

#ifdef WAITSETS
	//start_imu_reader (dr);
#endif

	thread_create (rt2, dds_send_imu, dr);
	do_dds (dw);

#ifdef WAITSETS
	//stop_imu_reader (dr);
#endif
	DDS_Publisher_delete_datawriter (pub, dw);
	usleep (200000);
	error = DDS_DomainParticipant_delete_contained_entities (part);
	if (verbose)
		printf ("DDS Entities deleted (error = %u).\r\n", error);

	Imu_type_free (ts);
	if (verbose)
		printf ("Chat Type deleted.\r\n");

	error = DDS_DomainParticipantFactory_delete_participant (part);
	if (verbose)
		printf ("DDS Participant deleted (error = %u).\r\n", error);

#ifdef DDS_SECURITY
	if (cert_path || key_path || engine_id)
		cleanup_security ();
#endif
	return (0);
}
Exemple #8
0
int thttp_main(int argc, char *argv[])
{
  struct in_addr addr;
#ifdef CONFIG_EXAMPLE_THTTPD_NOMAC
  uint8_t mac[IFHWADDRLEN];
#endif
  char *thttpd_argv = "thttpd";
  int ret;

  /* Configure SLIP */

#ifdef CONFIG_NET_SLIP
  ret = slip_initialize(SLIP_DEVNO, CONFIG_NET_SLIPTTY);
  if (ret < 0)
    {
      message("ERROR: SLIP initialization failed: %d\n", ret);
      exit(1);
    }
#endif

/* Many embedded network interfaces must have a software assigned MAC */

#ifdef CONFIG_EXAMPLE_THTTPD_NOMAC
  message("Assigning MAC\n");

  mac[0] = 0x00;
  mac[1] = 0xe0;
  mac[2] = 0xde;
  mac[3] = 0xad;
  mac[4] = 0xbe;
  mac[5] = 0xef;
  uip_setmacaddr(NET_DEVNAME, mac);
#endif

  /* Set up our host address */

  message("Setup network addresses\n");
  addr.s_addr = HTONL(CONFIG_THTTPD_IPADDR);
  uip_sethostaddr(NET_DEVNAME, &addr);

  /* Set up the default router address */

  addr.s_addr = HTONL(CONFIG_EXAMPLE_THTTPD_DRIPADDR);
  uip_setdraddr(NET_DEVNAME, &addr);

  /* Setup the subnet mask */

  addr.s_addr = HTONL(CONFIG_EXAMPLE_THTTPD_NETMASK);
  uip_setnetmask(NET_DEVNAME, &addr);

  /* Initialize the NXFLAT binary loader */

  message("Initializing the NXFLAT binary loader\n");
  ret = nxflat_initialize();
  if (ret < 0)
    {
      message("ERROR: Initialization of the NXFLAT loader failed: %d\n", ret);
      exit(2);
    }

  /* Create a ROM disk for the ROMFS filesystem */

  message("Registering romdisk\n");
  ret = romdisk_register(0, (uint8_t*)romfs_img, NSECTORS(romfs_img_len), SECTORSIZE);
  if (ret < 0)
    {
      message("ERROR: romdisk_register failed: %d\n", ret);
      nxflat_uninitialize();
      exit(1);
    }

  /* Mount the file system */

  message("Mounting ROMFS filesystem at target=%s with source=%s\n",
         MOUNTPT, ROMFSDEV);

  ret = mount(ROMFSDEV, MOUNTPT, "romfs", MS_RDONLY, NULL);
  if (ret < 0)
    {
      message("ERROR: mount(%s,%s,romfs) failed: %s\n",
              ROMFSDEV, MOUNTPT, errno);
      nxflat_uninitialize();
    }

  /* Start THTTPD.  At present, symbol table info is passed via global variables */

  g_thttpdsymtab   = exports;
  g_thttpdnsymbols = NEXPORTS;

  message("Starting THTTPD\n");
  msgflush();
  thttpd_main(1, &thttpd_argv);
  message("THTTPD terminated\n");
  msgflush();
  return 0;
}
Exemple #9
0
/*
int init_send_file(file_desc *f_desc)
{
    return init_send_list(f_desc);
    
}
*/
int get_file_info(char *path, unsigned char **buf)
{
    DIR *dir = NULL;
    FILE *fp = NULL;
    struct dirent *ent = NULL;
    struct stat file_stat;
    unsigned short name_len = 0;
    unsigned short total_len = 0;
    unsigned int mod_time = 0;
    unsigned int file_size = 0;
    unsigned int offset = 0;
    unsigned char file_count = 0;
    char path_buf[128];
    
    dir = opendir(path);
    while (NULL != (ent=readdir(dir)))
    {
        if(strcmp(ent->d_name, "..") == 0 || strcmp(ent->d_name, ".") == 0)
            continue;
        memset(path_buf, 0, 128);
        strcpy(path_buf + strlen(strcpy(path_buf, path)), ent->d_name);
        if(fp = fopen(path_buf, "r"))
        {
            if(get_file_size(fp) <= 0)
            {
                fclose(fp);
                fp = NULL;
                continue;
            }
            name_len = strlen(ent->d_name);
            total_len += FILE_INFO_LEN + name_len;
            file_count++;
            fclose(fp);
            fp = NULL;
        }
    }
    closedir(dir);
    dir = NULL;
    
    //n files and count(n)
    if ((*buf = (unsigned char *)t_malloc(total_len + 1)) == NULL)
        return -1;
    
    dir=opendir(path);
    /* 1 for file count */
    (*buf)[0] = file_count;
    offset++;

    while (NULL != (ent=readdir(dir)))
    {
        if(strcmp(ent->d_name, "..") == 0 || strcmp(ent->d_name, ".") == 0)
            continue;
        name_len = strlen(ent->d_name);
        memset(path_buf, 0, 128);

        strcpy(path_buf + strlen(strcpy(path_buf, path)), ent->d_name);
        /*     mod time = st_mtime
            access time = st_atime*/
       
       if(stat(path_buf, &file_stat) != -1)
        {
            mod_time = HTONL((unsigned int)(file_stat.st_mtime));
            if(file_stat.st_size <= 0)
                continue;
            file_size = HTONL((unsigned int)file_stat.st_size);
            memcpy((*buf) + offset, (unsigned char *)(&file_size), 4);
            offset += 4;
            memcpy((*buf) + offset, (unsigned char *)(&mod_time), 4);
            offset += 4;
            memcpy((*buf) + offset, (char *)&name_len, 1);
            offset += 1;
            memcpy((*buf) + offset, ent->d_name, name_len);
            offset += name_len;
        }
    } 
    closedir(dir);
    dir = NULL;
    
    return offset;
}
Exemple #10
0
void time_functions(void)
/* Perform time dependend functions: router solicitation, router advert. */
{
	if (now >= next_sol) {
		char buf[sizeof(ip_hdr_t) + 8];
		ip_hdr_t *ip_hdr;
		icmp_hdr_t *icmp_hdr;

		if (sol_retries == 0) {
			/* Stop soliciting. */
			next_sol= NEVER;
#if !__minix_vmd
			/* Switch to RIP if no router responded. */
			if (table_size == 0) {
				do_rip= 1;
				do_rdisc= 0;
			}
#endif
			return;
		}

		/* Broadcast a router solicitation to find a router. */
		ip_hdr= (ip_hdr_t *) buf;
		icmp_hdr= (icmp_hdr_t *) (ip_hdr + 1);

		ip_hdr->ih_vers_ihl= 0x45;
#ifdef __NBSD_LIBC
		ip_hdr->ih_dst= htonl(0xFFFFFFFFL);
#else
		ip_hdr->ih_dst= HTONL(0xFFFFFFFFL);
#endif
		icmp_hdr->ih_type= ICMP_TYPE_ROUTE_SOL;
		icmp_hdr->ih_code= 0;
		icmp_hdr->ih_chksum= 0;
		icmp_hdr->ih_hun.ihh_unused= 0;
		icmp_hdr->ih_chksum= ~oneC_sum(0, icmp_hdr, 8);

		if (debug) printf("Broadcasting router solicitation\n");

		if (write(irdp_fd, buf, sizeof(buf)) < 0)
			fatal("sending router solicitation failed");

		/* Schedule the next packet. */
		next_sol= now + SOLICITATION_INTERVAL;

		sol_retries--;
	}

	if (now >= next_advert) {
		/* Advertize routes to the local host (normally), or
		 * broadcast them (to keep bad hosts up.)
		 */

#ifdef __NBSD_LIBC
		advertize(bcast ? htonl(0xFFFFFFFFL) : htonl(0x7F000001L));
#else
		advertize(bcast ? HTONL(0xFFFFFFFFL) : HTONL(0x7F000001L));
#endif
		next_advert= now + MaxAdvertisementInterval;
#if !__minix_vmd
		/* Make sure we are listening to RIP now. */
		do_rip= 1;
		do_rdisc= 0;
#endif
	}
}
Exemple #11
0
int main(int argc, char **argv)
{
	int i;
	struct servent *service;
	udpport_t route_port;
	nwio_udpopt_t udpopt;
	nwio_ipopt_t ipopt;
	asynchio_t asyn;
	time_t timeout;
	struct timeval tv;
	struct sigaction sa;
	char *offset_arg, *offset_end;
	long arg;

	udp_device= ip_device= nil;
	offset_arg= nil;

	for (i = 1; i < argc && argv[i][0] == '-'; i++) {
		char *p= argv[i] + 1;

		if (p[0] == '-' && p[1] == 0) { i++; break; }

		while (*p != 0) {
			switch (*p++) {
			case 'U':
				if (udp_device != nil) usage();
				if (*p == 0) {
					if (++i == argc) usage();
					p= argv[i];
				}
				udp_device= p;
				p= "";
				break;
			case 'I':
				if (ip_device != nil) usage();
				if (*p == 0) {
					if (++i == argc) usage();
					p= argv[i];
				}
				ip_device= p;
				p= "";
				break;
			case 'o':
				if (offset_arg != nil) usage();
				if (*p == 0) {
					if (++i == argc) usage();
					p= argv[i];
				}
				offset_arg= p;
				p= "";
				break;
			case 'b':
				bcast= 1;
				break;
			case 's':
				/*obsolete*/
				break;
			case 'd':
				debug= 1;
				break;
			default:
				usage();
			}
		}
	}
	if (i != argc) usage();

	/* Debug level signals. */
	sa.sa_handler= sig_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags= 0;
	sigaction(SIGUSR1, &sa, nil);
	sigaction(SIGUSR2, &sa, nil);

	if (udp_device == nil && (udp_device= getenv("UDP_DEVICE")) == nil)
		udp_device= UDP_DEVICE;

	if (ip_device == nil && (ip_device= getenv("IP_DEVICE")) == nil)
		ip_device= IP_DEVICE;

	if (offset_arg == nil) {
		priority_offset= PRIO_OFF_DEF;
	} else {
		arg= strtol(offset_arg, &offset_end, 0);
		if (*offset_end != 0 || (priority_offset= arg) != arg) usage();
	}

	if ((service= getservbyname("route", "udp")) == nil) {
		fprintf(stderr,
	"irdpd: unable to look up the port number for the 'route' service\n");
		exit(1);
	}

	route_port= (udpport_t) service->s_port;

	if ((rip_fd= open(udp_device, O_RDWR)) < 0) fatal(udp_device);

	udpopt.nwuo_flags= NWUO_COPY | NWUO_LP_SET | NWUO_DI_LOC
		| NWUO_EN_BROAD | NWUO_RP_SET | NWUO_RA_ANY | NWUO_RWDATALL
		| NWUO_DI_IPOPT;
	udpopt.nwuo_locport= route_port;
	udpopt.nwuo_remport= route_port;
	if (ioctl(rip_fd, NWIOSUDPOPT, &udpopt) < 0)
		fatal("setting UDP options failed");

	if ((irdp_fd= open(ip_device, O_RDWR)) < 0) fatal(ip_device);

	ipopt.nwio_flags= NWIO_COPY | NWIO_EN_LOC | NWIO_EN_BROAD
			| NWIO_REMANY | NWIO_PROTOSPEC
			| NWIO_HDR_O_SPEC | NWIO_RWDATALL;
	ipopt.nwio_tos= 0;
	ipopt.nwio_ttl= 1;
	ipopt.nwio_df= 0;
	ipopt.nwio_hdropt.iho_opt_siz= 0;
#ifdef __NBSD_LIBC
	ipopt.nwio_rem= htonl(0xFFFFFFFFL);
#else
	ipopt.nwio_rem= HTONL(0xFFFFFFFFL);
#endif
	ipopt.nwio_proto= IPPROTO_ICMP;

	if (ioctl(irdp_fd, NWIOSIPOPT, &ipopt) < 0)
		fatal("can't configure ICMP channel");

	asyn_init(&asyn);

	while (1) {
		ssize_t r;

		if (do_rip) {
			/* Try a RIP read. */
			r= asyn_read(&asyn, rip_fd, rip_buf, sizeof(rip_buf));
			if (r < 0) {
				if (errno == EIO) fatal(udp_device);
				if (errno != EINPROGRESS) report(udp_device);
			} else {
				now= time(nil);
				rip_incoming(r);
			}
		}

		if (do_rdisc) {
			/* Try an IRDP read. */
			r= asyn_read(&asyn, irdp_fd, irdp_buf,
							sizeof(irdp_buf));
			if (r < 0) {
				if (errno == EIO) fatal(ip_device);
				if (errno != EINPROGRESS) report(ip_device);
			} else {
				now= time(nil);
				irdp_incoming(r);
			}
		}
		fflush(stdout);

		/* Compute the next wakeup call. */
		timeout= next_sol < next_advert ? next_sol : next_advert;

		/* Wait for a RIP or IRDP packet or a timeout. */
		tv.tv_sec= timeout;
		tv.tv_usec= 0;
		if (asyn_wait(&asyn, 0, timeout == NEVER ? nil : &tv) < 0) {
			/* Timeout? */
			if (errno != EINTR && errno != EAGAIN)
				fatal("asyn_wait()");
			now= time(nil);
			time_functions();
		}
	}
}
/*
funcational description:
schedual module ,extract some information about this flow
author:jzheng
date:2014-06-01
*/
int sched_module_classify(struct rte_mbuf*pktbuf,struct sched_stat_str *lpstat)
{
	dbg_local struct ether_hdr *eh;
	dbg_local struct ether_arp *ea;
	dbg_local struct iphdr *iph;
	dbg_local uint32_t uiSIP;
	dbg_local uint32_t uiDIP;
	
	memset(lpstat,0x0,sizeof(struct sched_stat_str));//reset all fields
	lpstat->iport_in=GETLONIB(pktbuf->pkt.in_port);
	lpstat->iport_out=GETHINIB(pktbuf->pkt.in_port);
	lpstat->iDiscard=FALSE;
	if(gPortParaConf[lpstat->iport_in].port_grp!=gPortParaConf[lpstat->iport_out].port_grp){
		lpstat->enDir=TRAFFIC_DIR_UNDEF;
	}else{
		lpstat->enDir=TRAFFIC_DIR_UNDEF;
		
		switch(gPortParaConf[lpstat->iport_in].ePortRole)
		{
			case PORT_ROLE_INTERIOR:
				if(gPortParaConf[lpstat->iport_out].ePortRole==PORT_ROLE_EXTERIOR)
					lpstat->enDir=TRAFFIC_DIR_OUTBOUND;
				break;
			case PORT_ROLE_EXTERIOR:
				if(gPortParaConf[lpstat->iport_out].ePortRole==PORT_ROLE_INTERIOR)
					lpstat->enDir=TRAFFIC_DIR_INBOUND;
				break;
			case PORT_ROLE_PE:
				if(gPortParaConf[lpstat->iport_out].ePortRole==PORT_ROLE_CE)
					lpstat->enDir=TRAFFIC_DIR_INBOUND;
				break;
			case PORT_ROLE_CE:
				if(gPortParaConf[lpstat->iport_out].ePortRole==PORT_ROLE_PE)
					lpstat->enDir=TRAFFIC_DIR_OUTBOUND;
				break;
		}
	}
	eh=rte_pktmbuf_mtod(pktbuf,struct ether_hdr *);
	lpstat->iPayloadLength=pktbuf->pkt.pkt_len-sizeof(struct ether_hdr);//payload length do not include datalink layer header
	switch(HTONS(eh->ether_type))
	{
		case ETH_TYPE_ARP:
			ea=(struct ether_arp *)(sizeof(struct ether_hdr)+(char*)eh);
			uiSIP=HTONL(MAKEUINT32FROMUINT8ARR(ea->arp_spa));
			uiDIP=HTONL(MAKEUINT32FROMUINT8ARR(ea->arp_tpa));
			lpstat->iPaketType=ETH_TYPE_ARP;
			break;
		case ETH_TYPE_IP:
			iph=(struct iphdr *)(sizeof(struct ether_hdr)+(char*)eh);
			uiSIP=HTONL(iph->ip_src);
			uiDIP=HTONL(iph->ip_dst);
			lpstat->iPaketType=ETH_TYPE_IP;
			break;
		default:
			uiSIP=uiDIP=0;
			lpstat->iPaketType=HTONS(eh->ether_type);
			break;
	}
	switch(lpstat->enDir)
	{
		case TRAFFIC_DIR_INBOUND:
			lpstat->iFlowIdx=find_net_entry(uiDIP,TRUE);
			break;
		case TRAFFIC_DIR_OUTBOUND:
			lpstat->iFlowIdx=find_net_entry(uiSIP,TRUE);
			break;
		default:
			lpstat->iDiscard=TRUE;
			lpstat->iFlowIdx=-1;
			break;
	}
	return 0;	
}
void send_client(void)
{
#ifdef CONFIG_EXAMPLES_UDP_IPv6
  struct sockaddr_in6 server;
#else
  struct sockaddr_in server;
#endif
  unsigned char outbuf[SENDSIZE];
  socklen_t addrlen;
  int sockfd;
  int nbytes;
  int offset;

  /* Create a new UDP socket */

  sockfd = socket(PF_INETX, SOCK_DGRAM, 0);
  if (sockfd < 0)
    {
      printf("client socket failure %d\n", errno);
      exit(1);
    }

  /* Then send and receive 256 messages */

  for (offset = 0; offset < 256; offset++)
    {
      /* Set up the output buffer */

      fill_buffer(outbuf, offset);

      /* Set up the server address */

#ifdef CONFIG_EXAMPLES_UDP_IPv6
      server.sin6_family            = AF_INET6;
      server.sin6_port              = HTONS(PORTNO);

      server.sin6_addr.s6_addr16[0] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_1);
      server.sin6_addr.s6_addr16[1] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_2);
      server.sin6_addr.s6_addr16[2] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_3);
      server.sin6_addr.s6_addr16[3] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_4);
      server.sin6_addr.s6_addr16[4] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_5);
      server.sin6_addr.s6_addr16[5] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_6);
      server.sin6_addr.s6_addr16[6] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_7);
      server.sin6_addr.s6_addr16[7] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_8);

      addrlen                       = sizeof(struct sockaddr_in6);
#else
      server.sin_family             = AF_INET;
      server.sin_port               = HTONS(PORTNO);
      server.sin_addr.s_addr        = HTONL(CONFIG_EXAMPLES_UDP_SERVERIP);

      addrlen                       = sizeof(struct sockaddr_in);
#endif

      /* Send the message */

      printf("client: %d. Sending %d bytes\n", offset, SENDSIZE);
      nbytes = sendto(sockfd, outbuf, SENDSIZE, 0,
                      (struct sockaddr*)&server, addrlen);
      printf("client: %d. Sent %d bytes\n", offset, nbytes);

      if (nbytes < 0)
        {
          printf("client: %d. sendto failed: %d\n", offset, errno);
          close(sockfd);
          exit(-1);
        }
      else if (nbytes != SENDSIZE)
        {
          printf("client: %d. Bad send length: %d Expected: %d\n",
                 offset, nbytes, SENDSIZE);
          close(sockfd);
          exit(-1);
        }

      /* Now, sleep a bit.  No packets should be dropped due to overrunning
       * the server.
       */

      sleep(2);
    }
  close(sockfd);
}
NTSTATUS
DispatchRequest (
	IN PPRIMARY_SESSION	PrimarySession
	)
{
	NTSTATUS				status;
	IN PNDFS_REQUEST_HEADER	ndfsRequestHeader;


	ASSERT( NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2) < PrimarySession->SessionContext.SessionSlotCount );

	RtlCopyMemory( PrimarySession->Thread.SessionSlot[NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2)].RequestMessageBuffer,
				   &PrimarySession->Thread.NdfsRequestHeader,
				   sizeof(NDFS_REQUEST_HEADER) );

	ndfsRequestHeader 
		= (PNDFS_REQUEST_HEADER)PrimarySession->Thread.SessionSlot[NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2)].RequestMessageBuffer;
   
	ASSERT (PrimarySession->ReceiveOverlapped.Request[0].IoStatusBlock.Information == sizeof(NDFS_REQUEST_HEADER) );

    SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_NOISE,
				   ("DispatchRequest: PrimarySession = %p, ndfsRequestHeader->Command = %d\n", 
				   PrimarySession, ndfsRequestHeader->Command) );

	
	switch (ndfsRequestHeader->Command) {

	case NDFS_COMMAND_NEGOTIATE: {

		PNDFS_REQUEST_NEGOTIATE	ndfsRequestNegotiate;
		PNDFS_REPLY_HEADER		ndfsReplyHeader;
		PNDFS_REPLY_NEGOTIATE	ndfsReplyNegotiate;
		
		
		if (PrimarySession->Thread.SessionState != SESSION_CLOSE) {

			ASSERT( LFS_BUG );
			status = STATUS_UNSUCCESSFUL;

			break;
		}
		
		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) == sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_REQUEST_NEGOTIATE) );
		ndfsRequestNegotiate = (PNDFS_REQUEST_NEGOTIATE)(ndfsRequestHeader+1);
	
		status = RecvMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->RecvNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsRequestNegotiate,
							  sizeof(NDFS_REQUEST_NEGOTIATE) );
	

		if (status != STATUS_SUCCESS) {

			ASSERT( LFS_BUG );

			break;
		}

		PrimarySession->SessionContext.Flags = ndfsRequestNegotiate->Flags;
		ndfsReplyHeader = (PNDFS_REPLY_HEADER)(ndfsRequestNegotiate+1);

		RtlCopyMemory( ndfsReplyHeader->Protocol, NDFS_PROTOCOL, sizeof(ndfsReplyHeader->Protocol) );
		ndfsReplyHeader->Status		= NDFS_SUCCESS;
		ndfsReplyHeader->Flags	    = PrimarySession->SessionContext.Flags;
		ndfsReplyHeader->Uid2		= 0;
		ndfsReplyHeader->Tid2		= 0;
		ndfsReplyHeader->Mid2		= 0;
		ndfsReplyHeader->MessageSize4 = HTONL((UINT32)(sizeof(NDFS_REPLY_HEADER)+sizeof(NDFS_REPLY_NEGOTIATE)));

		ndfsReplyNegotiate = (PNDFS_REPLY_NEGOTIATE)(ndfsReplyHeader+1);

		if (NTOHS(ndfsRequestNegotiate->NdfsMajorVersion2) == NDFS_PROTOCOL_MAJOR_3 && 
			NTOHS(ndfsRequestNegotiate->NdfsMinorVersion2) == NDFS_PROTOCOL_MINOR_0 && 
			NTOHS(ndfsRequestNegotiate->OsMajorType2) == OS_TYPE_WINDOWS			&& 
			NTOHS(ndfsRequestNegotiate->OsMinorType2) == OS_TYPE_WINXP) {

			PrimarySession->SessionContext.NdfsMajorVersion = NTOHS(ndfsRequestNegotiate->NdfsMajorVersion2);
			PrimarySession->SessionContext.NdfsMinorVersion = NTOHS(ndfsRequestNegotiate->NdfsMinorVersion2);

			ndfsReplyNegotiate->Status = NDFS_NEGOTIATE_SUCCESS;
			ndfsReplyNegotiate->NdfsMajorVersion2 = HTONS(PrimarySession->SessionContext.NdfsMajorVersion);
			ndfsReplyNegotiate->NdfsMinorVersion2 = HTONS(PrimarySession->SessionContext.NdfsMinorVersion);
			ndfsReplyNegotiate->OsMajorType2 = HTONS(OS_TYPE_WINDOWS);	
			ndfsReplyNegotiate->OsMinorType2 = HTONS(OS_TYPE_WINXP);
			ndfsReplyNegotiate->SessionKey4 = HTONL(PrimarySession->SessionContext.SessionKey);
			ndfsReplyNegotiate->MaxBufferSize4 = HTONL(PrimarySession->SessionContext.PrimaryMaxDataSize);

			RtlCopyMemory( ndfsReplyNegotiate->ChallengeBuffer,
						   &PrimarySession,
						   sizeof(PPRIMARY_SESSION) );

			ndfsReplyNegotiate->ChallengeLength2 = HTONS((UINT16)(sizeof(PPRIMARY_SESSION)));

			PrimarySession->Thread.SessionState = SESSION_NEGOTIATE;
		
		} else {

			ndfsReplyNegotiate->Status = NDFS_NEGOTIATE_UNSUCCESSFUL;
		}

		status = SendMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->SendNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsReplyHeader,
							  NTOHL(ndfsReplyHeader->MessageSize4) );

		if (status != STATUS_SUCCESS) {

			break;
		}

		break;
	
	}

	case NDFS_COMMAND_SETUP: {

		PNDFS_REQUEST_SETUP	ndfsRequestSetup;
		PNDFS_REPLY_HEADER	ndfsReplyHeader;
		PNDFS_REPLY_SETUP	ndfsReplySetup;

		UINT8					ndfsReplySetupStatus;

		unsigned char		idData[1];
		MD5_CTX				context;
		UINT8				responseBuffer[16]; 
		
		
		if (PrimarySession->Thread.SessionState != SESSION_NEGOTIATE) {

			ASSERT( LFS_BUG );
			status = STATUS_UNSUCCESSFUL;

			break;
		}
		
		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) == sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_REQUEST_SETUP) );
		ndfsRequestSetup = (PNDFS_REQUEST_SETUP)(ndfsRequestHeader+1);

		status = RecvMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->RecvNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsRequestSetup,
							  sizeof(NDFS_REQUEST_SETUP) );
	
		if (status != STATUS_SUCCESS) {

			ASSERT( LFS_BUG );

			break;
		}
	
		do {

			ASSERT( PrimarySession->NetdiskPartition == NULL );

			if (NTOHL(ndfsRequestSetup->SessionKey4) != PrimarySession->SessionContext.SessionKey) {

				ndfsReplySetupStatus = NDFS_SETUP_UNSUCCESSFUL;				
				break;
			}

			RtlCopyMemory( PrimarySession->NetDiskAddress.Node,
						   ndfsRequestSetup->NetdiskNode,
						   6 );
			
			PrimarySession->NetDiskAddress.Port = ndfsRequestSetup->NetdiskPort2;//HTONS(ndfsRequestSetup->NetDiskPort);
			PrimarySession->UnitDiskNo = NTOHS(ndfsRequestSetup->UnitDiskNo2);
			RtlCopyMemory( PrimarySession->NdscId, ndfsRequestSetup->NdscId, NDSC_ID_LENGTH);
				
			if (PrimarySession->SessionContext.NdfsMinorVersion == NDFS_PROTOCOL_MINOR_0) {

				status = NetdiskManager_GetPrimaryPartition( GlobalLfs.NetdiskManager,
															 PrimarySession,
															 &PrimarySession->NetDiskAddress,
															 PrimarySession->UnitDiskNo,
															 PrimarySession->NdscId,
															 NULL,
															 PrimarySession->IsLocalAddress,
															 &PrimarySession->NetdiskPartition,
															 &PrimarySession->NetdiskPartitionInformation,
															 &PrimarySession->FileSystemType );

				SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
							   ("PRIM:SETUP:MIN1 PrimarySession->NetdiskPartition = %p netDiskPartitionInfo.StartingOffset = %I64x\n",
								 PrimarySession->NetdiskPartition, PrimarySession->StartingOffset.QuadPart) );

				if (status != STATUS_SUCCESS) {

					ndfsReplySetupStatus = NDFS_SETUP_UNSUCCESSFUL;
					break;
				}
			
			} else {

				NDAS_BUGON( FALSE );
			}

			
			MD5Init( &context );

			/* id byte */
			idData[0] = (unsigned char)PrimarySession->SessionContext.SessionKey;
			
			MD5Update( &context, idData, 1 );

			MD5Update( &context, 
					   PrimarySession->NetdiskPartitionInformation.NetdiskInformation.Password, 
					   8 );

			MD5Update( &context, &(UCHAR)PrimarySession, sizeof(PPRIMARY_SESSION) );
			MD5Final( responseBuffer, &context );

			if (!RtlEqualMemory(ndfsRequestSetup->ResponseBuffer,
								responseBuffer,
								16)) {

				NDAS_BUGON( LFS_BUG );
				ndfsReplySetupStatus = NDFS_SETUP_UNSUCCESSFUL;				
				break;
			}

			ndfsReplySetupStatus = NDFS_SETUP_SUCCESS;
		
		} while(0);

		ndfsReplyHeader = (PNDFS_REPLY_HEADER)(ndfsRequestSetup+1);
			
		RtlCopyMemory( ndfsReplyHeader->Protocol, NDFS_PROTOCOL, sizeof(ndfsReplyHeader->Protocol) );
		
		ndfsReplyHeader->Status		= NDFS_SUCCESS;
		ndfsReplyHeader->Flags	    = 0;
		ndfsReplyHeader->Uid2		= 0;
		ndfsReplyHeader->Tid2		= 0;
		ndfsReplyHeader->Mid2		= 0;
		ndfsReplyHeader->MessageSize4 = HTONL((UINT32)(sizeof(NDFS_REPLY_HEADER)+sizeof(NDFS_REPLY_SETUP)));

		if (ndfsReplySetupStatus == NDFS_SETUP_SUCCESS) {

			if (NTOHL(ndfsRequestSetup->MaxBufferSize4)) {

				if (PrimarySession->NetdiskPartition->FileSystemType == LFS_FILE_SYSTEM_NDAS_NTFS ||
					GlobalLfs.NdasFatRwIndirect == FALSE && PrimarySession->NetdiskPartition->FileSystemType == LFS_FILE_SYSTEM_NDAS_FAT ||
					GlobalLfs.NdasNtfsRwIndirect == FALSE && PrimarySession->NetdiskPartition->FileSystemType == LFS_FILE_SYSTEM_NDAS_NTFS) {

					PrimarySession->SessionContext.SecondaryMaxDataSize = NTOHL(ndfsRequestSetup->MaxBufferSize4);
				
				} else {

					PrimarySession->SessionContext.SecondaryMaxDataSize = 
						(NTOHL(ndfsRequestSetup->MaxBufferSize4) <= PrimarySession->SessionContext.SecondaryMaxDataSize) ? 
							   NTOHL(ndfsRequestSetup->MaxBufferSize4) : PrimarySession->SessionContext.SecondaryMaxDataSize;
				}

				//
				//	Initialize transport context for traffic control
				//

				InitTransCtx(&PrimarySession->Thread.TransportCtx, PrimarySession->SessionContext.SecondaryMaxDataSize);
			}

			SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
						   ("NDFS_COMMAND_SETUP: PrimarySession->NetdiskPartition->FileSystemType = %d "  
						    "ndfsRequestSetup->MaxBufferSize = %x PrimaryMaxDataSize:%x SecondaryMaxDataSize:%x \n",
							PrimarySession->NetdiskPartition->FileSystemType, NTOHL(ndfsRequestSetup->MaxBufferSize4), 
							PrimarySession->SessionContext.PrimaryMaxDataSize,
							PrimarySession->SessionContext.SecondaryMaxDataSize) );

			ndfsReplyHeader->Uid2 = HTONS(PrimarySession->SessionContext.Uid);
			ndfsReplyHeader->Tid2 = HTONS(PrimarySession->SessionContext.Tid);
		
		} else {

			if (PrimarySession->NetdiskPartition) {

				NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager, 
													   PrimarySession,
													   PrimarySession->NetdiskPartition, 
													   PrimarySession->IsLocalAddress );

				PrimarySession->NetdiskPartition = NULL;
			}
		}

		ndfsReplySetup = (PNDFS_REPLY_SETUP)(ndfsReplyHeader+1);
		ndfsReplySetup->Status = ndfsReplySetupStatus;

		status = SendMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->SendNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsReplyHeader,
							  NTOHL(ndfsReplyHeader->MessageSize4) );

		if (status != STATUS_SUCCESS) {

			break;
		}

		if (ndfsReplySetupStatus == NDFS_SETUP_SUCCESS)
			PrimarySession->Thread.SessionState = SESSION_SETUP;
		
		break;
	}

	case NDFS_COMMAND_TREE_CONNECT:{

		PNDFS_REQUEST_TREE_CONNECT	ndfsRequestTreeConnect;
		PNDFS_REPLY_HEADER			ndfsReplyHeader;
		PNDFS_REPLY_TREE_CONNECT	ndfsReplyTreeConnect;
	
		UINT8							ndfsReplyTreeConnectStatus;
		
		
		if (!(PrimarySession->Thread.SessionState == SESSION_SETUP && \
			  NTOHS(ndfsRequestHeader->Uid2) == PrimarySession->SessionContext.Uid)) {

			ASSERT( LFS_BUG );
			status = STATUS_UNSUCCESSFUL;

			break;
		}
		
		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) == sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_REQUEST_TREE_CONNECT) );
		ndfsRequestTreeConnect = (PNDFS_REQUEST_TREE_CONNECT)(ndfsRequestHeader+1);

		status = RecvMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->RecvNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsRequestTreeConnect,
							  sizeof(NDFS_REQUEST_TREE_CONNECT) );
	
		if (status != STATUS_SUCCESS) {

			ASSERT( LFS_BUG );

			break;
		}
		
		do {

			NTSTATUS			getVolumeInformationStatus;
			PNETDISK_PARTITION	netdiskPartition;


			ndfsReplyHeader = (PNDFS_REPLY_HEADER)(ndfsRequestTreeConnect+1);

			RtlCopyMemory( ndfsReplyHeader->Protocol, NDFS_PROTOCOL, sizeof(ndfsReplyHeader->Protocol) );

			ndfsReplyHeader->Status		= NDFS_SUCCESS;
			ndfsReplyHeader->Flags	    = 0;
			ndfsReplyHeader->Uid2		= HTONS(PrimarySession->SessionContext.Uid);
			ndfsReplyHeader->Tid2		= 0;
			ndfsReplyHeader->Mid2		= 0;
			ndfsReplyHeader->MessageSize4 = HTONL((UINT32)(sizeof(NDFS_REPLY_HEADER)+sizeof(NDFS_REPLY_TREE_CONNECT)));

			PrimarySession->StartingOffset.QuadPart = NTOHLL(ndfsRequestTreeConnect->StartingOffset8);

			status = NetdiskManager_GetPrimaryPartition( GlobalLfs.NetdiskManager,
														 PrimarySession,
														 &PrimarySession->NetDiskAddress,
														 PrimarySession->UnitDiskNo,
														 PrimarySession->NdscId,
														 &PrimarySession->StartingOffset,
														 PrimarySession->IsLocalAddress,
														 &netdiskPartition,
														 &PrimarySession->NetdiskPartitionInformation,
														 &PrimarySession->FileSystemType );

			SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE,
						   ("PRIM:TREE_CONNECT: netdiskPartition = %p netDiskPartitionInfo.StartingOffset = %I64x\n", 
						    netdiskPartition, PrimarySession->StartingOffset.QuadPart) );

			if (status != STATUS_SUCCESS) {
				
				if (status == STATUS_UNRECOGNIZED_VOLUME) {

					SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE,
								   ("PRIM:TREE_CONNECT: Partition is not available\n") );

					ndfsReplyTreeConnectStatus = NDFS_TREE_CONNECT_NO_PARTITION;				
				
				} else {

					ndfsReplyTreeConnectStatus = NDFS_TREE_CONNECT_UNSUCCESSFUL;
				}
			
				break;
			}

			if (FlagOn(netdiskPartition->Flags, NETDISK_PARTITION_FLAG_MOUNT_CORRUPTED)) {

				ndfsReplyTreeConnectStatus = NDFS_TREE_CORRUPTED;

				NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager, 
													   PrimarySession,
													   netdiskPartition, 
													   PrimarySession->IsLocalAddress );
				break;
			}

			if (netdiskPartition->FileSystemType == LFS_FILE_SYSTEM_NTFS && IS_WINDOWSXP_OR_LATER()) {

				getVolumeInformationStatus = 
					GetVolumeInformation( PrimarySession, 
										  &netdiskPartition->NetdiskPartitionInformation.VolumeName );
		
				SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE,
							   ("PRIM:TREE_CONNECT: getVolumeInformationStatus = %x\n", 
								getVolumeInformationStatus) );

				if (getVolumeInformationStatus != STATUS_SUCCESS) {

					NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager, 
														   PrimarySession,
														   netdiskPartition, 
														   PrimarySession->IsLocalAddress );

					ndfsReplyTreeConnectStatus = NDFS_TREE_CONNECT_UNSUCCESSFUL;				
					break;
				}
			}

			if (PrimarySession->NetdiskPartition) { 

				NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager, 
													   PrimarySession,
													   PrimarySession->NetdiskPartition, 
													   PrimarySession->IsLocalAddress );
			
				PrimarySession->NetdiskPartition = NULL;
			
			} else {

				NDAS_BUGON( FALSE );
			}

			PrimarySession->NetdiskPartition = netdiskPartition;

			PrimarySession->SessionContext.Tid  = PrimarySession->NetdiskPartition->Tid;
			ndfsReplyHeader->Tid2 = HTONS(PrimarySession->SessionContext.Tid);

			ndfsReplyTreeConnectStatus = NDFS_TREE_CONNECT_SUCCESS;				
		
		} while(0);
		
		ndfsReplyTreeConnect = (PNDFS_REPLY_TREE_CONNECT)(ndfsReplyHeader+1);
		ndfsReplyTreeConnect->Status = ndfsReplyTreeConnectStatus;
		
		ndfsReplyTreeConnect->SessionSlotCount = SESSION_SLOT_COUNT;
		
		ndfsReplyTreeConnect->BytesPerFileRecordSegment4	= HTONL(PrimarySession->Thread.BytesPerFileRecordSegment);
		ndfsReplyTreeConnect->BytesPerSector4			= HTONL(PrimarySession->Thread.BytesPerSector);
		ndfsReplyTreeConnect->BytesPerCluster4			= HTONL(PrimarySession->Thread.BytesPerCluster);

		status = SendMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->SendNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsReplyHeader,
							  NTOHL(ndfsReplyHeader->MessageSize4) );

		if (status != STATUS_SUCCESS) {
		
			break;
		}

		if (ndfsReplyTreeConnectStatus == NDFS_TREE_CONNECT_SUCCESS) {

			status = PrimarySessionTakeOver( PrimarySession );

			if (status == STATUS_INVALID_DEVICE_REQUEST) {

				PrimarySession->Thread.SessionState = SESSION_TREE_CONNECT;
			
			} else {
				
				SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
						   ("PrimarySessionTakeOver: Success PrimarySession = %p status = %x\n", 
						    PrimarySession, status) );

				if (PrimarySession->NetdiskPartition) {

					NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager,
														   PrimarySession,
														   PrimarySession->NetdiskPartition, 
														   PrimarySession->IsLocalAddress );	

					PrimarySession->NetdiskPartition = NULL;
				}
						
				if (status == STATUS_SUCCESS) {

					PrimarySession->ConnectionFileHandle = NULL;
					PrimarySession->ConnectionFileObject = NULL;
					
				} else {

					DisconnectFromSecondary( PrimarySession );
				} 

				SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED );

				PrimarySession->Thread.SessionState = SESSION_CLOSED;
			}
		}

		status = STATUS_SUCCESS;

		break;
	}

	case NDFS_COMMAND_LOGOFF: {

		PNDFS_REQUEST_LOGOFF	ndfsRequestLogoff;
		PNDFS_REPLY_HEADER		ndfsReplyHeader;
		PNDFS_REPLY_LOGOFF		ndfsReplyLogoff;
		

		if(PrimarySession->SessionContext.NdfsMinorVersion == NDFS_PROTOCOL_MINOR_0) {

			if(PrimarySession->Thread.SessionState != SESSION_TREE_CONNECT) {

				ASSERT( LFS_BUG );
				status = STATUS_UNSUCCESSFUL;
				break;
			}
		}

		if (!(NTOHS(ndfsRequestHeader->Uid2) == PrimarySession->SessionContext.Uid && 
			  NTOHS(ndfsRequestHeader->Tid2) == PrimarySession->SessionContext.Tid)) {

			ASSERT( LFS_BUG );
			status = STATUS_UNSUCCESSFUL;

			break;
		}
		
		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) == sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_REQUEST_LOGOFF) );

		ndfsRequestLogoff = (PNDFS_REQUEST_LOGOFF)(ndfsRequestHeader+1);

		status = RecvMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->RecvNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsRequestLogoff,
							  sizeof(NDFS_REQUEST_LOGOFF) );
	

		if (status != STATUS_SUCCESS) {

			//ASSERT( LFS_BUG );

			break;
		}

		ndfsReplyHeader = (PNDFS_REPLY_HEADER)(ndfsRequestLogoff+1);

		RtlCopyMemory( ndfsReplyHeader->Protocol, NDFS_PROTOCOL, sizeof(ndfsReplyHeader->Protocol) );

		ndfsReplyHeader->Status		= NDFS_SUCCESS;
		ndfsReplyHeader->Flags	    = 0;
		ndfsReplyHeader->Uid2		= HTONS(PrimarySession->SessionContext.Uid);
		ndfsReplyHeader->Tid2		= 0;
		ndfsReplyHeader->Mid2		= 0;
		ndfsReplyHeader->MessageSize4 = HTONL((UINT32)(sizeof(NDFS_REPLY_HEADER)+sizeof(NDFS_REPLY_LOGOFF)));

		ndfsReplyLogoff = (PNDFS_REPLY_LOGOFF)(ndfsReplyHeader+1);

		if (NTOHL(ndfsRequestLogoff->SessionKey4) != PrimarySession->SessionContext.SessionKey) {

			ndfsReplyLogoff->Status = NDFS_LOGOFF_UNSUCCESSFUL;
		
		} else {

			ndfsReplyLogoff->Status = NDFS_LOGOFF_SUCCESS;
		}

		status = SendMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->SendNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsReplyHeader,
							  NTOHL(ndfsReplyHeader->MessageSize4) );

		if (status != STATUS_SUCCESS) {

			break;
		}

		PrimarySession->Thread.SessionState = SESSION_CLOSED;
		break;
	}

	case NDFS_COMMAND_EXECUTE: {

		UINT16	mid;

		if(PrimarySession->SessionContext.NdfsMinorVersion == NDFS_PROTOCOL_MINOR_0) {

			if (PrimarySession->Thread.SessionState != SESSION_TREE_CONNECT) {

				ASSERT( LFS_BUG );
				status = STATUS_UNSUCCESSFUL;
				break;
			}
		}

		if (!(NTOHS(ndfsRequestHeader->Uid2) == PrimarySession->SessionContext.Uid && 
			NTOHS(ndfsRequestHeader->Tid2) == PrimarySession->SessionContext.Tid)) {

			ASSERT( LFS_BUG );
			status = STATUS_UNSUCCESSFUL;

			break;
		}

		mid = NTOHS(ndfsRequestHeader->Mid2);

		PrimarySession->Thread.SessionSlot[mid].RequestMessageBufferLength = sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_WINXP_REQUEST_HEADER) + DEFAULT_MAX_DATA_SIZE;
		RtlZeroMemory( &PrimarySession->Thread.SessionSlot[mid].RequestMessageBuffer[sizeof(NDFS_REQUEST_HEADER)], 
					   PrimarySession->Thread.SessionSlot[mid].RequestMessageBufferLength - sizeof(NDFS_REQUEST_HEADER) );

		PrimarySession->Thread.SessionSlot[mid].ReplyMessageBufferLength = sizeof(NDFS_REPLY_HEADER) + sizeof(NDFS_WINXP_REPLY_HEADER) + DEFAULT_MAX_DATA_SIZE;
		RtlZeroMemory( PrimarySession->Thread.SessionSlot[mid].ReplyMessageBuffer, 
					   PrimarySession->Thread.SessionSlot[mid].ReplyMessageBufferLength );

		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) >= sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_WINXP_REQUEST_HEADER) );

		status = ReceiveNtfsWinxpMessage(PrimarySession, mid );

		if (status != STATUS_SUCCESS)
			break;

		if (PrimarySession->Thread.SessionSlot[mid].State != SLOT_WAIT) {

			break;
		}
	
		PrimarySession->Thread.SessionSlot[mid].State = SLOT_EXECUTING;
		PrimarySession->Thread.IdleSlotCount --;

		if (PrimarySession->SessionContext.SessionSlotCount == 1) {

			ASSERT( mid == 0 );

			DispatchWinXpRequestWorker( PrimarySession, mid );

			PrimarySession->Thread.SessionSlot[mid].State = SLOT_WAIT;
			PrimarySession->Thread.IdleSlotCount ++;

			if (PrimarySession->Thread.SessionSlot[mid].Status == STATUS_SUCCESS) {

				PNDFS_REPLY_HEADER		ndfsReplyHeader;

				ndfsReplyHeader = (PNDFS_REPLY_HEADER)PrimarySession->Thread.SessionSlot[mid].ReplyMessageBuffer;
										
				PrimarySession->Thread.SessionSlot[mid].Status = 
					SendNdfsWinxpMessage( PrimarySession,
										  ndfsReplyHeader,
										  PrimarySession->Thread.SessionSlot[mid].NdfsWinxpReplyHeader,
										  PrimarySession->Thread.SessionSlot[mid].ReplyDataSize,
										  mid );

			}
	
			if (PrimarySession->Thread.SessionSlot[mid].ExtendWinxpRequestMessagePool) {

				ExFreePool( PrimarySession->Thread.SessionSlot[mid].ExtendWinxpRequestMessagePool );	
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpRequestMessagePool = NULL;
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePoolLength = 0;
			}
		
			if (PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePool) {

				ExFreePool( PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePool );	
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePool = NULL;
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePoolLength = 0;
			}

			if (PrimarySession->Thread.SessionSlot[mid].Status == STATUS_PENDING)
				NDAS_BUGON( FALSE );			
			
			if (PrimarySession->Thread.SessionSlot[mid].Status != STATUS_SUCCESS) {

				SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR );
										
				status = PrimarySession->Thread.SessionSlot[mid].Status;
				break;		
			}
				
			status = STATUS_SUCCESS;
			break;
		}

		NDAS_BUGON( FALSE );

		if (mid == 0)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker0,
								  PrimarySession );
		
		if (mid == 1)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker1,
								  PrimarySession );
		
		if (mid == 2)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker2,
								  PrimarySession );

		
		if (mid == 3)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker3,
								  PrimarySession );

		ExQueueWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem, DelayedWorkQueue );	

		status = STATUS_PENDING;
		break;
	}

	default:

		ASSERT( LFS_LPX_BUG );
		status = STATUS_UNSUCCESSFUL;
		
		break;
	}

	return status;
}
NTSTATUS
XixFsdSendFileChangeRC(
	IN BOOLEAN		Wait,
	IN uint8		* HostMac,
	IN uint64		LotNumber,
	IN uint8		* DiskId,
	IN uint32		PartitionId,
	IN uint64		FileLength,
	IN uint64		AllocationLength,
	IN uint64		UpdateStartOffset
)
{
	NTSTATUS							RC = STATUS_UNSUCCESSFUL;
	PXIFSDG_PKT							pPacket = NULL;
	PXIFS_FILE_LENGTH_CHANGE_BROADCAST	pPacketData = NULL;
	uint8								DstAddress[6] ={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
	
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
		("Enter XixFsdSendFileChangeRC \n"));

	ASSERT(Wait);
	
	// Changed by ILGU HONG
	//	chesung suggest
	/*
	if(FALSE ==LfsAllocDGPkt(&pPacket, HostMac, DstAddress, XIFS_TYPE_FILE_LENGTH_CHANGE))
	{
		return FALSE;
	}
	*/
	
	if(FALSE ==LfsAllocDGPkt(&pPacket, HostMac, DstAddress, XIFS_TYPE_FILE_LENGTH_CHANGE))
	{
		return FALSE;
	}



	pPacketData = &(pPacket->RawDataDG.FileLenChangeReq);
	// Changed by ILGU HONG
	//	RtlCopyMemory(pPacketData->DiskId, DiskId, 6);
	RtlCopyMemory(pPacketData->DiskId, DiskId, 16);
	pPacketData->PartionId = HTONL(PartitionId);
	pPacketData->LotNumber = HTONLL(LotNumber);
	pPacketData->FileLength = HTONLL(FileLength);
	pPacketData->AllocationLength = HTONLL(AllocationLength);
	pPacketData->WriteStartOffset =	HTONLL(UpdateStartOffset);
	pPacket->TimeOut.QuadPart = XixGetSystemTime().QuadPart + DEFAULT_REQUEST_MAX_TIMEOUT;




	ExAcquireFastMutex(&XiGlobalData.XifsComCtx.SendPktListMutex);
	InsertTailList(&(XiGlobalData.XifsComCtx.SendPktList),
								&(pPacket->PktListEntry) );
	ExReleaseFastMutex(&XiGlobalData.XifsComCtx.SendPktListMutex);

	KeSetEvent(&(XiGlobalData.XifsComCtx.CliSendDataEvent),0, FALSE);
	

	
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
			("Exit XixFsdSendFileChangeRC \n"));

	return STATUS_SUCCESS;	
}
NTSTATUS
xixfs_SendRenameLinkBC(
	IN BOOLEAN		Wait,
	IN uint32		SubCommand,
	IN uint8		* HostMac,
	IN uint64		LotNumber,
	IN uint8		* VolumeId,
	IN uint64		OldParentLotNumber,
	IN uint64		NewParentLotNumber
)
{
	NTSTATUS						RC = STATUS_UNSUCCESSFUL;
	PXIXFSDG_PKT						pPacket = NULL;
	PXIXFS_FILE_CHANGE_BROADCAST		pPacketData = NULL;
	XIFS_LOCK_CONTROL				LockControl;
	uint8							DstAddress[6] ={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
	
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
		("Enter XifsdSendRenameLinkBC \n"));

	ASSERT(Wait);
	
	// Changed by ILGU HONG
	//	chesung suggest
	/*
	if(FALSE ==xixfs_AllocDGPkt(&pPacket, HostMac, DstAddress, XIXFS_TYPE_FILE_CHANGE))
	{
		return FALSE;
	}
	*/
	if(FALSE ==xixfs_AllocDGPkt(&pPacket, HostMac, NULL, XIXFS_TYPE_FILE_CHANGE))
	{
		return FALSE;
	}

	pPacketData = &(pPacket->RawDataDG.FileChangeReq);
	// Changed by ILGU HONG
	RtlCopyMemory(pPacketData->VolumeId, VolumeId, 16);
	pPacketData->LotNumber = HTONLL(LotNumber);
	pPacketData->PrevParentLotNumber = HTONLL(OldParentLotNumber);
	pPacketData->NewParentLotNumber = HTONLL(NewParentLotNumber);
	pPacketData->SubCommand =HTONL(SubCommand);

	pPacket->TimeOut.QuadPart = xixcore_GetCurrentTime64() + DEFAULT_REQUEST_MAX_TIMEOUT;




	ExAcquireFastMutexUnsafe(&XiGlobalData.XifsComCtx.SendPktListMutex);
	InsertTailList(&(XiGlobalData.XifsComCtx.SendPktList),
								&(pPacket->PktListEntry) );
	ExReleaseFastMutexUnsafe(&XiGlobalData.XifsComCtx.SendPktListMutex);

	KeSetEvent(&(XiGlobalData.XifsComCtx.CliSendDataEvent),0, FALSE);
	

	
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
			("Exit XifsdSendRenameLinkBC \n"));

	return STATUS_SUCCESS;	
}
BOOLEAN
XixFsAreYouHaveLotLock(
	IN BOOLEAN		Wait,
	IN uint8		* HostMac,
	IN uint8		* LockOwnerMac,
	IN uint64		LotNumber,
	IN uint8		* DiskId,
	IN uint32		PartitionId,
	IN uint8		* LockOwnerId
)
{
	// Request LotLock state to Lock Owner
	
	
	NTSTATUS					RC = STATUS_UNSUCCESSFUL;
	PXIFSDG_PKT					pPacket = NULL;
	PXIFS_LOCK_REQUEST			pPacketData = NULL;
	XIFS_LOCK_CONTROL			LockControl;
	
	//PAGED_CODE();
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
		("Enter XixFsAreYouHaveLotLock \n"));

	ASSERT(Wait);
	
	if(FALSE ==LfsAllocDGPkt(&pPacket, HostMac, LockOwnerMac, XIFS_TYPE_LOCK_REQUEST))
	{
		return FALSE;
	}


	// Changed by ILGU HONG
	//	chesung suggest
	/*
	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
		("Packet Dest Info  [0x%02x:%02x:%02x:%02x:%02x:%02x]\n",
		LockOwnerMac[0], LockOwnerMac[1], LockOwnerMac[2],
		LockOwnerMac[3], LockOwnerMac[4], LockOwnerMac[5]));
	*/
	DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
		("Packet Dest Info  [0x%02x:%02x:%02x:%02x:%02x:%02x]\n",
		LockOwnerMac[26], LockOwnerMac[27], LockOwnerMac[28],
		LockOwnerMac[29], LockOwnerMac[30], LockOwnerMac[31]));

	pPacketData = &(pPacket->RawDataDG.LockReq);
	RtlCopyMemory(pPacketData->LotOwnerID, LockOwnerId, 16);
	// Changed by ILGU HONG
	//	chesung suggest
	//RtlCopyMemory(pPacketData->DiskId, DiskId, 6);
	//RtlCopyMemory(pPacketData->LotOwnerMac, LockOwnerMac, 6);
	RtlCopyMemory(pPacketData->DiskId, DiskId, 16);
	RtlCopyMemory(pPacketData->LotOwnerMac, LockOwnerMac, 32);
	pPacketData->PartionId = HTONL(PartitionId);
	pPacketData->LotNumber = HTONLL(LotNumber);
	pPacketData->PacketNumber = HTONL(XiGlobalData.XifsComCtx.PacketNumber);
	XiGlobalData.XifsComCtx.PacketNumber++;

	pPacket->TimeOut.QuadPart = XixGetSystemTime().QuadPart + DEFAULT_REQUEST_MAX_TIMEOUT;


	KeInitializeEvent(&LockControl.KEvent, SynchronizationEvent, FALSE);
	LockControl.Status = LOCK_INVALID;

	pPacket->pLockContext = &LockControl;


	ExAcquireFastMutex(&XiGlobalData.XifsComCtx.SendPktListMutex);
	InsertTailList(&(XiGlobalData.XifsComCtx.SendPktList),
								&(pPacket->PktListEntry) );
	ExReleaseFastMutex(&XiGlobalData.XifsComCtx.SendPktListMutex);

	KeSetEvent(&(XiGlobalData.XifsComCtx.CliSendDataEvent),0, FALSE);
	
	RC = KeWaitForSingleObject(&LockControl.KEvent, Executive, KernelMode, FALSE, NULL);

	if(!NT_SUCCESS(RC)){
		DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
			("Exit XixFsAreYouHaveLotLock \n"));
		return FALSE;
	}

	if(LockControl.Status == LOCK_OWNED_BY_OWNER){
		DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
			("Exit XixFsAreYouHaveLotLock Lock is realy acquired by other \n"));
		return TRUE;
	}


	DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
			("Exit XifsdAreYouHaveLotLock Lock is status(0x%x) \n", LockControl.Status));
	/*
		TRUE --> Lock is Owner by Me
		FALSE --> Lock is Not Mine
		FALSE--> TimeOut Lock Owner is not in Network
	*/
	
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
			("Exit XifsdAreYouHaveLotLock \n"));

	return FALSE;
}
Exemple #18
0
/**
  Configure a UDP IO port to receive the multicast.

  @param  McastIo               The UDP IO to configure
  @param  Context               The opaque parameter to the function which is the
                                MTFTP session.

  @retval EFI_SUCCESS           The UDP child is successfully configured.
  @retval Others                Failed to configure the UDP child.

**/
EFI_STATUS
EFIAPI
Mtftp4RrqConfigMcastPort (
  IN UDP_IO                 *McastIo,
  IN VOID                   *Context
  )
{
  MTFTP4_PROTOCOL           *Instance;
  EFI_MTFTP4_CONFIG_DATA    *Config;
  EFI_UDP4_CONFIG_DATA      UdpConfig;
  EFI_IPv4_ADDRESS          Group;
  EFI_STATUS                Status;
  IP4_ADDR                  Ip;

  Instance                     = (MTFTP4_PROTOCOL *) Context;
  Config                       = &Instance->Config;

  UdpConfig.AcceptBroadcast    = FALSE;
  UdpConfig.AcceptPromiscuous  = FALSE;
  UdpConfig.AcceptAnyPort      = FALSE;
  UdpConfig.AllowDuplicatePort = FALSE;
  UdpConfig.TypeOfService      = 0;
  UdpConfig.TimeToLive         = 64;
  UdpConfig.DoNotFragment      = FALSE;
  UdpConfig.ReceiveTimeout     = 0;
  UdpConfig.TransmitTimeout    = 0;
  UdpConfig.UseDefaultAddress  = Config->UseDefaultSetting;
  UdpConfig.StationAddress     = Config->StationIp;
  UdpConfig.SubnetMask         = Config->SubnetMask;
  UdpConfig.StationPort        = Instance->McastPort;
  UdpConfig.RemotePort         = 0;

  Ip = HTONL (Instance->ServerIp);
  CopyMem (&UdpConfig.RemoteAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));

  Status = McastIo->Protocol.Udp4->Configure (McastIo->Protocol.Udp4, &UdpConfig);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (!Config->UseDefaultSetting && 
      !EFI_IP4_EQUAL (&mZeroIp4Addr, &Config->GatewayIp)) {
    //
    // The station IP address is manually configured and the Gateway IP is not 0.
    // Add the default route for this UDP instance.
    //
    Status = McastIo->Protocol.Udp4->Routes (
                                       McastIo->Protocol.Udp4, 
                                       FALSE,
                                       &mZeroIp4Addr,
                                       &mZeroIp4Addr,
                                       &Config->GatewayIp
                                       );
                             
    if (EFI_ERROR (Status)) {
      McastIo->Protocol.Udp4->Configure (McastIo->Protocol.Udp4, NULL);
      return Status;
    }
  }

  //
  // join the multicast group
  //
  Ip = HTONL (Instance->McastIp);
  CopyMem (&Group, &Ip, sizeof (EFI_IPv4_ADDRESS));

  return McastIo->Protocol.Udp4->Groups (McastIo->Protocol.Udp4, TRUE, &Group);
}
Exemple #19
0
NTSTATUS
LspNoOperation(
	   IN PLANSCSI_SESSION	LSS,
		IN UINT32			TargetId,
	   OUT PBYTE			PduResponse
	)
{
	_int8								PduBuffer[MAX_REQUEST_SIZE];
	PLANSCSI_H2R_PDU_HEADER				pRequestHeader;
	LANSCSI_PDU_POINTERS				pdu;
	NTSTATUS							ntStatus;

	//
	// Check Parameters.
	//
	if(PduResponse == NULL) {
		KDPrintM(DBG_PROTO_ERROR, ("pResult is NULL!!!\n"));
		return STATUS_INVALID_PARAMETER;
	}

	//
	// Make Request.
	//
	memset(PduBuffer, 0, MAX_REQUEST_SIZE);
	
	pRequestHeader = (PLANSCSI_H2R_PDU_HEADER)PduBuffer;
	pRequestHeader->Opcode = NOP_H2R;
	pRequestHeader->HPID = HTONL(LSS->HPID);
	pRequestHeader->RPID = HTONS(LSS->RPID);
	pRequestHeader->PathCommandTag = HTONL(++LSS->CommandTag);
	pRequestHeader->TargetID = TargetId;

	//
	// Send Request.
	//
	pdu.pH2RHeader = (PLANSCSI_H2R_PDU_HEADER)pRequestHeader;

	ntStatus = LspSendRequest(LSS, &pdu, NULL);
	if(!NT_SUCCESS(ntStatus)) {
		KDPrintM(DBG_PROTO_ERROR, ("Error when Send Request.\n"));
		return ntStatus;
	}

	if (LSS->HWVersion == LANSCSIIDE_VERSION_2_5) {
		// NDAS 2.5 replies to NOP
		// Read Reply.
		ntStatus = LspReadReply(LSS, (PCHAR)PduBuffer, &pdu, NULL);
		if(!NT_SUCCESS(ntStatus)) {
			KDPrintM(DBG_PROTO_ERROR, ("Error when read request.\n"));
			return ntStatus;
		}
		if (NOP_R2H != pdu.pR2HHeader->Opcode) {
			KDPrintM(DBG_PROTO_ERROR, ("Invalid opcode %x replied to NOP.\n", pdu.pR2HHeader->Opcode));
			return ntStatus;
		}
	} else {

	}
	*PduResponse = LANSCSI_RESPONSE_SUCCESS;

	return STATUS_SUCCESS;
}
EFI_STATUS
SendOutAck (
  IN UINT32                         SeqId,
  IN UINT32                         Type
  )
/*++

Routine Description:

  Send data or ack packet.

Arguments:

  SeqId - Sequence ID.

Returns:

  EFI_SUCCESS - Operation succeeded.
  Others      - Some failure happened.
  EFI_OUT_OF_RESOURCES - Memory allocation failure.

--*/
{
  EFI_STATUS                            Status;
  EAS_MNP_FRAG_FLAG                     FragFlag;
  UINT8                                 *Buffer;

  Buffer = EntsAllocatePool (sizeof (EAS_MNP_FRAG_FLAG));
  if(Buffer == NULL) {
    EFI_ENTS_DEBUG ((EFI_ENTS_D_ERROR, L"EntsAllocatePool Error"));
    return EFI_OUT_OF_RESOURCES;
  }

  FragFlag.LLFlag       ^= FragFlag.LLFlag;
  FragFlag.Flag.SeqId   = HTONL (SeqId);
  FragFlag.Flag.OpCode  = Type;

  //
  // Build data
  //
  EntsCopyMem (&TxLLData, &mMnpTxDataTemplate, sizeof (EFI_MANAGED_NETWORK_TRANSMIT_DATA));
  TxLLData.DataLength                       = (UINT32) (sizeof (EAS_MNP_FRAG_FLAG));
  TxLLData.FragmentTable[0].FragmentLength  = (UINT32) (sizeof (EAS_MNP_FRAG_FLAG));
  TxLLData.FragmentTable[0].FragmentBuffer  = Buffer;

  EntsCopyMem (TxLLData.FragmentTable[0].FragmentBuffer, &FragFlag.LLFlag, sizeof (EAS_MNP_FRAG_FLAG));

  //
  // Ready to send buffer
  //
  TxLLToken.Packet.TxData = &TxLLData;
  Context                 = 0;

  Status                  = Mnp->Transmit (Mnp, &TxLLToken);
  if (EFI_ERROR (Status)) {
  	RecycleTxBuffer(Buffer);
    EFI_ENTS_DEBUG ((EFI_ENTS_D_ERROR, L"Mnp->Transmit Error"));
	return Status;
  }

  RecycleTxBuffer(Buffer);

  return EFI_SUCCESS;
}
Exemple #21
0
int discover_main(int argc, char *argv[])
{
    /* If this task is excecutated as an NSH built-in function, then the
     * network has already been configured by NSH's start-up logic.
     */

#ifndef CONFIG_NSH_BUILTIN_APPS
    struct in_addr addr;
#if defined(CONFIG_EXAMPLES_DISCOVER_DHCPC) || defined(CONFIG_EXAMPLES_DISCOVER_NOMAC)
    uint8_t mac[IFHWADDRLEN];
#endif
#ifdef CONFIG_EXAMPLES_DISCOVER_DHCPC
    void *handle;
#endif

    /* Many embedded network interfaces must have a software assigned MAC */

#ifdef CONFIG_EXAMPLES_DISCOVER_NOMAC
    mac[0] = 0x00;
    mac[1] = 0xe0;
    mac[2] = 0xde;
    mac[3] = 0xad;
    mac[4] = 0xbe;
    mac[5] = 0xef;
    uip_setmacaddr("eth0", mac);
#endif

    /* Set up our host address */

#ifdef CONFIG_EXAMPLES_DISCOVER_DHCPC
    addr.s_addr = 0;
#else
    addr.s_addr = HTONL(CONFIG_EXAMPLES_DISCOVER_IPADDR);
#endif
    uip_sethostaddr("eth0", &addr);

    /* Set up the default router address */

    addr.s_addr = HTONL(CONFIG_EXAMPLES_DISCOVER_DRIPADDR);
    uip_setdraddr("eth0", &addr);

    /* Setup the subnet mask */

    addr.s_addr = HTONL(CONFIG_EXAMPLES_DISCOVER_NETMASK);
    uip_setnetmask("eth0", &addr);

#ifdef CONFIG_EXAMPLES_DISCOVER_DHCPC
    /* Set up the resolver */

    resolv_init();

    /* Get the MAC address of the NIC */

    uip_getmacaddr("eth0", mac);

    /* Set up the DHCPC modules */

    handle = dhcpc_open(&mac, IFHWADDRLEN);

    /* Get an IP address.  Note:  there is no logic here for renewing the address in this
     * example.  The address should be renewed in ds.lease_time/2 seconds.
     */

    printf("Getting IP address\n");
    if (handle)
    {
        struct dhcpc_state ds;
        (void)dhcpc_request(handle, &ds);
        uip_sethostaddr("eth1", &ds.ipaddr);

        if (ds.netmask.s_addr != 0)
        {
            uip_setnetmask("eth0", &ds.netmask);
        }

        if (ds.default_router.s_addr != 0)
        {
            uip_setdraddr("eth0", &ds.default_router);
        }

        if (ds.dnsaddr.s_addr != 0)
        {
            resolv_conf(&ds.dnsaddr);
        }

        dhcpc_close(handle);
        printf("IP: %s\n", inet_ntoa(ds.ipaddr));
    }

#endif /* CONFIG_EXAMPLES_DISCOVER_DHCPC */
#endif /* CONFIG_NSH_BUILTIN_APPS */

    if (discover_start(NULL) < 0)
    {
        ndbg("Could not start discover daemon.\n");
        return ERROR;
    }

    return OK;
}
EFI_STATUS
MnpSendPacketOut (
  IN CHAR8     *Buffer,
  IN UINT32    Sequence,
  IN UINTN     Size
  )
/*++

Routine Description:

  This func is to send a data packet out to managed network.

Arguments:

  Buffer    - A buffer for writing.
  Sequence  - The Sequence Id of the packet to send.
  Size      - The size of the buffer to send.

Returns:

  EFI_SUCCESS          - Operation succeeded.
  EFI_OUT_OF_RESOURCES - Memory allocation failed.
  Others               - Some failure happened.

--*/
{
  BOOLEAN           IsOver;
  EAS_MNP_FRAG_FLAG FragFlag;
  EAS_APP_FLAG      AppFlag;
  UINTN             BufferSize;
  UINT32            PacketLength;
  UINT32            PacketStartPoint;
  EFI_STATUS        Status;
  UINT8             *FragmentBuffer;

  if (0 == Size) {
    return EFI_SUCCESS;
  }

  IsOver = FALSE;
  FragFlag.LLFlag ^= FragFlag.LLFlag;
  FragFlag.Flag.SeqId   = HTONL (Sequence);
  FragFlag.Flag.OpCode  = LINK_OPERATION_DATA;
  BufferSize            = Size;
  PacketStartPoint      = 0;
  FragmentBuffer        = NULL;

  while (!IsOver) {
    //
    // Build Fragment Flag
    //
    if (BufferSize <= MAX_PACKET_LENGTH) {
      IsOver = TRUE;
      CLR_FLAG_MF (FragFlag.LLFlag);
      PacketLength          = (UINT32) BufferSize;
      FragFlag.Flag.Offset  = HTONS (PacketStartPoint);
    } else {
      //
      // Need more fragement
      //
      IsOver = FALSE;
      SET_FLAG_MF (FragFlag.LLFlag);
      PacketLength          = MAX_PACKET_LENGTH;
      FragFlag.Flag.Offset  = HTONS (PacketStartPoint);
      BufferSize -= MAX_PACKET_LENGTH;
    }
    //
    // Build App Flag
    //
    AppFlag.LLFlag ^= AppFlag.LLFlag;
    AppSequence = AppSequenceSavedForResend;
    AppFlag.Flag.SeqId = HTONL(AppSequence);
    //
    // Build data
    //
   	FragmentBuffer = EntsAllocatePool (PacketLength + sizeof (EAS_MNP_FRAG_FLAG) + sizeof (EAS_APP_FLAG));
	if(NULL == FragmentBuffer) {
      EFI_ENTS_DEBUG ((EFI_ENTS_D_ERROR, L"EntsAllocatePool Error"));
      return EFI_OUT_OF_RESOURCES;
    }

    EntsCopyMem (&TxData, &mMnpTxDataTemplate, sizeof (EFI_MANAGED_NETWORK_TRANSMIT_DATA));
    TxData.DataLength = (UINT32) (PacketLength + sizeof (EAS_MNP_FRAG_FLAG) + sizeof (EAS_APP_FLAG));
    TxData.FragmentTable[0].FragmentLength = (UINT32) (PacketLength + sizeof (EAS_MNP_FRAG_FLAG) + sizeof (EAS_APP_FLAG));
    TxData.FragmentTable[0].FragmentBuffer = FragmentBuffer;

    EntsCopyMem (
      (UINT8 *) TxData.FragmentTable[0].FragmentBuffer + sizeof (EAS_MNP_FRAG_FLAG) + sizeof (EAS_APP_FLAG),
      (CHAR8 *) Buffer + PacketStartPoint,
      PacketLength
      );
    EntsCopyMem (
      (UINT8 *) TxData.FragmentTable[0].FragmentBuffer + sizeof (EAS_MNP_FRAG_FLAG),
      &AppFlag.LLFlag,
      sizeof (EAS_APP_FLAG)
      );
    EntsCopyMem (
      TxData.FragmentTable[0].FragmentBuffer,
      &FragFlag.LLFlag,
      sizeof (EAS_MNP_FRAG_FLAG)
      );
    PacketStartPoint += PacketLength;

    TxToken.Packet.TxData = &TxData;

    //
    // Ready to send buffer
    //
    Context = 0;
    Status  = Mnp->Transmit (Mnp, &TxToken);
    if (EFI_ERROR (Status)) {
      RecycleTxBuffer(FragmentBuffer);
      EFI_ENTS_DEBUG ((EFI_ENTS_D_ERROR, L"Mnp->Transmit Error"));
      return Status;
    }
    //
    // Check the event ( Omitted...)
    //
    RecycleTxBuffer(FragmentBuffer);
  }

  return EFI_SUCCESS;
}
Exemple #23
0
static int test_callback(netdev_t *rcv_dev, void *src, size_t src_len,
                         void *dest, size_t dest_len, void *payload,
                         size_t payload_len)
{
    uint8_t exp_src[dev_address_len];
    uint8_t exp_dest[dev_address_len];

    if (rcv_dev != dev) {
        printf("cb: Device is not the expected one: %p != %p\n",
               (void *)rcv_dev, (void *)dev);
        return -EINVAL;
    }

    switch (dev_address_len) {
        case 1:
            exp_src[0] = NETDEV_TEST_SENDER;
            exp_dest[0] = NETDEV_TEST_RECEIVER;
            break;

        case 2:
            do {
                uint16_t *exp_src_ptr = (uint16_t *)exp_src;
                uint16_t *exp_dest_ptr = (uint16_t *)exp_dest;
                *exp_src_ptr = NETDEV_TEST_SENDER;
                *exp_dest_ptr = NETDEV_TEST_RECEIVER;
            } while (0);

            break;

        case 3:
            do {
                uint16_t exp_src_int = HTONS(NETDEV_TEST_SENDER);
                uint16_t exp_dest_int = HTONS(NETDEV_TEST_RECEIVER);
                memset(exp_dest, 0, dev_address_len - sizeof(uint16_t));
                memset(exp_src, 0, dev_address_len - sizeof(uint16_t));
                memcpy(&(exp_dest[dev_address_len - sizeof(uint16_t)]),
                       &exp_dest_int, sizeof(uint16_t));
                memcpy(&(exp_src[dev_address_len - sizeof(uint16_t)]),
                       &exp_src_int, sizeof(uint16_t));
            }
            while (0);

            break;

        case 4:
            do {
                uint32_t *exp_src_ptr = (uint32_t *)exp_src;
                uint32_t *exp_dest_ptr = (uint32_t *)exp_dest;
                *exp_src_ptr = NETDEV_TEST_SENDER;
                *exp_dest_ptr = NETDEV_TEST_RECEIVER;
            } while (0);

            break;

        case 8:
            do {
                uint64_t *exp_src_ptr = (uint64_t *)exp_src;
                uint64_t *exp_dest_ptr = (uint64_t *)exp_dest;
                *exp_src_ptr = NETDEV_TEST_SENDER;
                *exp_dest_ptr = NETDEV_TEST_RECEIVER;
            } while (0);

            break;

        default:
            do {
                uint32_t exp_src_int = HTONL(NETDEV_TEST_SENDER);
                uint32_t exp_dest_int = HTONL(NETDEV_TEST_RECEIVER);
                memset(exp_dest, 0, dev_address_len - sizeof(uint32_t));
                memset(exp_src, 0, dev_address_len - sizeof(uint32_t));
                memcpy(&(exp_dest[dev_address_len - sizeof(uint32_t)]),
                       &exp_dest_int, sizeof(uint32_t));
                memcpy(&(exp_src[dev_address_len - sizeof(uint32_t)]),
                       &exp_src_int, sizeof(uint32_t));
            }
            while (0);

            break;
    }

    if (src_len != dev_address_len || memcmp(exp_src, src, src_len) != 0) {
        printf("cb: src is not from sender %d\n", NETDEV_TEST_SENDER);
        return -EINVAL;
    }

    if (dest_len != dev_address_len || memcmp(exp_dest, dest, dest_len) != 0) {
        printf("cb: dest is not for receiver %d\n", NETDEV_TEST_SENDER);
        return -EINVAL;
    }

    if (strcmp(payload, "header 1,header 2,payload") != 0) {
        puts("cb: payload is not as expected (\"header 1,header 2,payload\")");
        return -EINVAL;
    }

    printf("Received \"");

    for (size_t i = 0; i < payload_len; i++) {
        printf("%c", ((char *)payload)[i]);
    }

    printf("\"\n");

    printf("Sender was");

    for (size_t i = 0; i < src_len; i++) {
        printf(" %02x", ((char *)src)[i]);
    }

    printf("\n");

    return payload_len;
}
NTSTATUS
DispatchRequest (
	IN PPRIMARY_SESSION	PrimarySession
	)
{
	NTSTATUS				status;
	IN PNDFS_REQUEST_HEADER	ndfsRequestHeader;


	ASSERT( NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2) < PrimarySession->SessionContext.SessionSlotCount );
	ASSERT( PrimarySession->Thread.SessionSlot[NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2)].State == SLOT_WAIT );
	ASSERT( PrimarySession->Thread.ReceiveOverlapped.Request[0].IoStatusBlock.Information == sizeof(NDFS_REQUEST_HEADER) );

	RtlCopyMemory( PrimarySession->Thread.SessionSlot[NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2)].RequestMessageBuffer,
				   &PrimarySession->Thread.NdfsRequestHeader,
				   sizeof(NDFS_REQUEST_HEADER) );

	ndfsRequestHeader = (PNDFS_REQUEST_HEADER)PrimarySession->Thread.SessionSlot[NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2)].RequestMessageBuffer;
   
    DebugTrace2( 0, Dbg,
				("DispatchRequest: ndfsRequestHeader->Command = %d\n", 
				ndfsRequestHeader->Command) );

	switch (ndfsRequestHeader->Command) {

	case NDFS_COMMAND_LOGOFF: {

		PNDFS_REQUEST_LOGOFF	ndfsRequestLogoff;
		PNDFS_REPLY_HEADER		ndfsReplyHeader;
		PNDFS_REPLY_LOGOFF		ndfsReplyLogoff;
		

		if (PrimarySession->Thread.SessionState != SESSION_TREE_CONNECT) {

			ASSERT(NDASFAT_BUG);
			status = STATUS_UNSUCCESSFUL;
			break;
		}

		if (!(NTOHS(ndfsRequestHeader->Uid2) == PrimarySession->SessionContext.Uid && 
			 NTOHS(ndfsRequestHeader->Tid2) == PrimarySession->SessionContext.Tid)) {

			ASSERT(NDASFAT_BUG);
			status = STATUS_UNSUCCESSFUL;
			break;
		}
		
		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) == sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_REQUEST_LOGOFF) );

		ndfsRequestLogoff = (PNDFS_REQUEST_LOGOFF)(ndfsRequestHeader+1);
		
		status = RecvMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->RecvNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsRequestLogoff,
							  sizeof(NDFS_REQUEST_LOGOFF) );
	
		if (status != STATUS_SUCCESS) {

			ASSERT(NDASFAT_BUG);
			break;
		}

		ndfsReplyHeader = (PNDFS_REPLY_HEADER)(ndfsRequestLogoff+1);

		RtlCopyMemory( ndfsReplyHeader->Protocol, NDFS_PROTOCOL, sizeof(ndfsReplyHeader->Protocol) );
		ndfsReplyHeader->Status		= NDFS_SUCCESS;
		ndfsReplyHeader->Flags	    = 0;
		ndfsReplyHeader->Uid2		= HTONS(PrimarySession->SessionContext.Uid);
		ndfsReplyHeader->Tid2		= 0;
		ndfsReplyHeader->Mid2		= 0;
		ndfsReplyHeader->MessageSize4 = HTONL((UINT32)(sizeof(NDFS_REPLY_HEADER)+sizeof(NDFS_REPLY_LOGOFF)));

		ndfsReplyLogoff = (PNDFS_REPLY_LOGOFF)(ndfsReplyHeader+1);

		if (NTOHL(ndfsRequestLogoff->SessionKey4) != PrimarySession->SessionContext.SessionKey) {

			ndfsReplyLogoff->Status = NDFS_LOGOFF_UNSUCCESSFUL;
		
		} else {

			ndfsReplyLogoff->Status = NDFS_LOGOFF_SUCCESS;
		}

		status = SendMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->SendNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsReplyHeader,
							  NTOHL(ndfsReplyHeader->MessageSize4) );

		if (status != STATUS_SUCCESS) {

			break;
		}

		PrimarySession->Thread.SessionState = SESSION_CLOSED;

		status = STATUS_SUCCESS;

		break;
	}

	case NDFS_COMMAND_EXECUTE: {

		UINT16	mid;

		if(PrimarySession->SessionContext.NdfsMinorVersion == NDFS_PROTOCOL_MINOR_0) {

			if (PrimarySession->Thread.SessionState != SESSION_TREE_CONNECT) {

				ASSERT( NDASFAT_BUG );
				status = STATUS_UNSUCCESSFUL;
				break;
			}
		}

		if (!(NTOHS(ndfsRequestHeader->Uid2) == PrimarySession->SessionContext.Uid && 
			NTOHS(ndfsRequestHeader->Tid2) == PrimarySession->SessionContext.Tid)) {

			ASSERT( NDASFAT_BUG );
			status = STATUS_UNSUCCESSFUL;

			break;
		}

		mid = NTOHS(ndfsRequestHeader->Mid2);

		PrimarySession->Thread.SessionSlot[mid].RequestMessageBufferLength = sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_WINXP_REQUEST_HEADER) + DEFAULT_NDAS_MAX_DATA_SIZE;
		RtlZeroMemory( &PrimarySession->Thread.SessionSlot[mid].RequestMessageBuffer[sizeof(NDFS_REQUEST_HEADER)], 
					   PrimarySession->Thread.SessionSlot[mid].RequestMessageBufferLength - sizeof(NDFS_REQUEST_HEADER) );

		PrimarySession->Thread.SessionSlot[mid].ReplyMessageBufferLength = sizeof(NDFS_REPLY_HEADER) + sizeof(NDFS_WINXP_REPLY_HEADER) + DEFAULT_NDAS_MAX_DATA_SIZE;
		RtlZeroMemory( PrimarySession->Thread.SessionSlot[mid].ReplyMessageBuffer, 
					   PrimarySession->Thread.SessionSlot[mid].ReplyMessageBufferLength );

		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) >= sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_WINXP_REQUEST_HEADER) );

		status = ReceiveNdfsWinxpMessage( PrimarySession, mid );

		if (status != STATUS_SUCCESS)
			break;

		if (PrimarySession->Thread.SessionSlot[mid].State != SLOT_WAIT) {

			break;
		}
	
		PrimarySession->Thread.SessionSlot[mid].State = SLOT_EXECUTING;
		PrimarySession->Thread.IdleSlotCount --;

		if (PrimarySession->SessionContext.SessionSlotCount == 1) {

			ASSERT( mid == 0 );

			DispatchWinXpRequestWorker( PrimarySession, mid );

			PrimarySession->Thread.SessionSlot[mid].State = SLOT_WAIT;
			PrimarySession->Thread.IdleSlotCount ++;

			if (PrimarySession->Thread.SessionSlot[mid].Status == STATUS_SUCCESS) {

				PNDFS_REPLY_HEADER		ndfsReplyHeader;

				ndfsReplyHeader = (PNDFS_REPLY_HEADER)PrimarySession->Thread.SessionSlot[mid].ReplyMessageBuffer;
				
				PrimarySession->Thread.SessionSlot[mid].Status = 
					SendNdfsWinxpMessage( PrimarySession,
										  ndfsReplyHeader,
										  PrimarySession->Thread.SessionSlot[mid].NdfsWinxpReplyHeader,
										  PrimarySession->Thread.SessionSlot[mid].ReplyDataSize,
										  mid );

			}
	
			if (PrimarySession->Thread.SessionSlot[mid].ExtendWinxpRequestMessagePool) {

				ExFreePool( PrimarySession->Thread.SessionSlot[mid].ExtendWinxpRequestMessagePool );	
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpRequestMessagePool = NULL;
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePoolLength = 0;
			}
		
			if (PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePool) {

				ExFreePool( PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePool );	
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePool = NULL;
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePoolLength = 0;
			}

			NDAS_ASSERT( PrimarySession->Thread.SessionSlot[mid].Status != STATUS_PENDING );
			
			if (PrimarySession->Thread.SessionSlot[mid].Status != STATUS_SUCCESS) {

				SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR );
										
				status = PrimarySession->Thread.SessionSlot[mid].Status;
				break;		
			}
				
			status = STATUS_SUCCESS;
			break;
		}

		if (mid == 0)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker0,
								  PrimarySession );
		
		if (mid == 1)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker1,
								  PrimarySession );
		
		if (mid == 2)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker2,
								  PrimarySession );

		
		if (mid == 3)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker3,
								  PrimarySession );

		ExQueueWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem, DelayedWorkQueue );	

		status = STATUS_PENDING;
		break;
	}

	default:

		NDAS_ASSERT( FALSE );			
		status = STATUS_UNSUCCESSFUL;
		
		break;
	}

	return status;
}
Exemple #25
0
static int tcpecho_netsetup()
{
  /* If this task is excecutated as an NSH built-in function, then the
   * network has already been configured by NSH's start-up logic.
   */

#ifndef CONFIG_NSH_BUILTIN_APPS
  struct in_addr addr;
#if defined(CONFIG_EXAMPLES_TCPECHO_DHCPC) || defined(CONFIG_EXAMPLES_TCPECHO_NOMAC)
  uint8_t mac[IFHWADDRLEN];
#endif
#ifdef CONFIG_EXAMPLES_TCPECHO_DHCPC
  struct dhcpc_state ds;
  void *handle;
#endif

/* Many embedded network interfaces must have a software assigned MAC */

#ifdef CONFIG_EXAMPLES_TCPECHO_NOMAC
  mac[0] = 0x00;
  mac[1] = 0xe0;
  mac[2] = 0xde;
  mac[3] = 0xad;
  mac[4] = 0xbe;
  mac[5] = 0xef;
  uip_setmacaddr("eth0", mac);
#endif

  /* Set up our host address */

#ifdef CONFIG_EXAMPLES_TCPECHO_DHCPC
  addr.s_addr = 0;
#else
  addr.s_addr = HTONL(CONFIG_EXAMPLES_TCPECHO_IPADDR);
#endif
  uip_sethostaddr("eth0", &addr);

  /* Set up the default router address */

  addr.s_addr = HTONL(CONFIG_EXAMPLES_TCPECHO_DRIPADDR);
  uip_setdraddr("eth0", &addr);

  /* Setup the subnet mask */

  addr.s_addr = HTONL(CONFIG_EXAMPLES_TCPECHO_NETMASK);
  uip_setnetmask("eth0", &addr);

#ifdef CONFIG_EXAMPLES_TCPECHO_DHCPC
  /* Set up the resolver */

  dns_bind();

  /* Get the MAC address of the NIC */

  uip_getmacaddr("eth0", mac);

  /* Set up the DHCPC modules */

  handle = dhcpc_open(&mac, IFHWADDRLEN);

  /* Get an IP address.  Note:  there is no logic here for renewing the address in this
   * example.  The address should be renewed in ds.lease_time/2 seconds.
   */

  if (!handle)
    {
      return ERROR;
    }

  if (dhcpc_request(handle, &ds) != OK)
    {
      return ERROR;
    }

  uip_sethostaddr("eth1", &ds.ipaddr);

  if (ds.netmask.s_addr != 0)
    {
      uip_setnetmask("eth0", &ds.netmask);
    }

  if (ds.default_router.s_addr != 0)
    {
      uip_setdraddr("eth0", &ds.default_router);
    }

  if (ds.dnsaddr.s_addr != 0)
    {
      dns_setserver(&ds.dnsaddr);
    }

  dhcpc_close(handle);
  printf("IP: %s\n", inet_ntoa(ds.ipaddr));

#endif /* CONFIG_EXAMPLES_TCPECHO_DHCPC */
#endif /* CONFIG_NSH_BUILTIN_APPS */

  return OK;
}
Exemple #26
0
#include "lwip/ip6_addr.h"
#include "lwip/netif.h"
#include "lwip/udp.h"
#include "lwip/timers.h"
#include "nrf_platform_port.h"
#include "app_util_platform.h"

#define DEVICE_NAME                         "LwIPUDPClient"                                         /**< Device name used in BLE undirected advertisement. */

/** Remote UDP Port Address on which data is transmitted. 
 *  Modify m_remote_addr according to your setup.
 *  The address provided below is a place holder.  */
static const ip6_addr_t                     m_remote_addr = 
{
    .addr =
    {HTONL(0x20040000),
    0x00000000,
    HTONL(0x02AABBFF),
    HTONL(0xFECCDDEE)}
};

#define APP_TIMER_PRESCALER                 NRF51_DRIVER_TIMER_PRESCALER                            /**< Value of the RTC1 PRESCALER register. */
#define APP_TIMER_MAX_TIMERS                1                                                       /**< Maximum number of simultaneously created timers. */
#define APP_TIMER_OP_QUEUE_SIZE             1
#define LWIP_SYS_TIMER_INTERVAL             APP_TIMER_TICKS(2000, APP_TIMER_PRESCALER)              /**< Interval for timer used as trigger to send. */

#define ADVERTISING_LED                     BSP_LED_0_MASK                                          /**< Is on when device is advertising. */
#define CONNECTED_LED                       BSP_LED_1_MASK                                          /**< Is on when device is connected. */
#define DISPLAY_LED_0                       BSP_LED_0_MASK                                          /**< LED used for displaying mod 4 of data payload received on UDP port. */
#define DISPLAY_LED_1                       BSP_LED_1_MASK                                          /**< LED used for displaying mod 4 of data payload received on UDP port. */
#define ALL_APP_LED                        (BSP_LED_0_MASK | BSP_LED_1_MASK)                        /**< Define used for simultaneous operation of all application LEDs. */
Exemple #27
0
int webserver_main(int argc, char *argv[])
#endif
{
  struct in_addr addr;
#if defined(CONFIG_EXAMPLES_WEBSERVER_DHCPC) || defined(CONFIG_EXAMPLES_WEBSERVER_NOMAC)
  uint8_t mac[IFHWADDRLEN];
#endif
#ifdef CONFIG_EXAMPLES_WEBSERVER_DHCPC
  void *handle;
#endif

/* Many embedded network interfaces must have a software assigned MAC */

#ifdef CONFIG_EXAMPLES_WEBSERVER_NOMAC
  mac[0] = 0x00;
  mac[1] = 0xe0;
  mac[2] = 0xde;
  mac[3] = 0xad;
  mac[4] = 0xbe;
  mac[5] = 0xef;
  netlib_setmacaddr("eth0", mac);
#endif

  /* Set up our host address */

#ifdef CONFIG_EXAMPLES_WEBSERVER_DHCPC
  addr.s_addr = 0;
#else
  addr.s_addr = HTONL(CONFIG_EXAMPLES_WEBSERVER_IPADDR);
#endif
  netlib_set_ipv4addr("eth0", &addr);

  /* Set up the default router address */

  addr.s_addr = HTONL(CONFIG_EXAMPLES_WEBSERVER_DRIPADDR);
  netlib_set_dripv4addr("eth0", &addr);

  /* Setup the subnet mask */

  addr.s_addr = HTONL(CONFIG_EXAMPLES_WEBSERVER_NETMASK);
  netlib_set_ipv4netmask("eth0", &addr);

#ifdef CONFIG_EXAMPLES_WEBSERVER_DHCPC
  /* Get the MAC address of the NIC */

  netlib_getmacaddr("eth0", mac);

  /* Set up the DHCPC modules */

  handle = dhcpc_open(&mac, IFHWADDRLEN);

  /* Get an IP address.  Note:  there is no logic here for renewing the address in this
   * example.  The address should be renewed in ds.lease_time/2 seconds.
   */

  printf("Getting IP address\n");
  if (handle)
    {
        struct dhcpc_state ds;
        (void)dhcpc_request(handle, &ds);
        netlib_set_ipv4addr("eth0", &ds.ipaddr);

        if (ds.netmask.s_addr != 0)
          {
            netlib_set_ipv4netmask("eth0", &ds.netmask);
          }

        if (ds.default_router.s_addr != 0)
          {
            netlib_set_dripv4addr("eth0", &ds.default_router);
          }

        if (ds.dnsaddr.s_addr != 0)
          {
            netlib_set_ipv4dnsaddr(&ds.dnsaddr);
          }

        dhcpc_close(handle);
        printf("IP: %s\n", inet_ntoa(ds.ipaddr));
    }
#endif

#ifdef CONFIG_NET_TCP
  printf("Starting webserver\n");
  httpd_init();
  cgi_register();
  httpd_listen();
#endif

  while (1)
    {
      sleep(3);
      printf("webserver_main: Still running\n");
#if CONFIG_NFILE_DESCRIPTORS > 0
      fflush(stdout);
#endif
    }

  return 0;
}
Exemple #28
0
/**
  Build the options buffer for the DHCPv6 request packet.

  @param[in]  Private             The pointer to HTTP BOOT driver private data.
  @param[out] OptList             The pointer to the option pointer array.
  @param[in]  Buffer              The pointer to the buffer to contain the option list.

  @return     Index               The count of the built-in options.

**/
UINT32
HttpBootBuildDhcp6Options (
  IN  HTTP_BOOT_PRIVATE_DATA       *Private,
  OUT EFI_DHCP6_PACKET_OPTION      **OptList,
  IN  UINT8                        *Buffer
  )
{
  HTTP_BOOT_DHCP6_OPTION_ENTRY     OptEnt;
  UINT16                           Value;
  UINT32                           Index;

  Index      = 0;
  OptList[0] = (EFI_DHCP6_PACKET_OPTION *) Buffer;

  //
  // Append client option request option
  //
  OptList[Index]->OpCode     = HTONS (HTTP_BOOT_DHCP6_OPT_ORO);
  OptList[Index]->OpLen      = HTONS (8);
  OptEnt.Oro                 = (HTTP_BOOT_DHCP6_OPTION_ORO *) OptList[Index]->Data;
  OptEnt.Oro->OpCode[0]      = HTONS(HTTP_BOOT_DHCP6_OPT_BOOT_FILE_URL);
  OptEnt.Oro->OpCode[1]      = HTONS(HTTP_BOOT_DHCP6_OPT_BOOT_FILE_PARAM);
  OptEnt.Oro->OpCode[2]      = HTONS(HTTP_BOOT_DHCP6_OPT_DNS_SERVERS);
  OptEnt.Oro->OpCode[3]      = HTONS(HTTP_BOOT_DHCP6_OPT_VENDOR_CLASS);
  Index++;
  OptList[Index]             = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);

  //
  // Append client network device interface option
  //
  OptList[Index]->OpCode     = HTONS (HTTP_BOOT_DHCP6_OPT_UNDI);
  OptList[Index]->OpLen      = HTONS ((UINT16)3);
  OptEnt.Undi                = (HTTP_BOOT_DHCP6_OPTION_UNDI *) OptList[Index]->Data;

  if (Private->Nii != NULL) {
    OptEnt.Undi->Type        = Private->Nii->Type;
    OptEnt.Undi->MajorVer    = Private->Nii->MajorVer;
    OptEnt.Undi->MinorVer    = Private->Nii->MinorVer;
  } else {
    OptEnt.Undi->Type        = DEFAULT_UNDI_TYPE;
    OptEnt.Undi->MajorVer    = DEFAULT_UNDI_MAJOR;
    OptEnt.Undi->MinorVer    = DEFAULT_UNDI_MINOR;
  }

  Index++;
  OptList[Index]             = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);

  //
  // Append client system architecture option
  //
  OptList[Index]->OpCode     = HTONS (HTTP_BOOT_DHCP6_OPT_ARCH);
  OptList[Index]->OpLen      = HTONS ((UINT16) sizeof (HTTP_BOOT_DHCP6_OPTION_ARCH));
  OptEnt.Arch                = (HTTP_BOOT_DHCP6_OPTION_ARCH *) OptList[Index]->Data;
  Value                      = HTONS (EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE);
  CopyMem (&OptEnt.Arch->Type, &Value, sizeof (UINT16));
  Index++;
  OptList[Index]             = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);

  //
  // Append vendor class identify option.
  //
  OptList[Index]->OpCode       = HTONS (HTTP_BOOT_DHCP6_OPT_VENDOR_CLASS);
  OptList[Index]->OpLen        = HTONS ((UINT16) sizeof (HTTP_BOOT_DHCP6_OPTION_VENDOR_CLASS));
  OptEnt.VendorClass           = (HTTP_BOOT_DHCP6_OPTION_VENDOR_CLASS *) OptList[Index]->Data;
  OptEnt.VendorClass->Vendor   = HTONL (HTTP_BOOT_DHCP6_ENTERPRISE_NUM);
  OptEnt.VendorClass->ClassLen = HTONS ((UINT16) sizeof (HTTP_BOOT_CLASS_ID));
  CopyMem (
    &OptEnt.VendorClass->ClassId,
    DEFAULT_CLASS_ID_DATA,
    sizeof (HTTP_BOOT_CLASS_ID)
    );
  HttpBootUintnToAscDecWithFormat (
    EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE,
    OptEnt.VendorClass->ClassId.ArchitectureType,
    sizeof (OptEnt.VendorClass->ClassId.ArchitectureType)
    );

  if (Private->Nii != NULL) {
    CopyMem (
      OptEnt.VendorClass->ClassId.InterfaceName,
      Private->Nii->StringId,
      sizeof (OptEnt.VendorClass->ClassId.InterfaceName)
      );
    HttpBootUintnToAscDecWithFormat (
      Private->Nii->MajorVer,
      OptEnt.VendorClass->ClassId.UndiMajor,
      sizeof (OptEnt.VendorClass->ClassId.UndiMajor)
      );
    HttpBootUintnToAscDecWithFormat (
      Private->Nii->MinorVer,
      OptEnt.VendorClass->ClassId.UndiMinor,
      sizeof (OptEnt.VendorClass->ClassId.UndiMinor)
      );
  }

  Index++;

  return Index;
}
Exemple #29
0
tcp_socket_t *
tcp_accept (tcp_socket_t *s)
{
	tcp_socket_t *ns;
	buf_t *p;
	ip_hdr_t *iph;
	tcp_hdr_t *h;
	unsigned long optdata;
again:
	mutex_lock (&s->lock);
	for (;;) {
		if (s->state != LISTEN) {
			mutex_unlock (&s->lock);
			tcp_debug ("tcp_accept: called in invalid state\n");
			return 0;
		}
		if (! tcp_queue_is_empty (s)) {
			p = tcp_queue_get (s);
			break;
		}
		mutex_wait (&s->lock);
	}
	mutex_unlock (&s->lock);

	/* Create a new PCB, and respond with a SYN|ACK.
	 * If a new PCB could not be created (probably due to lack of memory),
	 * we don't do anything, but rely on the sender will retransmit
	 * the SYN at a time when we have more memory available. */
	mutex_lock (&s->ip->lock);
	ns = tcp_alloc (s->ip);
	if (ns == 0) {
		tcp_debug ("tcp_accept: could not allocate PCB\n");
		++s->ip->tcp_in_discards;
		mutex_unlock (&s->ip->lock);
		buf_free (p);
		goto again;
	}
	h = (tcp_hdr_t*) p->payload;
	iph = ((ip_hdr_t*) p->payload) - 1;

	/* Set up the new PCB. */
	memcpy (ns->local_ip, iph->dest, 4);
	ns->local_port = s->local_port;
	memcpy (ns->remote_ip, iph->src, 4);
	ns->remote_port = h->src;
	ns->state = SYN_RCVD;
	ns->rcv_nxt = s->ip->tcp_input_seqno + 1;
	ns->snd_wnd = h->wnd;
	ns->ssthresh = ns->snd_wnd;
	ns->snd_wl1 = s->ip->tcp_input_seqno;
	ns->ip = s->ip;

	/* Register the new PCB so that we can begin receiving
	 * segments for it. */
	tcp_list_add (&s->ip->tcp_sockets, ns);

	/* Parse any options in the SYN. */
	tcp_parseopt (ns, h);

	/* Build an MSS option. */
	optdata = HTONL (((unsigned long)2 << 24) | ((unsigned long)4 << 16) |
		(((unsigned long)ns->mss / 256) << 8) | (ns->mss & 255));
	buf_free (p);

	/* Send a SYN|ACK together with the MSS option. */
	tcp_enqueue (ns, 0, 0, TCP_SYN | TCP_ACK, (unsigned char*) &optdata, 4);
	tcp_output (ns);
	mutex_unlock (&s->ip->lock);
	return ns;
}
Exemple #30
0
void recv_server(void)
{
  struct sockaddr_in server;
  struct sockaddr_in client;
  in_addr_t tmpaddr;
  unsigned char inbuf[1024];
  int sockfd;
  int nbytes;
  int optval;
  int offset;
  socklen_t addrlen;

  /* Create a new UDP socket */

  sockfd = socket(PF_INET, SOCK_DGRAM, 0);
  if (sockfd < 0)
    {
      printf("server: socket failure: %d\n", errno);
      exit(1);
    }

  /* Set socket to reuse address */

  optval = 1;
  if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, sizeof(int)) < 0)
    {
      printf("server: setsockopt SO_REUSEADDR failure: %d\n", errno);
      exit(1);
    }

  /* Bind the socket to a local address */

  server.sin_family      = AF_INET;
  server.sin_port        = HTONS(PORTNO);
  server.sin_addr.s_addr = HTONL(INADDR_ANY);

  if (bind(sockfd, (struct sockaddr*)&server, sizeof(struct sockaddr_in)) < 0)
    {
      printf("server: bind failure: %d\n", errno);
      exit(1);
    }

  /* Then receive up to 256 packets of data */

  for (offset = 0; offset < 256; offset++)
    {
      printf("server: %d. Receiving up 1024 bytes\n", offset);
      addrlen = sizeof(struct sockaddr_in);
      nbytes = recvfrom(sockfd, inbuf, 1024, 0,
                        (struct sockaddr*)&client, &addrlen);

      tmpaddr = ntohl(client.sin_addr.s_addr);
      printf("server: %d. Received %d bytes from %d.%d.%d.%d:%d\n",
             offset, nbytes,
             tmpaddr >> 24, (tmpaddr >> 16) & 0xff,
             (tmpaddr >> 8) & 0xff, tmpaddr & 0xff,
             ntohs(client.sin_port));

      if (nbytes < 0)
        {
          printf("server: %d. recv failed: %d\n", offset, errno);
          close(sockfd);
          exit(-1);
        }

      if (nbytes != SENDSIZE)
        {
          printf("server: %d. recv size incorrect: %d vs %d\n", offset, nbytes, SENDSIZE);
          close(sockfd);
          exit(-1);
        }

      if (offset < inbuf[0])
        {
          printf("server: %d. %d packets lost, resetting offset\n", offset, inbuf[0] - offset);
          offset = inbuf[0];
        }
      else if (offset > inbuf[0])
        {
          printf("server: %d. Bad offset in buffer: %d\n", offset, inbuf[0]);
          close(sockfd);
          exit(-1);
        }

      if (!check_buffer(inbuf))
        {
          printf("server: %d. Bad buffer contents\n", offset);
          close(sockfd);
          exit(-1);
        }
    }
  close(sockfd);
}