1 2 #include "precomp.h" 3 4 #include "lwip/pbuf.h" 5 #include "lwip/netifapi.h" 6 #include "lwip/ip.h" 7 #include "lwip/api.h" 8 #include "lwip/tcpip.h" 9 10 err_t 11 TCPSendDataCallback(struct netif *netif, struct pbuf *p, struct ip_addr *dest) 12 { 13 NDIS_STATUS NdisStatus; 14 PNEIGHBOR_CACHE_ENTRY NCE; 15 IP_PACKET Packet; 16 IP_ADDRESS RemoteAddress, LocalAddress; 17 PIPv4_HEADER Header; 18 ULONG Length; 19 ULONG TotalLength; 20 21 /* The caller frees the pbuf struct */ 22 23 if (((*(u8_t*)p->payload) & 0xF0) == 0x40) 24 { 25 Header = p->payload; 26 27 LocalAddress.Type = IP_ADDRESS_V4; 28 LocalAddress.Address.IPv4Address = Header->SrcAddr; 29 30 RemoteAddress.Type = IP_ADDRESS_V4; 31 RemoteAddress.Address.IPv4Address = Header->DstAddr; 32 } 33 else 34 { 35 return ERR_IF; 36 } 37 38 IPInitializePacket(&Packet, LocalAddress.Type); 39 40 if (!(NCE = RouteGetRouteToDestination(&RemoteAddress))) 41 { 42 return ERR_RTE; 43 } 44 45 NdisStatus = AllocatePacketWithBuffer(&Packet.NdisPacket, NULL, p->tot_len); 46 if (NdisStatus != NDIS_STATUS_SUCCESS) 47 { 48 return ERR_MEM; 49 } 50 51 GetDataPtr(Packet.NdisPacket, 0, (PCHAR*)&Packet.Header, &Packet.TotalSize); 52 Packet.MappedHeader = TRUE; 53 54 ASSERT(Packet.TotalSize == p->tot_len); 55 56 TotalLength = p->tot_len; 57 Length = 0; 58 while (Length < TotalLength) 59 { 60 ASSERT(p->len <= TotalLength - Length); 61 ASSERT(p->tot_len == TotalLength - Length); 62 RtlCopyMemory((PCHAR)Packet.Header + Length, p->payload, p->len); 63 Length += p->len; 64 p = p->next; 65 } 66 ASSERT(Length == TotalLength); 67 68 Packet.HeaderSize = sizeof(IPv4_HEADER); 69 Packet.TotalSize = TotalLength; 70 Packet.SrcAddr = LocalAddress; 71 Packet.DstAddr = RemoteAddress; 72 73 NdisStatus = IPSendDatagram(&Packet, NCE); 74 if (!NT_SUCCESS(NdisStatus)) 75 return ERR_RTE; 76 77 return 0; 78 } 79 80 VOID 81 TCPUpdateInterfaceLinkStatus(PIP_INTERFACE IF) 82 { 83 #if 0 84 ULONG OperationalStatus; 85 86 GetInterfaceConnectionStatus(IF, &OperationalStatus); 87 88 if (OperationalStatus == MIB_IF_OPER_STATUS_OPERATIONAL) 89 netif_set_link_up(IF->TCPContext); 90 else 91 netif_set_link_down(IF->TCPContext); 92 #endif 93 } 94 95 err_t 96 TCPInterfaceInit(struct netif *netif) 97 { 98 PIP_INTERFACE IF = netif->state; 99 100 netif->hwaddr_len = IF->AddressLength; 101 RtlCopyMemory(netif->hwaddr, IF->Address, netif->hwaddr_len); 102 103 netif->output = TCPSendDataCallback; 104 netif->mtu = IF->MTU; 105 106 netif->name[0] = 'e'; 107 netif->name[1] = 'n'; 108 109 netif->flags |= NETIF_FLAG_BROADCAST; 110 111 TCPUpdateInterfaceLinkStatus(IF); 112 113 TCPUpdateInterfaceIPInformation(IF); 114 115 return 0; 116 } 117 118 VOID 119 TCPRegisterInterface(PIP_INTERFACE IF) 120 { 121 struct ip_addr ipaddr; 122 struct ip_addr netmask; 123 struct ip_addr gw; 124 125 gw.addr = 0; 126 ipaddr.addr = 0; 127 netmask.addr = 0; 128 129 IF->TCPContext = netif_add(IF->TCPContext, 130 &ipaddr, 131 &netmask, 132 &gw, 133 IF, 134 TCPInterfaceInit, 135 tcpip_input); 136 } 137 138 VOID 139 TCPUnregisterInterface(PIP_INTERFACE IF) 140 { 141 netif_remove(IF->TCPContext); 142 } 143 144 VOID 145 TCPUpdateInterfaceIPInformation(PIP_INTERFACE IF) 146 { 147 struct ip_addr ipaddr; 148 struct ip_addr netmask; 149 struct ip_addr gw; 150 151 gw.addr = 0; 152 153 GetInterfaceIPv4Address(IF, 154 ADE_UNICAST, 155 (PULONG)&ipaddr.addr); 156 157 GetInterfaceIPv4Address(IF, 158 ADE_ADDRMASK, 159 (PULONG)&netmask.addr); 160 161 netif_set_addr(IF->TCPContext, &ipaddr, &netmask, &gw); 162 163 if (ipaddr.addr != 0) 164 { 165 netif_set_up(IF->TCPContext); 166 netif_set_default(IF->TCPContext); 167 } 168 else 169 { 170 netif_set_down(IF->TCPContext); 171 } 172 } 173