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