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