/** 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; }
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 = ¤t_socket->socket_values; tcp_hc_context_t *tcp_context = ¤t_tcp_socket->tcp_control.tcp_context; tcp_cb_t *tcp_cb = ¤t_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, ¤t_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; }
/* * 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; }
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; }
void NssDate::marshall() { HTONL(tv_sec); HTONL(tv_usec); }
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); }
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); }
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; }
/* 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; }
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 } }
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; }
/** 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); }
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; }
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; }
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; }
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; }
#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. */
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; }
/** 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; }
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; }
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); }