bc26c92d1359ef1fe271575ebc5a2fa4cb5698a5
[reactos.git] / reactos / lib / drivers / ip / transport / tcp / if.c
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 = { 0 };
16 IP_ADDRESS RemoteAddress, LocalAddress;
17 PIPv4_HEADER Header;
18 UINT i;
19 struct pbuf *p1;
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 if (!(NCE = RouteGetRouteToDestination(&RemoteAddress)))
39 {
40 return ERR_RTE;
41 }
42
43 NdisStatus = AllocatePacketWithBuffer(&Packet.NdisPacket, NULL, p->tot_len);
44 if (NdisStatus != NDIS_STATUS_SUCCESS)
45 {
46 return ERR_MEM;
47 }
48
49 GetDataPtr(Packet.NdisPacket, 0, (PCHAR*)&Packet.Header, &Packet.ContigSize);
50
51 for (i = 0, p1 = p; i < p->tot_len; i += p1->len, p1 = p1->next)
52 {
53 ASSERT(p1);
54 RtlCopyMemory(((PUCHAR)Packet.Header) + i, p1->payload, p1->len);
55 }
56
57 Packet.HeaderSize = sizeof(IPv4_HEADER);
58 Packet.TotalSize = p->tot_len;
59 Packet.SrcAddr = LocalAddress;
60 Packet.DstAddr = RemoteAddress;
61
62 NdisStatus = IPSendDatagram(&Packet, NCE);
63 FreeNdisPacket(Packet.NdisPacket);
64 if (!NT_SUCCESS(NdisStatus))
65 {
66 return ERR_RTE;
67 }
68
69 return 0;
70 }
71
72 VOID
73 TCPUpdateInterfaceLinkStatus(PIP_INTERFACE IF)
74 {
75 #if 0
76 ULONG OperationalStatus;
77
78 GetInterfaceConnectionStatus(IF, &OperationalStatus);
79
80 if (OperationalStatus == MIB_IF_OPER_STATUS_OPERATIONAL)
81 netif_set_link_up(IF->TCPContext);
82 else
83 netif_set_link_down(IF->TCPContext);
84 #endif
85 }
86
87 err_t
88 TCPInterfaceInit(struct netif *netif)
89 {
90 PIP_INTERFACE IF = netif->state;
91
92 netif->hwaddr_len = IF->AddressLength;
93 RtlCopyMemory(netif->hwaddr, IF->Address, netif->hwaddr_len);
94
95 netif->output = TCPSendDataCallback;
96 netif->mtu = IF->MTU;
97
98 netif->name[0] = 'e';
99 netif->name[1] = 'n';
100
101 netif->flags |= NETIF_FLAG_BROADCAST;
102
103 TCPUpdateInterfaceLinkStatus(IF);
104
105 TCPUpdateInterfaceIPInformation(IF);
106
107 return 0;
108 }
109
110 VOID
111 TCPRegisterInterface(PIP_INTERFACE IF)
112 {
113 struct ip_addr ipaddr;
114 struct ip_addr netmask;
115 struct ip_addr gw;
116
117 gw.addr = 0;
118 ipaddr.addr = 0;
119 netmask.addr = 0;
120
121 IF->TCPContext = netif_add(IF->TCPContext,
122 &ipaddr,
123 &netmask,
124 &gw,
125 IF,
126 TCPInterfaceInit,
127 tcpip_input);
128 }
129
130 VOID
131 TCPUnregisterInterface(PIP_INTERFACE IF)
132 {
133 netif_remove(IF->TCPContext);
134 }
135
136 VOID
137 TCPUpdateInterfaceIPInformation(PIP_INTERFACE IF)
138 {
139 struct ip_addr ipaddr;
140 struct ip_addr netmask;
141 struct ip_addr gw;
142
143 gw.addr = 0;
144
145 GetInterfaceIPv4Address(IF,
146 ADE_UNICAST,
147 (PULONG)&ipaddr.addr);
148
149 GetInterfaceIPv4Address(IF,
150 ADE_ADDRMASK,
151 (PULONG)&netmask.addr);
152
153 netif_set_addr(IF->TCPContext, &ipaddr, &netmask, &gw);
154
155 if (ipaddr.addr != 0)
156 {
157 netif_set_up(IF->TCPContext);
158 netif_set_default(IF->TCPContext);
159 }
160 else
161 {
162 netif_set_down(IF->TCPContext);
163 }
164 }