xref: /reactos/drivers/network/tcpip/ip/transport/tcp/if.c (revision 09dde2cf)
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