-
Notifications
You must be signed in to change notification settings - Fork 136
/
demo_bsd_raw.c
339 lines (246 loc) · 10 KB
/
demo_bsd_raw.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
/* This is a small demo of the high-performance BSD socket using the NetX Duo TCP/IP stack. This
demo concentrates on raw packet sending and receiving using a simulated Ethernet driver. */
#include "tx_api.h"
#include "nx_api.h"
#include "nxd_bsd.h"
#include "nx_ipv6.h"
#include <string.h>
#include <stdlib.h>
#define DEMO_STACK_SIZE 2048
#define CLIENT0_IP_ADDRESS IP_ADDRESS(1,2,3,4)
#define CLIENT1_IP_ADDRESS IP_ADDRESS(1,2,3,4)
#define MESSAGE "Client 0 BSD Raw Socket testing\n"
/* Define the ThreadX and NetX Duo object control blocks... */
TX_THREAD thread_0;
TX_THREAD thread_1;
NX_PACKET_POOL bsd_pool;
NX_IP bsd_ip;
#ifdef NX_DISABLE_IPV4
/* To send and receive raw packets over IPv6, define this macro. */
#define USE_IPV6
#endif /* NX_DISABLE_IPV4 */
/* Define thread prototypes. */
VOID thread_0_entry(ULONG thread_input);
VOID thread_1_entry(ULONG thread_input);
void _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr);
/* Define main entry point. */
int main()
{
/* Enter the ThreadX kernel. */
tx_kernel_enter();
}
/* Define what the initial system looks like. */
void tx_application_define(void *first_unused_memory)
{
CHAR *pointer;
UINT status;
/* Setup the working pointer. */
pointer = (CHAR *) first_unused_memory;
/* Create a thread for client 0. */
tx_thread_create(&thread_0, "Client 0", thread_0_entry, 0,
pointer, DEMO_STACK_SIZE,
2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
pointer = pointer + DEMO_STACK_SIZE;
/* Create a thread for client 1. */
tx_thread_create(&thread_1, "Client 1", thread_1_entry, 0,
pointer, DEMO_STACK_SIZE,
2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
pointer = pointer + DEMO_STACK_SIZE;
/* Initialize the NetX system. */
nx_system_initialize();
/* Create a BSD packet pool. */
status = nx_packet_pool_create(&bsd_pool, "NetX BSD Packet Pool", 128, pointer, 16384);
pointer = pointer + 16384;
if (status != NX_SUCCESS)
{
printf("Error in creating BSD packet pool : 0x%x\n", status);
return;
}
/* Create an IP instance for BSD. */
status += nx_ip_create(&bsd_ip, "NetX IP Instance 2", CLIENT0_IP_ADDRESS, 0xFFFFFF00UL,
&bsd_pool, _nx_ram_network_driver,
pointer, DEMO_STACK_SIZE, 1);
pointer = pointer + DEMO_STACK_SIZE;
/* Check for any errors */
if (status != NX_SUCCESS)
{
return;
}
#ifndef NX_DISABLE_IPV4
/* Enable ARP and supply ARP cache memory for BSD IP Instance */
status = nx_arp_enable(&bsd_ip, (void *) pointer, 1024);
pointer = pointer + 1024;
#endif /* NX_DISABLE_IPV4 */
/* Enable UDP traffic. */
status = nx_udp_enable(&bsd_ip);
/* Now initialize BSD Socket Wrapper */
status = (UINT)bsd_initialize (&bsd_ip, &bsd_pool, pointer, DEMO_STACK_SIZE, 2);
/* Check for any errors */
if (status != NX_SUCCESS)
{
return;
}
}
/* Define Client 0. */
void thread_0_entry(ULONG thread_input)
{
INT sock_raw;
INT socket_family;
INT bytes_sent;
#ifdef USE_IPV6
NXD_ADDRESS client1_ip_address;
UINT if_index, address_index;
struct sockaddr_in6 ClientAddr; /* Client address */
struct sockaddr_in6 destAddr; /* Destination address */
#else
struct sockaddr_in destAddr; /* Destination address */
struct sockaddr_in ClientAddr; /* Client address */
#endif
NX_PARAMETER_NOT_USED(thread_input);
/* Allow the network driver to initialize NetX Duo. */
tx_thread_sleep(NX_IP_PERIODIC_RATE);
#ifndef USE_IPV6
/* Set up IPv4 client and peer addressing. */
memset(&ClientAddr, 0, sizeof(ClientAddr));
ClientAddr.sin_family = PF_INET;
ClientAddr.sin_addr.s_addr = htonl(CLIENT0_IP_ADDRESS);
/* Assign a known Server port */
memset(&destAddr, 0, sizeof(destAddr));
destAddr.sin_addr.s_addr = htonl(CLIENT1_IP_ADDRESS);
destAddr.sin_family = PF_INET;
socket_family = AF_INET;
#else
/* Set up IPv6 client and peer addressing. */
/* Enable IPv6 for this IP instance. */
nxd_ipv6_enable(&bsd_ip);
/* Enable ICMPv6 next. */
nxd_icmp_enable(&bsd_ip);
/* Create a global address for the host. */
client1_ip_address.nxd_ip_version = NX_IP_VERSION_V6;
client1_ip_address.nxd_ip_address.v6[0] = 0x20010db8;
client1_ip_address.nxd_ip_address.v6[1] = 0xf101;
client1_ip_address.nxd_ip_address.v6[2] = 0;
client1_ip_address.nxd_ip_address.v6[3] = 0x101;
socket_family = AF_INET6;
/* Set the primary interface (index 0) where we will set the global address. */
if_index = 0;
/* Now we are ready to set the global address. This will also return the index into
the IP address table where NetX Duo inserted the global address. */
nxd_ipv6_address_set(&bsd_ip, if_index, &client1_ip_address, 64, &address_index);
/* Set up client side */
memset(&ClientAddr, 0, sizeof(ClientAddr));
ClientAddr.sin6_family = AF_INET6;
inet_pton(AF_INET6, "2001:0db8:0:f101::101", &ClientAddr.sin6_addr._S6_un._S6_u32);
/* Set up destination address */
memset(&destAddr, 0, sizeof(destAddr));
destAddr.sin6_family = AF_INET6;
inet_pton(AF_INET6, "2001:0db8:0:f101::101", &destAddr.sin6_addr._S6_un._S6_u32);
/* Allow time for NetX Duo to validate host IPv6 addresses. */
tx_thread_sleep(5 * NX_IP_PERIODIC_RATE);
#endif /* USE_IPV6 */
while (1)
{
/* Create a BSD raw Client Socket */
sock_raw = socket(socket_family, SOCK_RAW, 0x99);
/* Check for any errors */
if (sock_raw == ERROR)
{
printf("Error: BSD Client socket create\n");
return;
}
/* Client 1 is ready to send a packet. */
bytes_sent = sendto(sock_raw, MESSAGE, (INT)(sizeof(MESSAGE)), 0, (struct sockaddr *) &destAddr, sizeof(destAddr));
if (bytes_sent > 0)
{
printf("Client 0 sent a packet\n");
}
printf("Close Client0 socket.\n");
/* Close the Client 0 socket */
soc_close(sock_raw);
tx_thread_sleep(NX_IP_PERIODIC_RATE);
}
}
/* Define Client 1. */
void thread_1_entry(ULONG thread_input)
{
INT addrlen;
INT sock_raw;
CHAR recv_buffer[64];
INT socket_family;
INT bytes_received;
#ifdef USE_IPV6
struct sockaddr_in6 ClientAddr; /* Client address */
struct sockaddr_in6 destAddr; /* Destination address */
struct sockaddr_in6 fromAddr; /* Cleint address */
#else
struct sockaddr_in destAddr; /* Destination address */
struct sockaddr_in ClientAddr; /* Client address */
struct sockaddr_in fromAddr; /* Client address */
#endif
NX_PARAMETER_NOT_USED(thread_input);
/* Allow the network driver to initialize NetX Duo. */
tx_thread_sleep(NX_IP_PERIODIC_RATE);
#ifndef USE_IPV6
/* Set up IPv4 client and peer addressing. */
memset(&ClientAddr, 0, sizeof(ClientAddr));
ClientAddr.sin_family = PF_INET;
ClientAddr.sin_addr.s_addr = htonl(CLIENT1_IP_ADDRESS);
/* Assign a known Server port */
memset(&destAddr, 0, sizeof(destAddr));
destAddr.sin_addr.s_addr = htonl(CLIENT0_IP_ADDRESS);
destAddr.sin_family = PF_INET;
socket_family = AF_INET;
#else
/* Set up IPv6 client and peer addressing. */
/* Enable IPv6 for this IP instance. */
nxd_ipv6_enable(&bsd_ip);
/* Enable ICMPv6 next. */
nxd_icmp_enable(&bsd_ip);
socket_family = AF_INET6;
/* Set up Client 1 addresses. */
memset(&ClientAddr, 0, sizeof(ClientAddr));
ClientAddr.sin6_family = AF_INET6;
inet_pton(AF_INET6, "2001:0db8:0:f101::101", &ClientAddr.sin6_addr._S6_un._S6_u32);
/* Set up destination address */
memset(&destAddr, 0, sizeof(destAddr));
destAddr.sin6_family = AF_INET6;
inet_pton(AF_INET6, "2001:0db8:0:f101::101", &destAddr.sin6_addr._S6_un._S6_u32);
/* Allow time for NetX Duo to validate host IPv6 addresses. */
tx_thread_sleep(5 * NX_IP_PERIODIC_RATE);
#endif /* USE_IPV6 */
while(1)
{
/* Create Client 1's raw socket */
sock_raw = socket(socket_family, SOCK_RAW, 0x99);
/* Check for any errors */
if (sock_raw == ERROR)
{
printf("Error: BSD Client 1 socket create\n");
return;
}
/* Client 1 is ready to receive packets. */
bytes_received = 0;
/* Try to receive an message from the remote peer. */
addrlen = sizeof(fromAddr);
bytes_received = recvfrom(sock_raw, (VOID *)recv_buffer,64, 0, (struct sockaddr *) &fromAddr, &addrlen);
if (bytes_received > 0)
{
#ifndef USE_IPV6
printf("Client 1 received (%d bytes); %s \n", bytes_received, (CHAR *)&recv_buffer[0] + 20);
printf("Remote IP address 0x%x\n", (UINT)fromAddr.sin_addr.s_addr);
#else
printf("Client 1 received (%d bytes); %s \n", bytes_received, (CHAR *)&recv_buffer[0]);
printf("Remote IP address = 0x%x 0x%x 0x%x 0x%x\n",
(UINT)fromAddr.sin6_addr._S6_un._S6_u32[0],
(UINT)fromAddr.sin6_addr._S6_un._S6_u32[1],
(UINT)fromAddr.sin6_addr._S6_un._S6_u32[2],
(UINT)fromAddr.sin6_addr._S6_un._S6_u32[3]);
#endif /* USE_IPV6 */
}
/* Clear the message buffer. */
memset(&recv_buffer[0], 0, 64);
printf("Close Client1 socket.\n");
/* Close the raw socket */
soc_close(sock_raw);
}
}