master
c 5,394 lines 185 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 netlink.c
8
9 Abstract:
10
11 Linux socket test for the AF_NETLINK family.
12
13 --*/
14
15 #include "lxtcommon.h"
16 #include "unittests.h"
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <sys/un.h>
24 #include <sys/ioctl.h>
25 #include <net/if.h>
26 #include <net/if_arp.h>
27 #include <arpa/inet.h>
28 #include <netinet/in.h>
29 #include <netinet/ip.h>
30 #include <netinet/udp.h>
31 #include <netinet/tcp.h>
32 #include <linux/icmp.h>
33 #include <netinet/icmp6.h>
34 #include <net/if.h>
35 #include <netdb.h>
36 #include <fcntl.h>
37 #include <time.h>
38 #include <pthread.h>
39 #include <poll.h>
40 #include <sys/epoll.h>
41 #include <sys/time.h>
42 #include <sys/prctl.h>
43 #include <asm/types.h>
44 #include <linux/netlink.h>
45 #include <linux/rtnetlink.h>
46 #include "common.h"
47
48 #define LXT_NAME "Netlink"
49
50 #define ATTRIBUTE_DUMP_BUFFER_SIZE 60
51
52 #define min(a, b) (((a) < (b)) ? (a) : (b))
53
54 #define SOCKET_LOOPBACK_IF_NAME "lo"
55
56 #define NLMSG_TAIL(nmsg) ((struct rtattr*)(((void*)(nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
57
58 const int MessageTypes[] = {
59 RTM_DELADDR, RTM_DELLINK, RTM_DELROUTE, RTM_GETADDR, RTM_GETLINK, RTM_GETNSID, RTM_GETROUTE, RTM_NEWADDR, RTM_NEWLINK, RTM_NEWROUTE, RTM_SETLINK};
60
61 const int SupportedFamily[] = {NETLINK_ROUTE};
62 const int SupportedType[] = {SOCK_DGRAM, SOCK_RAW};
63
64 typedef struct _NetlinkRecvmmsgBlockedReaderParams
65 {
66 int Socket;
67 int Option;
68 } NetlinkRecvmmsgBlockedReaderParams;
69
70 typedef struct _BindChildThreadReturn
71 {
72 pid_t nl_pid;
73 } BindChildThreadReturn;
74
75 LXT_VARIATION_HANDLER SocketNetlinkOpenClose;
76 LXT_VARIATION_HANDLER SocketNetlinkBasic;
77 LXT_VARIATION_HANDLER SocketNetlinkBind;
78 LXT_VARIATION_HANDLER SocketNetlinkBindThread;
79 LXT_VARIATION_HANDLER SocketNetlinkSendReceive;
80 LXT_VARIATION_HANDLER SocketNetlinkSendReceiveOverflow;
81 LXT_VARIATION_HANDLER SocketNetlinkBlockedReader;
82 LXT_VARIATION_HANDLER SocketNetlinkEpoll;
83 LXT_VARIATION_HANDLER SocketNetlinkRecvmmsg;
84 LXT_VARIATION_HANDLER SocketNetlinkSendBadMessage;
85 LXT_VARIATION_HANDLER SocketNetlinkRouteGetAddr;
86 LXT_VARIATION_HANDLER SocketNetlinkRouteGetLink;
87 LXT_VARIATION_HANDLER SocketNetlinkRouteGetRouteBestRoute;
88 LXT_VARIATION_HANDLER SocketNetlinkRouteGetRouteDump;
89 LXT_VARIATION_HANDLER SocketNetlinkRouteNewDelAddress;
90 LXT_VARIATION_HANDLER SocketNetlinkRouteNewDelRoute;
91 LXT_VARIATION_HANDLER SocketNetlinkSoPasscred;
92
93 void* SocketNetlinkBindThreadChild(void* Arg);
94
95 bool SocketNetlinkIsIpv6Configured();
96
97 void* SocketNetlinkRecvmmsgBlockedReaderThread(void* Arg);
98
99 void SocketNetlinkRouteDumpAttributeData(char* Buffer, int BufferSize, struct rtattr* Attribute);
100
101 int SocketNetlinkRouteGetLinkCheckResponse(int Socket, int OnlyOneLoopback);
102
103 int SocketNetlinkRouteGetRouteBestRouteCheckResponse(int Socket, int CheckGateway);
104
105 int SocketNetlinkGetLoopbackIndex();
106
107 int SocketNetlinkCheckResponseError(void* ReceiveBuffer, int ReceiveResult, int Error);
108
109 int SocketNetlinkRouteAddAttribute(struct nlmsghdr* Msghdr, int MessageSize, int AttributeType, void* AttributeData, int AttributeSize);
110
111 void SocketNetlinkRouteAddAddressAttributes(struct nlmsghdr* Msghdr, int MessageSize, struct in_addr* AddressIpv4);
112
113 void SocketNetlinkRouteAddRouteAttributes(
114 struct nlmsghdr* Msghdr, int MessageSize, struct in_addr* DestinationIpv4, struct in_addr* GatewayIpv4, int InterfaceIndex);
115
116 int SocketNetlinkSendAndWaitForExpectedError(int Socket, void* Request, int RequestSize, int ExpectedError);
117
118 int SocketNetlinkSetAndVerifySocketOptionTimeout(int Socket, int SocketOption, int Usec);
119
120 static const LXT_VARIATION g_LxtVariations[] = {
121 {"Open, close", SocketNetlinkOpenClose},
122 {"Basic netlink operations", SocketNetlinkBasic},
123 {"bind, getsockname (with fork)", SocketNetlinkBind},
124 {"bind, getsockname (with pthread_create)", SocketNetlinkBindThread},
125 {"Send and receive basic (sending to kernel)", SocketNetlinkSendReceive},
126 {"Send and receive where the receive buffer overflows (sending to kernel)", SocketNetlinkSendReceiveOverflow},
127 {"Blocked reader thread", SocketNetlinkBlockedReader},
128 {"epoll", SocketNetlinkEpoll},
129 {"Recvmmsg syscall", SocketNetlinkRecvmmsg},
130 {"Sending bad Netlink messages", SocketNetlinkSendBadMessage},
131 {"NETLINK_ROUTE RTM_GETADDR message", SocketNetlinkRouteGetAddr},
132 {"NETLINK_ROUTE RTM_GETLINK message", SocketNetlinkRouteGetLink},
133 {"NETLINK_ROUTE RTM_GETROUTE message - get best route", SocketNetlinkRouteGetRouteBestRoute},
134 {"NETLINK_ROUTE RTM_GETROUTE message - dump all routing entries", SocketNetlinkRouteGetRouteDump},
135 {"NETLINK_ROUTE RTM_NEWADDR and RTM_DELADDR message", SocketNetlinkRouteNewDelAddress},
136 {"NETLINK_ROUTE RTM_NEWROUTE and RTM_DELROUTE message", SocketNetlinkRouteNewDelRoute},
137 {"SO_PASSCRED", SocketNetlinkSoPasscred},
138 };
139
140 //
141 // Function definitions.
142 //
143
144 int NetlinkTestEntry(int Argc, char* Argv[])
145
146 /*++
147
148 Routine Description:
149
150 This routine main entry point for the test for get*id,set*id system call.
151
152 Arguments:
153
154 Argc - Supplies the number of command line arguments.
155
156 Argv - Supplies the command line arguments.
157
158 Return Value:
159
160 Returns 0 on success, -1 on failure.
161
162 --*/
163
164 {
165
166 LXT_ARGS Args;
167 int Result;
168
169 LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME));
170
171 //
172 // Run test cases.
173 //
174
175 LxtCheckResult(LxtRunVariations(&Args, g_LxtVariations, LXT_COUNT_OF(g_LxtVariations)));
176
177 ErrorExit:
178 LxtUninitialize();
179 return !LXT_SUCCESS(Result);
180 }
181
182 bool SocketNetlinkIsIpv6Configured()
183
184 /*++
185
186 Routine Description:
187
188 This routine checks if an IPv6 address has been configured.
189
190 Arguments:
191
192 None.
193
194 Return Value:
195
196 Returns true if an IPv6 address is available.
197
198 --*/
199
200 {
201
202 socklen_t AddressLength;
203 struct rtattr* Attribute;
204 char AttributeDump[ATTRIBUTE_DUMP_BUFFER_SIZE];
205 struct sockaddr_nl BindAddress;
206 int FoundDone;
207 struct nlmsghdr* Header;
208 struct ifaddrmsg* IfAddrMsg;
209 bool IpV6AddressValid;
210 int LoopbackIndex;
211 char ReceiveBuffer[5000];
212 int ReceiveResult;
213 int RemainingLength;
214 int Result;
215 int Socket;
216
217 struct
218 {
219 struct nlmsghdr nlh;
220 struct ifinfomsg ifm;
221 struct rtattr ext_req __attribute__((aligned(NLMSG_ALIGNTO)));
222 __u32 ext_filter_mask;
223 } Request;
224
225 IpV6AddressValid = false;
226
227 LxtCheckErrnoZeroSuccess(SocketNetlinkGetLoopbackIndex(&LoopbackIndex));
228
229 //
230 // Create and bind socket. Create a RTM_GETADDR request.
231 //
232
233 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
234 memset(&BindAddress, 0, sizeof(BindAddress));
235 BindAddress.nl_family = AF_NETLINK;
236 AddressLength = sizeof(BindAddress);
237 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
238
239 memset(&Request, 0, sizeof(Request));
240 Request.nlh.nlmsg_len = sizeof(Request);
241 Request.nlh.nlmsg_type = RTM_GETADDR;
242 Request.nlh.nlmsg_seq = 0x4563;
243 Request.ifm.ifi_family = AF_NETLINK;
244 Request.ext_req.rta_type = IFLA_EXT_MASK;
245 Request.ext_req.rta_len = RTA_LENGTH(sizeof(__u32));
246 Request.ext_filter_mask = RTEXT_FILTER_VF;
247 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
248 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
249 FoundDone = 0;
250 for (;;)
251 {
252 LxtCheckErrno(ReceiveResult = recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, NULL, 0));
253
254 Header = (struct nlmsghdr*)ReceiveBuffer;
255 while (!IpV6AddressValid && NLMSG_OK(Header, ReceiveResult))
256 {
257 if (Header->nlmsg_type == NLMSG_DONE)
258 {
259 FoundDone = 1;
260 break;
261 }
262
263 IfAddrMsg = (struct ifaddrmsg*)NLMSG_DATA(Header);
264 if ((IfAddrMsg->ifa_index != LoopbackIndex) && (IfAddrMsg->ifa_family == AF_INET6))
265 {
266
267 Attribute = (struct rtattr*)((char*)IfAddrMsg + sizeof(struct ifaddrmsg));
268
269 RemainingLength = Header->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg));
270
271 while (RTA_OK(Attribute, RemainingLength))
272 {
273 SocketNetlinkRouteDumpAttributeData(AttributeDump, ATTRIBUTE_DUMP_BUFFER_SIZE, Attribute);
274
275 //
276 // If the address is IPv6 and does not start with the link
277 // local prefix, assume it is a valid address.
278 //
279
280 if ((Attribute->rta_type == IFA_ADDRESS) && strncmp(AttributeDump, "fe 80", 5) != 0)
281 {
282
283 LxtLogInfo("IpV6 address found: %s", AttributeDump);
284 IpV6AddressValid = true;
285 break;
286 }
287
288 Attribute = RTA_NEXT(Attribute, RemainingLength);
289 }
290 }
291
292 Header = NLMSG_NEXT(Header, ReceiveResult);
293 }
294
295 if (IpV6AddressValid || (FoundDone == 1))
296 {
297 break;
298 }
299 }
300
301 ErrorExit:
302 if (Socket > 0)
303 {
304 close(Socket);
305 }
306
307 return IpV6AddressValid;
308 }
309
310 int SocketNetlinkOpenClose(PLXT_ARGS Args)
311
312 /*++
313
314 Routine Description:
315
316 This routine tests the socket() API.
317
318 Arguments:
319
320 Args - Supplies the command line arguments.
321
322 Return Value:
323
324 Returns 0 on success, -1 on failure.
325
326 --*/
327
328 {
329
330 int FamilyIterator;
331 int Result;
332 int Socket;
333 int TypeIterator;
334
335 Result = LXT_RESULT_FAILURE;
336 Socket = -1;
337
338 for (TypeIterator = 0; TypeIterator < sizeof(SupportedType) / sizeof(int); TypeIterator++)
339 {
340
341 for (FamilyIterator = 0; FamilyIterator < sizeof(SupportedFamily) / sizeof(int); FamilyIterator++)
342 {
343
344 LxtLogInfo("testing type: %d, netlink family: %d", SupportedType[TypeIterator], SupportedFamily[FamilyIterator]);
345
346 //
347 // Success cases.
348 //
349
350 LxtCheckErrno((Socket = socket(AF_NETLINK, SupportedType[TypeIterator], SupportedFamily[FamilyIterator])));
351
352 LxtClose(Socket);
353
354 //
355 // Test case: Overloading 'type' field for netlink sockets.
356 //
357
358 LxtCheckErrno((Socket = socket(AF_NETLINK, SupportedType[TypeIterator] | O_NONBLOCK, SupportedFamily[FamilyIterator])));
359
360 LxtClose(Socket);
361 LxtCheckErrno((Socket = socket(AF_NETLINK, SupportedType[TypeIterator] | O_CLOEXEC, SupportedFamily[FamilyIterator])));
362
363 LxtClose(Socket);
364 LxtCheckErrno((Socket = socket(AF_NETLINK, SupportedType[TypeIterator] | O_NONBLOCK | O_CLOEXEC, SupportedFamily[FamilyIterator])));
365
366 LxtClose(Socket);
367 }
368 }
369
370 //
371 // Test case: Failure cases for socket(), unsupported type, family.
372 //
373
374 LxtCheckErrnoFailure(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE + 100), EPROTONOSUPPORT);
375
376 LxtCheckErrnoFailure(socket(AF_NETLINK, SOCK_STREAM, NETLINK_ROUTE), ESOCKTNOSUPPORT);
377
378 ErrorExit:
379 if (Socket > 0)
380 {
381 close(Socket);
382 }
383
384 return Result;
385 }
386
387 int SocketNetlinkBasic(PLXT_ARGS Args)
388
389 /*++
390
391 Routine Description:
392
393 This routine tests basic operations on netlink sockets.
394
395 Arguments:
396
397 Args - Supplies the command line arguments.
398
399 Return Value:
400
401 Returns 0 on success, -1 on failure.
402
403 --*/
404
405 {
406
407 socklen_t AddressLength;
408 struct sockaddr_nl BindAddress;
409 int BufferSize;
410 int FamilyIterator;
411 socklen_t OptionLength;
412 int OptionInt;
413 char ReceiveBuffer[500];
414 int Result;
415 int Socket;
416 int SocketError;
417 struct timeval Timeout;
418 int TypeIterator;
419
420 Result = LXT_RESULT_FAILURE;
421 Socket = -1;
422
423 for (TypeIterator = 0; TypeIterator < sizeof(SupportedType) / sizeof(int); TypeIterator++)
424 {
425
426 for (FamilyIterator = 0; FamilyIterator < sizeof(SupportedFamily) / sizeof(int); FamilyIterator++)
427 {
428
429 LxtCheckErrno(Socket = socket(AF_NETLINK, SupportedType[TypeIterator], SupportedFamily[FamilyIterator]));
430
431 memset(&BindAddress, 0, sizeof(BindAddress));
432 BindAddress.nl_family = AF_NETLINK;
433 AddressLength = sizeof(BindAddress);
434 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
435 OptionLength = sizeof(BufferSize);
436 BufferSize = 2345;
437 LxtCheckErrno(setsockopt(Socket, SOL_SOCKET, SO_SNDBUF, &BufferSize, OptionLength));
438
439 LxtCheckErrno(getsockopt(Socket, SOL_SOCKET, SO_SNDBUF, &BufferSize, &OptionLength));
440
441 LxtCheckEqual(OptionLength, sizeof(BufferSize), "%d");
442 LxtCheckEqual(BufferSize, 2345 * 2, "%d");
443
444 OptionLength = sizeof(BufferSize);
445 BufferSize = 6345;
446 LxtCheckErrno(setsockopt(Socket, SOL_SOCKET, SO_RCVBUF, &BufferSize, OptionLength));
447
448 LxtCheckErrno(getsockopt(Socket, SOL_SOCKET, SO_RCVBUF, &BufferSize, &OptionLength));
449
450 LxtCheckEqual(OptionLength, sizeof(BufferSize), "%d");
451 LxtCheckEqual(BufferSize, 6345 * 2, "%d");
452
453 //
454 // Set a timeout value of 8 milliseconds for the send.
455 //
456
457 LxtCheckResult(SocketNetlinkSetAndVerifySocketOptionTimeout(Socket, SO_SNDTIMEO, 8000));
458
459 //
460 // Set a timeout value of 8 milliseconds for the receive.
461 //
462
463 LxtCheckResult(SocketNetlinkSetAndVerifySocketOptionTimeout(Socket, SO_RCVTIMEO, 8000));
464
465 //
466 // Check that the blocking read will timeout with EAGAIN
467 // after 8 milliseconds.
468 //
469
470 LxtCheckErrnoFailure(read(Socket, ReceiveBuffer, sizeof(ReceiveBuffer)), EAGAIN);
471
472 //
473 // Check that the value of SO_ERROR is 0 (no error).
474 //
475
476 SocketError = 1234;
477 OptionLength = sizeof(SocketError);
478 LxtCheckErrno(getsockopt(Socket, SOL_SOCKET, SO_ERROR, &SocketError, &OptionLength));
479
480 LxtCheckEqual(OptionLength, sizeof(SocketError), "%d");
481 LxtCheckEqual(SocketError, 0, "%d");
482
483 OptionLength = sizeof(OptionInt);
484 LxtCheckErrno(getsockopt(Socket, SOL_SOCKET, SO_TYPE, &OptionInt, &OptionLength));
485
486 LxtCheckEqual(OptionLength, sizeof(OptionInt), "%d");
487 LxtCheckEqual(OptionInt, SupportedType[TypeIterator], "%d");
488
489 OptionLength = sizeof(OptionInt);
490 LxtCheckErrno(getsockopt(Socket, SOL_SOCKET, SO_PROTOCOL, &OptionInt, &OptionLength));
491
492 LxtCheckEqual(OptionLength, sizeof(OptionInt), "%d");
493 LxtCheckEqual(OptionInt, SupportedFamily[FamilyIterator], "%d");
494
495 OptionLength = sizeof(OptionInt);
496 LxtCheckErrno(getsockopt(Socket, SOL_SOCKET, SO_DOMAIN, &OptionInt, &OptionLength));
497
498 LxtCheckEqual(OptionLength, sizeof(OptionInt), "%d");
499 LxtCheckEqual(OptionInt, AF_NETLINK, "%d");
500 LxtClose(Socket);
501 }
502 }
503
504 ErrorExit:
505 if (Socket > 0)
506 {
507 close(Socket);
508 }
509
510 return Result;
511 }
512
513 int SocketNetlinkBind(PLXT_ARGS Args)
514
515 /*++
516
517 Routine Description:
518
519 This routine tests the bind() API.
520
521 Arguments:
522
523 Args - Supplies the command line arguments.
524
525 Return Value:
526
527 Returns 0 on success, -1 on failure.
528
529 --*/
530
531 {
532
533 char AddressBuffer[150];
534 socklen_t AddressLength;
535 int ArrayIterator;
536 int ArrayIterator2;
537 const int ArraySize = 10;
538 struct sockaddr_nl BindAddress;
539 struct sockaddr_nl* BindAddressP;
540 int ChildPid;
541 char DataBuffer[10];
542 int Family;
543 int FamilyIterator;
544 int Result;
545 uint32_t SavedPid;
546 int Socket;
547 int Socket2;
548 int Socket3;
549 int Socket4;
550 int SocketA[ArraySize];
551 int SocketChildA[ArraySize];
552 int SocketChildPid[ArraySize];
553 int SocketPid[ArraySize];
554 int Type;
555 int TypeIterator;
556
557 Result = LXT_RESULT_FAILURE;
558 Socket = -1;
559 Socket2 = -1;
560 Socket3 = -1;
561 Socket4 = -1;
562 ChildPid = -1;
563 for (TypeIterator = 0; TypeIterator < sizeof(SupportedType) / sizeof(int); TypeIterator++)
564 {
565
566 Type = SupportedType[TypeIterator];
567 for (FamilyIterator = 0; FamilyIterator < sizeof(SupportedFamily) / sizeof(int); FamilyIterator++)
568 {
569
570 //
571 // First thing; initialize the various array.
572 //
573
574 for (ArrayIterator = 0; ArrayIterator < ArraySize; ArrayIterator++)
575 {
576 SocketA[ArrayIterator] = 0;
577 SocketPid[ArrayIterator] = 0;
578 SocketChildPid[ArrayIterator] = 0;
579 }
580
581 Family = SupportedFamily[FamilyIterator];
582 LxtLogInfo("testing type: %d, netlink family: %d", SupportedType[TypeIterator], SupportedFamily[FamilyIterator]);
583
584 //
585 // Test case: bind with invalid family value in the address.
586 //
587
588 LxtCheckErrno(Socket = socket(AF_NETLINK, Type, Family));
589 memset(&BindAddress, 0, sizeof(BindAddress));
590 BindAddress.nl_family = AF_INET;
591 AddressLength = sizeof(BindAddress);
592 LxtCheckErrnoFailure(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength), EINVAL);
593
594 LxtClose(Socket);
595
596 //
597 // Test case: bind with invalid address length.
598 //
599
600 LxtCheckErrno(Socket = socket(AF_NETLINK, Type, Family));
601 memset(&BindAddress, 0, sizeof(BindAddress));
602 BindAddress.nl_family = AF_NETLINK;
603 AddressLength = sizeof(BindAddress.nl_family);
604 LxtCheckErrnoFailure(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength), EINVAL);
605
606 LxtClose(Socket);
607
608 //
609 // Test case: address length > sizeof(sockaddr_nl) is also invalid.
610 //
611
612 LxtCheckErrno(Socket = socket(AF_NETLINK, Type, Family));
613 BindAddressP = (struct sockaddr_nl*)AddressBuffer;
614 memset(AddressBuffer, 0, sizeof(AddressBuffer));
615 BindAddressP->nl_family = AF_NETLINK;
616 AddressLength = sizeof(AddressBuffer);
617 LxtCheckErrnoFailure(bind(Socket, (struct sockaddr*)BindAddressP, AddressLength), EINVAL);
618
619 LxtClose(Socket);
620
621 //
622 // Test case: getsockname on unbound socket returns nl_pid = 0.
623 //
624
625 LxtCheckErrno(Socket = socket(AF_NETLINK, Type, Family));
626 memset(&BindAddress, 0, sizeof(BindAddress));
627 AddressLength = sizeof(BindAddress);
628 LxtCheckErrno(getsockname(Socket, (struct sockaddr*)&BindAddress, &AddressLength));
629
630 LxtCheckEqual(BindAddress.nl_pid, 0, "%d");
631 LxtCheckEqual(AddressLength, sizeof(BindAddress), "%d");
632 LxtClose(Socket);
633
634 //
635 // Test case: calling sendto() on unbound socket automatically
636 // binds the socket (even if the sendto() fails).
637 //
638
639 LxtCheckErrno(Socket = socket(AF_NETLINK, Type, Family));
640 memset(DataBuffer, 0, sizeof(DataBuffer));
641 memset(&BindAddress, 0, sizeof(BindAddress));
642 BindAddress.nl_family = AF_NETLINK;
643 AddressLength = sizeof(BindAddress);
644 sendto(Socket, DataBuffer, sizeof(DataBuffer), 0, (struct sockaddr*)&BindAddress, AddressLength);
645
646 memset(&BindAddress, 0, sizeof(BindAddress));
647 LxtCheckErrno(getsockname(Socket, (struct sockaddr*)&BindAddress, &AddressLength));
648
649 LxtCheckEqual(BindAddress.nl_pid, getpid(), "%d");
650 LxtCheckEqual(AddressLength, sizeof(BindAddress), "%d");
651 LxtClose(Socket);
652
653 //
654 // Test case: Bind with nl_pid = 0, kernel should assign a unique
655 // ID. The first netlink socket of the process is
656 // assigned the process ID as the nl_pid. It also confirms
657 // the pad value is ignored.
658 //
659
660 LxtCheckErrno(Socket = socket(AF_NETLINK, Type, Family));
661 memset(&BindAddress, 0, sizeof(BindAddress));
662 BindAddress.nl_family = AF_NETLINK;
663 BindAddress.nl_pad = 1;
664 AddressLength = sizeof(BindAddress);
665 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
666
667 memset(&BindAddress, 0, sizeof(BindAddress));
668 LxtCheckErrno(getsockname(Socket, (struct sockaddr*)&BindAddress, &AddressLength));
669
670 LxtCheckEqual(BindAddress.nl_pid, getpid(), "%d");
671 LxtCheckEqual(AddressLength, sizeof(BindAddress), "%d");
672
673 //
674 // Validate that a socket that is already bound, cannot be bound again.
675 //
676
677 memset(&BindAddress, 0, sizeof(BindAddress));
678 BindAddress.nl_family = AF_NETLINK;
679 AddressLength = sizeof(BindAddress);
680 LxtCheckErrnoFailure(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength), EINVAL);
681
682 //
683 // Test case: The user specifies a negative nl_pid (which is what the
684 // kernel assigns to the non-first sockets of the process).
685 // Test that the kernel will skip any negative nl_pid's that
686 // the user already specified. For example, Socket2 gets
687 // an auto-assigned nl_pid of -5. Socket3 is bound with
688 // the user specifying nl_pid of -4. Socket4 gets an
689 // auto-assigned nl_pid of -3, since -4 was already taken
690 // by the user.
691 //
692
693 LxtCheckErrno(Socket2 = socket(AF_NETLINK, Type, Family));
694 memset(&BindAddress, 0, sizeof(BindAddress));
695 BindAddress.nl_family = AF_NETLINK;
696 AddressLength = sizeof(BindAddress);
697 LxtCheckErrno(bind(Socket2, (struct sockaddr*)&BindAddress, AddressLength));
698
699 memset(&BindAddress, 0, sizeof(BindAddress));
700 LxtCheckErrno(getsockname(Socket2, (struct sockaddr*)&BindAddress, &AddressLength));
701
702 LxtCheckTrue((int)BindAddress.nl_pid < 0);
703 LxtCheckEqual(AddressLength, sizeof(BindAddress), "%d");
704
705 LxtCheckErrno(Socket3 = socket(AF_NETLINK, Type, Family));
706 BindAddress.nl_pid += 1;
707 AddressLength = sizeof(BindAddress);
708 LxtCheckErrno(bind(Socket3, (struct sockaddr*)&BindAddress, AddressLength));
709
710 memset(&BindAddress, 0, sizeof(BindAddress));
711 LxtCheckErrno(getsockname(Socket3, (struct sockaddr*)&BindAddress, &AddressLength));
712
713 LxtCheckTrue((int)BindAddress.nl_pid < 0);
714 LxtCheckEqual(AddressLength, sizeof(BindAddress), "%d");
715
716 LxtCheckErrno(Socket4 = socket(AF_NETLINK, Type, Family));
717 memset(&BindAddress, 0, sizeof(BindAddress));
718 BindAddress.nl_family = AF_NETLINK;
719 AddressLength = sizeof(BindAddress);
720 LxtCheckErrno(bind(Socket4, (struct sockaddr*)&BindAddress, AddressLength));
721
722 memset(&BindAddress, 0, sizeof(BindAddress));
723 LxtCheckErrno(getsockname(Socket4, (struct sockaddr*)&BindAddress, &AddressLength));
724
725 LxtCheckTrue((int)BindAddress.nl_pid < 0);
726 LxtCheckEqual(AddressLength, sizeof(BindAddress), "%d");
727 LxtClose(Socket3);
728 LxtClose(Socket4);
729
730 //
731 // Test case: The kernel assigned a negative custom PID for Socket2.
732 // Save Socket2's custom PID, close Socket2, then bind a
733 // new socket with the saved PID, and verify success.
734 //
735
736 AddressLength = sizeof(BindAddress);
737 memset(&BindAddress, 0, sizeof(BindAddress));
738 LxtCheckErrno(getsockname(Socket2, (struct sockaddr*)&BindAddress, &AddressLength));
739
740 LxtCheckTrue((int)BindAddress.nl_pid < 0);
741 LxtCheckEqual(AddressLength, sizeof(BindAddress), "%d");
742 SavedPid = BindAddress.nl_pid;
743 LxtClose(Socket2);
744 LxtCheckErrno(Socket2 = socket(AF_NETLINK, Type, Family));
745 AddressLength = sizeof(BindAddress);
746 LxtCheckErrno(bind(Socket2, (struct sockaddr*)&BindAddress, AddressLength));
747
748 memset(&BindAddress, 0, sizeof(BindAddress));
749 LxtCheckErrno(getsockname(Socket2, (struct sockaddr*)&BindAddress, &AddressLength));
750
751 LxtCheckEqual((int)BindAddress.nl_pid, SavedPid, "%d");
752 LxtCheckEqual(AddressLength, sizeof(BindAddress), "%d");
753 LxtClose(Socket2);
754
755 //
756 // Test case: close the first socket of the process and open a new
757 // one. Being the first netlink socket of the process,
758 // it should get the process ID as the 'nl_pid'.
759 //
760
761 LxtClose(Socket);
762 LxtCheckErrno(Socket = socket(AF_NETLINK, Type, Family));
763 memset(&BindAddress, 0, sizeof(BindAddress));
764 BindAddress.nl_family = AF_NETLINK;
765 AddressLength = sizeof(BindAddress);
766 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
767
768 memset(&BindAddress, 0, sizeof(BindAddress));
769 LxtCheckErrno(getsockname(Socket, (struct sockaddr*)&BindAddress, &AddressLength));
770
771 LxtCheckEqual(BindAddress.nl_pid, getpid(), "%d");
772 LxtCheckEqual(AddressLength, sizeof(BindAddress), "%d");
773
774 //
775 // Test case: Kernel should assign a negative unique ID to any subsequent
776 // (after the first one) netlink socket that the process
777 // subsequently creates.
778 //
779
780 for (ArrayIterator = 0; ArrayIterator < ArraySize; ArrayIterator++)
781 {
782 LxtCheckErrno(SocketA[ArrayIterator] = socket(AF_NETLINK, Type, Family));
783
784 memset(&BindAddress, 0, sizeof(BindAddress));
785 BindAddress.nl_family = AF_NETLINK;
786 AddressLength = sizeof(BindAddress);
787 LxtCheckErrno(bind(SocketA[ArrayIterator], (struct sockaddr*)&BindAddress, AddressLength));
788
789 memset(&BindAddress, 0, sizeof(BindAddress));
790 LxtCheckErrno(getsockname(SocketA[ArrayIterator], (struct sockaddr*)&BindAddress, &AddressLength));
791
792 SocketPid[ArrayIterator] = BindAddress.nl_pid;
793 LxtCheckTrue(SocketPid[ArrayIterator] < 0);
794 }
795
796 //
797 // Validate that every socket PID is unique.
798 //
799
800 for (ArrayIterator = 0; ArrayIterator < ArraySize; ArrayIterator++)
801 {
802 LxtLogInfo("parent, socket: %d, pid: %d", ArrayIterator + 1, SocketPid[ArrayIterator]);
803
804 for (ArrayIterator2 = ArrayIterator + 1; ArrayIterator2 < ArraySize; ArrayIterator2++)
805 {
806
807 LxtCheckNotEqual(SocketPid[ArrayIterator], SocketPid[ArrayIterator2], "%d");
808 }
809 }
810
811 //
812 // Test case: validate that the child process gets its own set of ID's.
813 //
814
815 ChildPid = fork();
816 if (ChildPid == 0)
817 {
818 LxtLogInfo("child, pid: %d", getpid());
819 LxtClose(Socket);
820 LxtCheckErrno(Socket = socket(AF_NETLINK, Type, Family));
821 memset(&BindAddress, 0, sizeof(BindAddress));
822 BindAddress.nl_family = AF_NETLINK;
823 AddressLength = sizeof(BindAddress);
824 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
825
826 memset(&BindAddress, 0, sizeof(BindAddress));
827 LxtCheckErrno(getsockname(Socket, (struct sockaddr*)&BindAddress, &AddressLength));
828
829 LxtCheckEqual(BindAddress.nl_pid, getpid(), "%d");
830 for (ArrayIterator = 0; ArrayIterator < ArraySize; ArrayIterator++)
831 {
832 LxtCheckErrno(SocketChildA[ArrayIterator] = socket(AF_NETLINK, Type, Family));
833
834 memset(&BindAddress, 0, sizeof(BindAddress));
835 BindAddress.nl_family = AF_NETLINK;
836 AddressLength = sizeof(BindAddress);
837 LxtCheckErrno(bind(SocketChildA[ArrayIterator], (struct sockaddr*)&BindAddress, AddressLength));
838
839 memset(&BindAddress, 0, sizeof(BindAddress));
840 LxtCheckErrno(getsockname(SocketChildA[ArrayIterator], (struct sockaddr*)&BindAddress, &AddressLength));
841
842 SocketChildPid[ArrayIterator] = BindAddress.nl_pid;
843 LxtCheckTrue(SocketChildPid[ArrayIterator] < 0);
844 }
845
846 //
847 // Validate that every socket PID is unique, locally as well
848 // as globally.
849 //
850
851 for (ArrayIterator = 0; ArrayIterator < ArraySize; ArrayIterator++)
852 {
853 LxtLogInfo("child, socket: %d, pid: %d", ArrayIterator + 1, SocketChildPid[ArrayIterator]);
854
855 for (ArrayIterator2 = ArrayIterator + 1; ArrayIterator2 < ArraySize; ArrayIterator2++)
856 {
857
858 LxtCheckNotEqual(SocketChildPid[ArrayIterator], SocketChildPid[ArrayIterator2], "%d");
859
860 LxtCheckNotEqual(SocketPid[ArrayIterator], SocketChildPid[ArrayIterator2], "%d");
861 }
862 }
863
864 for (ArrayIterator = 0; ArrayIterator < ArraySize; ArrayIterator++)
865 {
866 LxtClose(SocketChildA[ArrayIterator]);
867 }
868
869 LxtClose(Socket);
870 Result = LXT_RESULT_SUCCESS;
871 goto ErrorExit;
872 }
873
874 LxtCheckResult(LxtWaitPidPoll(ChildPid, LXT_RESULT_SUCCESS));
875 for (ArrayIterator = 0; ArrayIterator < ArraySize; ArrayIterator++)
876 {
877 LxtClose(SocketA[ArrayIterator]);
878 }
879
880 //
881 // Test case: validate that if the app provides a PID for the socket,
882 // then it should be unique.
883 //
884
885 LxtCheckErrno(SocketA[0] = socket(AF_NETLINK, Type, Family));
886 memset(&BindAddress, 0, sizeof(BindAddress));
887 BindAddress.nl_family = AF_NETLINK;
888
889 //
890 // Since the very first socket of this process is still open,
891 // getpid() as the socket PID is already in use.
892 //
893
894 BindAddress.nl_pid = getpid();
895 AddressLength = sizeof(BindAddress);
896 LxtCheckErrnoFailure(bind(SocketA[0], (struct sockaddr*)&BindAddress, AddressLength), EADDRINUSE);
897
898 LxtClose(SocketA[0]);
899 LxtClose(Socket);
900
901 //
902 // Test case: validate that when there are no netlink sockets opened
903 // by the process, the app should be able to provide the
904 // PID of the process as the unique ID for the socket.
905 //
906
907 LxtCheckErrno(Socket = socket(AF_NETLINK, Type, Family));
908 memset(&BindAddress, 0, sizeof(BindAddress));
909 BindAddress.nl_family = AF_NETLINK;
910 BindAddress.nl_pid = getpid();
911 AddressLength = sizeof(BindAddress);
912 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
913
914 LxtClose(Socket);
915 }
916 }
917
918 Result = LXT_RESULT_SUCCESS;
919
920 ErrorExit:
921 if (Socket > 0)
922 {
923 close(Socket);
924 }
925
926 if (Socket2 > 0)
927 {
928 close(Socket2);
929 }
930
931 if (Socket3 > 0)
932 {
933 close(Socket3);
934 }
935
936 if (Socket4 > 0)
937 {
938 close(Socket4);
939 }
940
941 for (ArrayIterator = 0; ArrayIterator < ArraySize; ArrayIterator++)
942 {
943 if (SocketA[ArrayIterator] != 0)
944 {
945 close(SocketA[ArrayIterator]);
946 }
947
948 if (SocketChildA[ArrayIterator] != 0)
949 {
950 close(SocketChildA[ArrayIterator]);
951 }
952 }
953
954 //
955 // If child, exit.
956 //
957
958 if (ChildPid == 0)
959 {
960 _exit(Result);
961 }
962
963 return Result;
964 }
965
966 int SocketNetlinkBindThread(PLXT_ARGS Args)
967
968 /*++
969
970 Routine Description:
971
972 This routine tests the bind() API with new threads
973 created by pthread_create.
974
975 Arguments:
976
977 Args - Supplies the command line arguments.
978
979 Return Value:
980
981 Returns 0 on success, -1 on failure.
982
983 --*/
984
985 {
986
987 socklen_t AddressLength;
988 int ArrayIterator;
989 struct sockaddr_nl BindAddress;
990 pthread_t ChildThread;
991 pid_t ChildThreadNetlinkPid;
992 BindChildThreadReturn* ChildThreadReturn;
993 int Result;
994 int Socket;
995
996 Result = LXT_RESULT_FAILURE;
997 Socket = -1;
998 for (ArrayIterator = 0; ArrayIterator < 5; ArrayIterator++)
999 {
1000
1001 //
1002 // Open a netlink socket. This is the first netlink socket of the
1003 // threadgroup, so it should have a nl_pid equal to getpid() (which
1004 // is the tgid).
1005 //
1006
1007 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
1008 memset(&BindAddress, 0, sizeof(BindAddress));
1009 BindAddress.nl_family = AF_NETLINK;
1010 AddressLength = sizeof(BindAddress);
1011 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
1012
1013 memset(&BindAddress, 0, sizeof(BindAddress));
1014 LxtCheckErrno(getsockname(Socket, (struct sockaddr*)&BindAddress, &AddressLength));
1015
1016 LxtLogInfo("nl_pid 1: %d pid: %d", BindAddress.nl_pid, getpid());
1017 LxtCheckTrue(BindAddress.nl_pid > 0);
1018 LxtCheckEqual(BindAddress.nl_pid, getpid(), "%d");
1019
1020 //
1021 // Create a new thread, which opens and closes a netlink socket in the
1022 // new thread. This is not the first netlink socket of the threadgroup,
1023 // so it should have a negative nl_pid.
1024 //
1025
1026 LxtCheckErrnoZeroSuccess(pthread_create(&ChildThread, NULL, SocketNetlinkBindThreadChild, NULL));
1027
1028 LxtCheckErrnoZeroSuccess(pthread_join(ChildThread, (void*)&ChildThreadReturn));
1029 LxtCheckTrue(ChildThreadReturn != NULL);
1030 ChildThreadNetlinkPid = ChildThreadReturn->nl_pid;
1031 free(ChildThreadReturn);
1032 LxtLogInfo("nl_pid 2: %d pid: %d", ChildThreadNetlinkPid, getpid());
1033 LxtCheckTrue(ChildThreadNetlinkPid < 0);
1034
1035 //
1036 // Close the first netlink socket (leaving no open netlink sockets).
1037 // Create a new thread, which opens and closes a netlink socket in the
1038 // new thread. This is the first netlink socket of the threadgroup.
1039 //
1040
1041 LxtClose(Socket);
1042 LxtCheckErrnoZeroSuccess(pthread_create(&ChildThread, NULL, SocketNetlinkBindThreadChild, NULL));
1043
1044 LxtCheckErrnoZeroSuccess(pthread_join(ChildThread, (void*)&ChildThreadReturn));
1045 LxtCheckTrue(ChildThreadReturn != NULL);
1046 ChildThreadNetlinkPid = ChildThreadReturn->nl_pid;
1047 free(ChildThreadReturn);
1048 LxtLogInfo("nl_pid 3: %d pid: %d", ChildThreadNetlinkPid, getpid());
1049 LxtCheckTrue(ChildThreadNetlinkPid > 0);
1050 LxtCheckEqual(ChildThreadNetlinkPid, getpid(), "%d");
1051 }
1052
1053 Result = LXT_RESULT_SUCCESS;
1054
1055 ErrorExit:
1056 if (Socket > 0)
1057 {
1058 close(Socket);
1059 }
1060
1061 return Result;
1062 }
1063
1064 void* SocketNetlinkBindThreadChild(void* Arg)
1065
1066 /*++
1067
1068 Routine Description:
1069
1070 This routine runs in a child thread and creates a netlink socket.
1071
1072 Arguments:
1073
1074 Args - Supplies the command line arguments.
1075
1076 Return Value:
1077
1078 On success, returns a struct containing the nl_pid of the netlink socket
1079 created by this thread. On failure, returns NULL.
1080
1081 --*/
1082
1083 {
1084
1085 socklen_t AddressLength;
1086 struct sockaddr_nl BindAddress;
1087 int Result;
1088 int Socket;
1089 BindChildThreadReturn* ThreadReturn;
1090
1091 Socket = -1;
1092 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
1093 memset(&BindAddress, 0, sizeof(BindAddress));
1094 BindAddress.nl_family = AF_NETLINK;
1095 AddressLength = sizeof(BindAddress);
1096 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
1097
1098 memset(&BindAddress, 0, sizeof(BindAddress));
1099 LxtCheckErrno(getsockname(Socket, (struct sockaddr*)&BindAddress, &AddressLength));
1100
1101 LxtLogInfo("Child thread: nl_pid: %d, getpid(): %d", BindAddress.nl_pid, getpid());
1102
1103 LxtClose(Socket);
1104 ThreadReturn = malloc(sizeof(*ThreadReturn));
1105 LxtCheckTrue(ThreadReturn != NULL);
1106 ThreadReturn->nl_pid = BindAddress.nl_pid;
1107
1108 ErrorExit:
1109 if (Socket > 0)
1110 {
1111 close(Socket);
1112 }
1113
1114 if (Result < 0)
1115 {
1116 return NULL;
1117 }
1118 else
1119 {
1120 return ThreadReturn;
1121 }
1122 }
1123
1124 int SocketNetlinkSendReceive(PLXT_ARGS Args)
1125
1126 /*++
1127
1128 Routine Description:
1129
1130 This routine tests the send and receive family of APIs.
1131
1132 Arguments:
1133
1134 Args - Supplies the command line arguments.
1135
1136 Return Value:
1137
1138 Returns 0 on success, -1 on failure.
1139
1140 --*/
1141
1142 {
1143
1144 socklen_t AddressLength;
1145 struct sockaddr_nl BindAddress;
1146 struct
1147 {
1148 struct nlmsghdr nlh1;
1149 char dummy[4];
1150 struct nlmsghdr nlh2;
1151 } DoubleRequest;
1152 struct nlmsgerr* Error;
1153 int ExpectedReceiveLength;
1154 struct iovec IoVec[10];
1155 struct msghdr MessageHeader;
1156 struct sockaddr_nl ReceiveAddress;
1157 char ReceiveBuffer[500];
1158 struct nlmsghdr* ReceiveHeader;
1159 struct nlmsghdr* ReceiveHeader2;
1160 int ReceiveResult;
1161 struct nlmsghdr Request;
1162 int Result;
1163 struct sockaddr_nl SendAddress;
1164 uint32_t Sequence;
1165 int Socket;
1166
1167 Result = LXT_RESULT_FAILURE;
1168 Socket = -1;
1169 Sequence = 0x7435;
1170
1171 //
1172 // Create and bind socket. Create a Netlink request with the ACK flag.
1173 // Netlink should echo the same request back to us.
1174 //
1175 // TODO_LX: Test whether invalid messages should be ACK'd back.
1176 //
1177
1178 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
1179 memset(&BindAddress, 0, sizeof(BindAddress));
1180 BindAddress.nl_family = AF_NETLINK;
1181 AddressLength = sizeof(BindAddress);
1182 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
1183
1184 memset(&Request, 0, sizeof(Request));
1185 Request.nlmsg_len = NLMSG_LENGTH(0);
1186 Request.nlmsg_type = NLMSG_NOOP;
1187 Request.nlmsg_flags = NLM_F_ACK;
1188 Request.nlmsg_seq = Sequence;
1189
1190 //
1191 // Test sendto() with invalid send addresses.
1192 //
1193
1194 AddressLength = sizeof(SendAddress);
1195 memset(&SendAddress, 0, sizeof(SendAddress));
1196 SendAddress.nl_family = AF_NETLINK;
1197 SendAddress.nl_pid = 0xFFFF1234;
1198 LxtCheckErrnoFailure(sendto(Socket, &Request, sizeof(Request), 0, (struct sockaddr*)&SendAddress, AddressLength), ECONNREFUSED);
1199
1200 memset(&SendAddress, 0, sizeof(SendAddress));
1201 SendAddress.nl_family = 0xFFFF;
1202 LxtCheckErrnoFailure(sendto(Socket, &Request, sizeof(Request), 0, (struct sockaddr*)&SendAddress, AddressLength), EINVAL);
1203
1204 //
1205 // Test sendto() with 0 nl_pid in send address. This should go to the kernel.
1206 // This is message 0.
1207 //
1208
1209 memset(&SendAddress, 0, sizeof(SendAddress));
1210 Request.nlmsg_seq = Sequence;
1211 SendAddress.nl_family = AF_NETLINK;
1212 SendAddress.nl_pid = 0;
1213 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, (struct sockaddr*)&SendAddress, AddressLength));
1214
1215 //
1216 // Test sendto() with 0 buffer length. The return value should be 0
1217 // and no response should be generated.
1218 //
1219
1220 LxtCheckErrnoZeroSuccess(sendto(Socket, &Request, 0, 0, (struct sockaddr*)&SendAddress, AddressLength));
1221
1222 //
1223 // Test sendto() with NULL send address. This should go to the kernel
1224 // by default. This is message 1.
1225 //
1226
1227 Request.nlmsg_seq = Sequence + 1;
1228 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
1229
1230 //
1231 // Test send(). This should go to the kernel by default. This is message 2.
1232 //
1233
1234 Request.nlmsg_seq = Sequence + 2;
1235 LxtCheckErrno(send(Socket, &Request, sizeof(Request), 0));
1236
1237 //
1238 // Test write(). This should go to the kernel by default. This is message 3.
1239 //
1240
1241 Request.nlmsg_seq = Sequence + 3;
1242 LxtCheckErrno(write(Socket, &Request, sizeof(Request)));
1243
1244 //
1245 // Test sendmsg() with NULL send address. This is message 4.
1246 // A NULL send address means the name size should be ignored, so also add
1247 // an invalid name size to verify this.
1248 //
1249
1250 memset(&IoVec, 0, sizeof(IoVec));
1251 memset(&MessageHeader, 0, sizeof(MessageHeader));
1252 IoVec[0].iov_base = &Request;
1253 IoVec[0].iov_len = sizeof(Request);
1254 MessageHeader.msg_iov = IoVec;
1255 MessageHeader.msg_iovlen = 1;
1256 MessageHeader.msg_namelen = -1;
1257 Request.nlmsg_seq = Sequence + 4;
1258 LxtCheckErrno(sendmsg(Socket, &MessageHeader, 0));
1259
1260 //
1261 // Test sendmsg() with buffer split across vectors. This is message 5.
1262 //
1263
1264 memset(&IoVec, 0, sizeof(IoVec));
1265 memset(&MessageHeader, 0, sizeof(MessageHeader));
1266 memset(&DoubleRequest, 0, sizeof(DoubleRequest));
1267 IoVec[0].iov_base = &DoubleRequest.nlh1;
1268 IoVec[0].iov_len = __builtin_offsetof(struct nlmsghdr, nlmsg_flags);
1269 IoVec[1].iov_base = &DoubleRequest.nlh2.nlmsg_flags;
1270 IoVec[1].iov_len = sizeof(struct nlmsghdr) - __builtin_offsetof(struct nlmsghdr, nlmsg_flags);
1271
1272 DoubleRequest.nlh1.nlmsg_len = NLMSG_LENGTH(0);
1273 DoubleRequest.nlh1.nlmsg_type = NLMSG_NOOP;
1274 DoubleRequest.nlh2.nlmsg_flags = NLM_F_ACK;
1275 DoubleRequest.nlh2.nlmsg_seq = Sequence + 5;
1276 MessageHeader.msg_iov = IoVec;
1277 MessageHeader.msg_iovlen = 2;
1278 LxtCheckErrno(sendmsg(Socket, &MessageHeader, 0));
1279
1280 //
1281 // Test sendmsg() with MSG_DONTWAIT flag.
1282 //
1283
1284 memset(&IoVec, 0, sizeof(IoVec));
1285 memset(&MessageHeader, 0, sizeof(MessageHeader));
1286 IoVec[0].iov_base = &Request;
1287 IoVec[0].iov_len = sizeof(Request);
1288 MessageHeader.msg_iov = IoVec;
1289 MessageHeader.msg_iovlen = 1;
1290 Request.nlmsg_seq = Sequence + 6;
1291 LxtCheckErrno(sendmsg(Socket, &MessageHeader, MSG_DONTWAIT));
1292
1293 //
1294 // Test sendmsg() with invalid send address.
1295 //
1296
1297 AddressLength = sizeof(SendAddress);
1298 memset(&SendAddress, 0, sizeof(SendAddress));
1299 SendAddress.nl_family = AF_NETLINK;
1300 SendAddress.nl_pid = 0xFFFF1234;
1301 MessageHeader.msg_name = &SendAddress;
1302 MessageHeader.msg_namelen = AddressLength;
1303 LxtCheckErrnoFailure(sendmsg(Socket, &MessageHeader, 0), ECONNREFUSED);
1304
1305 //
1306 // Test sendmsg() with negative send address length.
1307 //
1308
1309 AddressLength = sizeof(SendAddress);
1310 memset(&SendAddress, 0, sizeof(SendAddress));
1311 SendAddress.nl_family = AF_NETLINK;
1312 SendAddress.nl_pid = 0xFFFF1234;
1313 MessageHeader.msg_name = &SendAddress;
1314 MessageHeader.msg_namelen = -1;
1315 LxtCheckErrnoFailure(sendmsg(Socket, &MessageHeader, 0), EINVAL);
1316
1317 //
1318 // Test sendmsg() with 0 nl_pid in send address.
1319 //
1320
1321 AddressLength = sizeof(SendAddress);
1322 memset(&SendAddress, 0, sizeof(SendAddress));
1323 SendAddress.nl_family = AF_NETLINK;
1324 SendAddress.nl_pid = 0;
1325 MessageHeader.msg_name = &SendAddress;
1326 MessageHeader.msg_namelen = AddressLength;
1327 Request.nlmsg_seq = Sequence + 7;
1328 LxtCheckErrno(sendmsg(Socket, &MessageHeader, 0));
1329
1330 //
1331 // Test read(). Verify the received contents. The response should be message 0.
1332 //
1333
1334 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1335 LxtCheckErrno(ReceiveResult = read(Socket, ReceiveBuffer, sizeof(ReceiveBuffer)));
1336 ExpectedReceiveLength = NLMSG_LENGTH(sizeof(struct nlmsgerr));
1337 LxtCheckEqual(ReceiveResult, ExpectedReceiveLength, "%d");
1338 ReceiveHeader = (struct nlmsghdr*)ReceiveBuffer;
1339 LxtCheckEqual(ReceiveHeader->nlmsg_type, NLMSG_ERROR, "%d");
1340 LxtCheckEqual(ReceiveHeader->nlmsg_flags, 0, "%d");
1341 LxtCheckEqual(ReceiveHeader->nlmsg_seq, Sequence, "%d");
1342 LxtCheckEqual(ReceiveHeader->nlmsg_pid, getpid(), "%d");
1343 Error = (struct nlmsgerr*)NLMSG_DATA(ReceiveBuffer);
1344 LxtCheckEqual(Error->error, 0, "%d");
1345
1346 //
1347 // Test recv(). Verify the received contents. The response should be message 1.
1348 //
1349
1350 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1351 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
1352 ExpectedReceiveLength = NLMSG_LENGTH(sizeof(struct nlmsgerr));
1353 LxtCheckEqual(ReceiveResult, ExpectedReceiveLength, "%d");
1354 ReceiveHeader = (struct nlmsghdr*)ReceiveBuffer;
1355 LxtCheckEqual(ReceiveHeader->nlmsg_type, NLMSG_ERROR, "%d");
1356 LxtCheckEqual(ReceiveHeader->nlmsg_flags, 0, "%d");
1357 LxtCheckEqual(ReceiveHeader->nlmsg_seq, Sequence + 1, "%d");
1358 LxtCheckEqual(ReceiveHeader->nlmsg_pid, getpid(), "%d");
1359 Error = (struct nlmsgerr*)NLMSG_DATA(ReceiveBuffer);
1360 LxtCheckEqual(Error->error, 0, "%d");
1361
1362 //
1363 // Test recvfrom() with NULL receive address. Use MSG_PEEK flag, which
1364 // should not remove the data from the socket. Use MSG_TRUNC flag, which
1365 // should have no effect since the passed in buffer is larger than the
1366 // response. Use MSG_WAITALL flag, which has no effect on datagram sockets.
1367 // Verify the received contents. The response should be message 2.
1368 //
1369
1370 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1371 LxtCheckErrno(ReceiveResult = recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_PEEK | MSG_TRUNC | MSG_WAITALL, NULL, 0));
1372
1373 ExpectedReceiveLength = NLMSG_LENGTH(sizeof(struct nlmsgerr));
1374 LxtCheckEqual(ReceiveResult, ExpectedReceiveLength, "%d");
1375 ReceiveHeader = (struct nlmsghdr*)ReceiveBuffer;
1376 LxtCheckEqual(ReceiveHeader->nlmsg_type, NLMSG_ERROR, "%d");
1377 LxtCheckEqual(ReceiveHeader->nlmsg_flags, 0, "%d");
1378 LxtCheckEqual(ReceiveHeader->nlmsg_seq, Sequence + 2, "%d");
1379 LxtCheckEqual(ReceiveHeader->nlmsg_pid, getpid(), "%d");
1380 Error = (struct nlmsgerr*)NLMSG_DATA(ReceiveBuffer);
1381 LxtCheckEqual(Error->error, 0, "%d");
1382
1383 //
1384 // Test recvfrom(). Use MSG_TRUNC flag. Even though the passed in
1385 // receive buffer is too small, the return value should be the full length
1386 // of the response. The response should still be message 2, since the previous
1387 // call was a MSK_PEEK.
1388 //
1389
1390 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1391 LxtCheckErrno(ReceiveResult = recvfrom(Socket, ReceiveBuffer, 2 * sizeof(uint32_t), MSG_TRUNC, NULL, 0));
1392
1393 ExpectedReceiveLength = NLMSG_LENGTH(sizeof(struct nlmsgerr));
1394 LxtCheckEqual(ReceiveResult, ExpectedReceiveLength, "%d");
1395 ReceiveHeader = (struct nlmsghdr*)ReceiveBuffer;
1396 LxtCheckEqual(ReceiveHeader->nlmsg_type, NLMSG_ERROR, "%d");
1397 LxtCheckEqual(ReceiveHeader->nlmsg_flags, 0, "%d");
1398 LxtCheckEqual(ReceiveHeader->nlmsg_seq, 0, "%d");
1399 LxtCheckEqual(ReceiveHeader->nlmsg_pid, 0, "%d");
1400 Error = (struct nlmsgerr*)NLMSG_DATA(ReceiveBuffer);
1401 LxtCheckEqual(Error->error, 0, "%d");
1402
1403 //
1404 // Test recvfrom() with 0 buffer length. This should still advance the
1405 // socket's internal receive buffer (making the next response message 4).
1406 // This response should be message 3.
1407 //
1408
1409 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1410 LxtCheckErrno(ReceiveResult = recvfrom(Socket, ReceiveBuffer, 0, 0, NULL, 0));
1411
1412 ExpectedReceiveLength = 0;
1413 LxtCheckEqual(ReceiveResult, ExpectedReceiveLength, "%d");
1414 ReceiveHeader = (struct nlmsghdr*)ReceiveBuffer;
1415
1416 //
1417 // Test recvfrom() with valid receive address. Verify the received contents.
1418 // The response should be message 4.
1419 //
1420
1421 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1422 memset(&ReceiveAddress, 0, sizeof(ReceiveAddress));
1423 AddressLength = sizeof(struct sockaddr_nl);
1424 LxtCheckErrno(ReceiveResult = recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, (struct sockaddr*)&ReceiveAddress, &AddressLength));
1425
1426 ExpectedReceiveLength = NLMSG_LENGTH(sizeof(struct nlmsgerr));
1427 LxtCheckEqual(ReceiveResult, ExpectedReceiveLength, "%d");
1428 LxtCheckEqual(AddressLength, sizeof(struct sockaddr_nl), "%d");
1429 ReceiveHeader = (struct nlmsghdr*)ReceiveBuffer;
1430 LxtCheckEqual(ReceiveHeader->nlmsg_type, NLMSG_ERROR, "%d");
1431 LxtCheckEqual(ReceiveHeader->nlmsg_flags, 0, "%d");
1432 LxtCheckEqual(ReceiveHeader->nlmsg_seq, Sequence + 4, "%d");
1433 LxtCheckEqual(ReceiveHeader->nlmsg_pid, getpid(), "%d");
1434 LxtCheckEqual(ReceiveAddress.nl_family, AF_NETLINK, "%d");
1435 LxtCheckEqual(ReceiveAddress.nl_pid, 0, "%d");
1436 Error = (struct nlmsgerr*)NLMSG_DATA(ReceiveBuffer);
1437 LxtCheckEqual(Error->error, 0, "%d");
1438 Request.nlmsg_seq = Sequence + 4;
1439 LxtCheckEqual(memcmp(&Error->msg, &Request, sizeof(Request)), 0, "%d");
1440
1441 //
1442 // Test recvmsg() with valid receive address. Verify the received contents.
1443 //
1444
1445 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1446 memset(&ReceiveAddress, 0, sizeof(ReceiveAddress));
1447 memset(&IoVec, 0, sizeof(IoVec));
1448 memset(&MessageHeader, 0, sizeof(MessageHeader));
1449 IoVec[0].iov_base = &ReceiveBuffer;
1450 IoVec[0].iov_len = sizeof(ReceiveBuffer);
1451 MessageHeader.msg_iov = IoVec;
1452 MessageHeader.msg_iovlen = 1;
1453 MessageHeader.msg_name = &ReceiveAddress;
1454 MessageHeader.msg_namelen = AddressLength;
1455
1456 //
1457 // Set some random value as the control length and check whether it gets
1458 // properly (re)set by the kernel.
1459 //
1460
1461 MessageHeader.msg_controllen = 100;
1462 LxtCheckErrno(ReceiveResult = recvmsg(Socket, &MessageHeader, 0));
1463 LxtCheckEqual(MessageHeader.msg_controllen, 0, "%d");
1464 LxtCheckEqual(MessageHeader.msg_flags, 0, "%d");
1465 ExpectedReceiveLength = NLMSG_LENGTH(sizeof(struct nlmsgerr));
1466 LxtCheckEqual(ReceiveResult, ExpectedReceiveLength, "%d");
1467 LxtCheckEqual(MessageHeader.msg_namelen, AddressLength, "%d");
1468 ReceiveHeader = (struct nlmsghdr*)ReceiveBuffer;
1469 LxtCheckEqual(ReceiveHeader->nlmsg_type, NLMSG_ERROR, "%d");
1470 LxtCheckEqual(ReceiveHeader->nlmsg_flags, 0, "%d");
1471 LxtCheckEqual(ReceiveHeader->nlmsg_seq, Sequence + 5, "%d");
1472 LxtCheckEqual(ReceiveHeader->nlmsg_pid, getpid(), "%d");
1473 LxtCheckEqual(ReceiveAddress.nl_family, AF_NETLINK, "%d");
1474 LxtCheckEqual(ReceiveAddress.nl_pid, 0, "%d");
1475 Error = (struct nlmsgerr*)NLMSG_DATA(ReceiveBuffer);
1476 LxtCheckEqual(Error->error, 0, "%d");
1477 Request.nlmsg_seq = Sequence + 5;
1478 LxtCheckEqual(memcmp(&Error->msg, &Request, sizeof(Request)), 0, "%d");
1479
1480 //
1481 // Test recvmsg() with passing in a small receive buffer.
1482 // The response should be truncated.
1483 //
1484
1485 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1486 memset(&IoVec, 0, sizeof(IoVec));
1487 memset(&MessageHeader, 0, sizeof(MessageHeader));
1488 IoVec[0].iov_base = &ReceiveBuffer;
1489 IoVec[0].iov_len = 2 * sizeof(uint32_t);
1490 MessageHeader.msg_iov = IoVec;
1491 MessageHeader.msg_iovlen = 1;
1492 LxtCheckErrno(ReceiveResult = recvmsg(Socket, &MessageHeader, 0));
1493 ExpectedReceiveLength = IoVec[0].iov_len;
1494 LxtCheckEqual(ReceiveResult, ExpectedReceiveLength, "%d");
1495 LxtCheckEqual(ReceiveHeader->nlmsg_type, NLMSG_ERROR, "%d");
1496 LxtCheckEqual(ReceiveHeader->nlmsg_flags, 0, "%d");
1497 LxtCheckEqual(ReceiveHeader->nlmsg_seq, 0, "%d");
1498 LxtCheckEqual(ReceiveHeader->nlmsg_pid, 0, "%d");
1499 Error = (struct nlmsgerr*)NLMSG_DATA(ReceiveBuffer);
1500 LxtCheckEqual(Error->error, 0, "%d");
1501 memset(&Request, 0, sizeof(Request));
1502 LxtCheckEqual(memcmp(&Error->msg, &Request, sizeof(Request)), 0, "%d");
1503
1504 //
1505 // Test recvmsg() split across vectors.
1506 //
1507
1508 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1509 memset(&IoVec, 0, sizeof(IoVec));
1510 memset(&MessageHeader, 0, sizeof(MessageHeader));
1511 ReceiveHeader2 =
1512 (struct nlmsghdr*)&ReceiveBuffer[NLMSG_LENGTH(sizeof(struct nlmsgerr)) + __builtin_offsetof(struct nlmsghdr, nlmsg_flags)];
1513
1514 IoVec[0].iov_len = __builtin_offsetof(struct nlmsghdr, nlmsg_flags);
1515 IoVec[0].iov_base = ReceiveHeader2;
1516 IoVec[1].iov_base = ReceiveBuffer + __builtin_offsetof(struct nlmsghdr, nlmsg_flags);
1517 IoVec[1].iov_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
1518 MessageHeader.msg_iov = IoVec;
1519 MessageHeader.msg_iovlen = 2;
1520 LxtCheckErrno(ReceiveResult = recvmsg(Socket, &MessageHeader, 0));
1521 LxtCheckEqual(MessageHeader.msg_controllen, 0, "%d");
1522 LxtCheckEqual(MessageHeader.msg_flags, 0, "%d");
1523 ExpectedReceiveLength = NLMSG_LENGTH(sizeof(struct nlmsgerr));
1524 LxtCheckEqual(ReceiveResult, ExpectedReceiveLength, "%d");
1525 ReceiveHeader = (struct nlmsghdr*)ReceiveBuffer;
1526 LxtCheckEqual(ReceiveHeader->nlmsg_len, 0, "%d");
1527 LxtCheckEqual(ReceiveHeader->nlmsg_type, 0, "%d");
1528 ReceiveHeader->nlmsg_len = ReceiveHeader2->nlmsg_len;
1529 ReceiveHeader->nlmsg_type = ReceiveHeader2->nlmsg_type;
1530 LxtCheckEqual(ReceiveHeader->nlmsg_len, ExpectedReceiveLength, "%d");
1531 LxtCheckEqual(ReceiveHeader->nlmsg_type, NLMSG_ERROR, "%d");
1532 LxtCheckEqual(ReceiveHeader->nlmsg_flags, 0, "%d");
1533 LxtCheckEqual(ReceiveHeader->nlmsg_seq, Sequence + 7, "%d");
1534 LxtCheckEqual(ReceiveHeader->nlmsg_pid, getpid(), "%d");
1535 LxtCheckEqual(ReceiveAddress.nl_family, AF_NETLINK, "%d");
1536 LxtCheckEqual(ReceiveAddress.nl_pid, 0, "%d");
1537 Error = (struct nlmsgerr*)NLMSG_DATA(ReceiveBuffer);
1538 LxtCheckEqual(Error->error, 0, "%d");
1539 Request.nlmsg_len = NLMSG_LENGTH(0);
1540 Request.nlmsg_type = NLMSG_NOOP;
1541 Request.nlmsg_flags = NLM_F_ACK;
1542 Request.nlmsg_seq = Sequence + 7;
1543 LxtCheckEqual(memcmp(&Error->msg, &Request, sizeof(Request)), 0, "%d");
1544
1545 //
1546 // Test recvfrom() when using the MSG_DONTWAIT flag. The socket has no data,
1547 // so it should return EAGAIN immediately instead of blocking forever.
1548 //
1549
1550 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1551 LxtCheckErrnoFailure(recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT, NULL, 0), EAGAIN);
1552
1553 //
1554 // Test specifying that the input buffer is much larger than it actually is.
1555 //
1556
1557 memset(&DoubleRequest, 0, sizeof(DoubleRequest));
1558 memset(&IoVec, 0, sizeof(IoVec));
1559 memset(&MessageHeader, 0, sizeof(MessageHeader));
1560 DoubleRequest.nlh1.nlmsg_len = 0x30000;
1561 DoubleRequest.nlh1.nlmsg_type = NLMSG_NOOP;
1562 DoubleRequest.nlh1.nlmsg_flags = NLM_F_ACK;
1563 DoubleRequest.nlh1.nlmsg_seq = Sequence;
1564 IoVec[0].iov_base = &DoubleRequest;
1565 IoVec[0].iov_len = 0x30000;
1566 MessageHeader.msg_iov = IoVec;
1567 MessageHeader.msg_iovlen = 1;
1568 Request.nlmsg_seq = Sequence + 4;
1569 LxtCheckErrnoFailure(sendmsg(Socket, &MessageHeader, 0), EFAULT);
1570
1571 //
1572 // Test passing in garbage length values in the message headers.
1573 //
1574
1575 DoubleRequest.nlh1.nlmsg_len = NLMSG_LENGTH(0) + 1;
1576 DoubleRequest.nlh2.nlmsg_len = 0x3000;
1577 IoVec[0].iov_len = sizeof(DoubleRequest.nlh1) + 1;
1578 LxtCheckErrno(sendmsg(Socket, &MessageHeader, 0));
1579
1580 //
1581 // Again.
1582 //
1583
1584 DoubleRequest.nlh1.nlmsg_len = 0x3000;
1585 DoubleRequest.nlh2.nlmsg_len = 0x3000;
1586 IoVec[0].iov_len = sizeof(DoubleRequest.nlh1) + 1;
1587 LxtCheckErrno(sendmsg(Socket, &MessageHeader, 0));
1588
1589 //
1590 // Again.
1591 //
1592
1593 DoubleRequest.nlh1.nlmsg_len = 0x3000;
1594 DoubleRequest.nlh2.nlmsg_len = NLMSG_LENGTH(0) + 1;
1595 IoVec[0].iov_len = sizeof(DoubleRequest.nlh1) + 1;
1596 LxtCheckErrno(sendmsg(Socket, &MessageHeader, 0));
1597
1598 //
1599 // TODO: Test multi-message send with different requests
1600 // bundled in the same send.
1601 //
1602
1603 ErrorExit:
1604 if (Socket > 0)
1605 {
1606 close(Socket);
1607 }
1608
1609 return Result;
1610 }
1611
1612 int SocketNetlinkSendReceiveOverflow(PLXT_ARGS Args)
1613
1614 /*++
1615
1616 Routine Description:
1617
1618 This routine tests the send and receive family of APIs
1619 in the context of the receive buffer overflowing.
1620
1621 Arguments:
1622
1623 Args - Supplies the command line arguments.
1624
1625 Return Value:
1626
1627 Returns 0 on success, -1 on failure.
1628
1629 --*/
1630
1631 {
1632
1633 socklen_t AddressLength;
1634 struct sockaddr_nl BindAddress;
1635 struct nlmsgerr* Error;
1636 int ExpectedReceiveLength;
1637 int Index;
1638 struct sockaddr_nl ReceiveAddress;
1639 char ReceiveBuffer[500];
1640 struct nlmsghdr* ReceiveHeader;
1641 int ReceiveResult;
1642 struct nlmsghdr Request;
1643 int Result;
1644 struct sockaddr_nl SendAddress;
1645 int SendResult;
1646 uint32_t Sequence;
1647 int Socket;
1648 int SocketError;
1649 socklen_t SocketErrorSize;
1650 struct timeval Timeout;
1651
1652 Result = LXT_RESULT_FAILURE;
1653 Socket = -1;
1654 Sequence = 0x3468;
1655
1656 //
1657 // Create and bind socket. Create a NOOP request with the ACK flag.
1658 // Netlink should echo the same request back to us.
1659 //
1660
1661 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
1662 memset(&BindAddress, 0, sizeof(BindAddress));
1663 BindAddress.nl_family = AF_NETLINK;
1664 AddressLength = sizeof(BindAddress);
1665 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
1666
1667 memset(&Request, 0, sizeof(Request));
1668 Request.nlmsg_len = NLMSG_LENGTH(0);
1669 Request.nlmsg_type = NLMSG_NOOP;
1670 Request.nlmsg_flags = NLM_F_ACK;
1671
1672 //
1673 // Overflow the receive buffer by sending 3000 events.
1674 // Each send should succeed with the return value being the full number of
1675 // bytes the user sent.
1676 //
1677
1678 AddressLength = sizeof(SendAddress);
1679 memset(&SendAddress, 0, sizeof(SendAddress));
1680 SendAddress.nl_family = AF_NETLINK;
1681 SendAddress.nl_pid = 0;
1682 for (Index = 0; Index < 3000; Index++)
1683 {
1684 Request.nlmsg_seq = Sequence + Index;
1685 LxtCheckErrno(SendResult = sendto(Socket, &Request, sizeof(Request), 0, (struct sockaddr*)&SendAddress, AddressLength));
1686
1687 LxtCheckEqual(SendResult, sizeof(Request), "%d");
1688 }
1689
1690 //
1691 // The first call to recvfrom() after the overflow should return ENOBUFS.
1692 // Also verify that the receive and address buffers were not changed.
1693 //
1694
1695 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1696 memset(&ReceiveAddress, 0, sizeof(ReceiveAddress));
1697 ReceiveBuffer[1] = 0x56;
1698 ReceiveAddress.nl_groups = 0x3456789a;
1699 AddressLength = sizeof(struct sockaddr_nl);
1700 LxtCheckErrnoFailure(recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, (struct sockaddr*)&ReceiveAddress, &AddressLength), ENOBUFS);
1701
1702 LxtCheckEqual(ReceiveBuffer[1], 0x56, "%d");
1703 LxtCheckEqual(ReceiveAddress.nl_groups, 0x3456789a, "%d");
1704
1705 //
1706 // The subsequent calls to recvfrom() pull out the responses before the
1707 // overflow happened. Only call recvfrom() 3 times here, so that the receive
1708 // buffer is not yet fully drained.
1709 //
1710
1711 for (Index = 0; Index < 3; Index++)
1712 {
1713 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1714 memset(&ReceiveAddress, 0, sizeof(ReceiveAddress));
1715 LxtCheckErrno(ReceiveResult = recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, (struct sockaddr*)&ReceiveAddress, &AddressLength));
1716
1717 ExpectedReceiveLength = NLMSG_LENGTH(sizeof(struct nlmsgerr));
1718 LxtCheckEqual(ReceiveResult, ExpectedReceiveLength, "%d");
1719 LxtCheckEqual(AddressLength, sizeof(struct sockaddr_nl), "%d");
1720 ReceiveHeader = (struct nlmsghdr*)ReceiveBuffer;
1721 LxtCheckEqual(ReceiveHeader->nlmsg_type, NLMSG_ERROR, "%d");
1722 LxtCheckEqual(ReceiveHeader->nlmsg_flags, 0, "%d");
1723 LxtCheckEqual(ReceiveHeader->nlmsg_seq, Sequence + Index, "%d");
1724 LxtCheckEqual(ReceiveHeader->nlmsg_pid, getpid(), "%d");
1725 LxtCheckEqual(ReceiveAddress.nl_family, AF_NETLINK, "%d");
1726 LxtCheckEqual(ReceiveAddress.nl_pid, 0, "%d");
1727 }
1728
1729 //
1730 // Check the socket option SO_ERROR. This should be 0 (no error),
1731 // since the error was cleared when the first recvfrom() returned ENOBUFS.
1732 //
1733
1734 SocketErrorSize = sizeof(SocketError);
1735 SocketError = 212;
1736 LxtCheckErrno(getsockopt(Socket, SOL_SOCKET, SO_ERROR, &SocketError, &SocketErrorSize));
1737
1738 LxtCheckEqual(SocketErrorSize, sizeof(SocketError), "%d");
1739 LxtCheckEqual(SocketError, 0, "%d");
1740
1741 //
1742 // Test that the receive buffer is still considered to be "overflown"
1743 // until the entire buffer is drained. This means that anything sent to
1744 // the socket now will be ignored and no response generated, even though
1745 // technically there is space in the receive buffer for the response.
1746 // The test sends a message with a unique sequence number. Later on, the
1747 // entire receive buffer will be drained and all responses checked to
1748 // verify that this unique sequence number is not in any of the responses.
1749 //
1750
1751 Request.nlmsg_seq = 0x98765432;
1752 LxtCheckErrno(SendResult = sendto(Socket, &Request, sizeof(Request), 0, (struct sockaddr*)&SendAddress, AddressLength));
1753
1754 LxtCheckEqual(SendResult, sizeof(Request), "%d");
1755
1756 //
1757 // Drain the entire response buffer. Set the recvfrom() timeout to 1 millisecond
1758 // so that it does not block infinitely.
1759 //
1760
1761 Timeout.tv_sec = 0;
1762 Timeout.tv_usec = 1000;
1763 LxtCheckErrno(setsockopt(Socket, SOL_SOCKET, SO_RCVTIMEO, &Timeout, sizeof(Timeout)));
1764
1765 for (;;)
1766 {
1767 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1768 memset(&ReceiveAddress, 0, sizeof(ReceiveAddress));
1769 ReceiveResult = recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, (struct sockaddr*)&ReceiveAddress, &AddressLength);
1770
1771 if (ReceiveResult == -1)
1772 {
1773 LxtCheckErrnoFailure(ReceiveResult, EAGAIN);
1774 break;
1775 }
1776 else
1777 {
1778 ExpectedReceiveLength = NLMSG_LENGTH(sizeof(struct nlmsgerr));
1779 LxtCheckEqual(ReceiveResult, ExpectedReceiveLength, "%d");
1780 LxtCheckEqual(AddressLength, sizeof(struct sockaddr_nl), "%d");
1781 ReceiveHeader = (struct nlmsghdr*)ReceiveBuffer;
1782 LxtCheckEqual(ReceiveHeader->nlmsg_type, NLMSG_ERROR, "%d");
1783 LxtCheckEqual(ReceiveHeader->nlmsg_flags, 0, "%d");
1784 LxtCheckNotEqual(ReceiveHeader->nlmsg_seq, 0, "%d");
1785 LxtCheckNotEqual(ReceiveHeader->nlmsg_seq, 0x98765432, "%d");
1786 LxtCheckEqual(ReceiveHeader->nlmsg_pid, getpid(), "%d");
1787 LxtCheckEqual(ReceiveAddress.nl_family, AF_NETLINK, "%d");
1788 LxtCheckEqual(ReceiveAddress.nl_pid, 0, "%d");
1789 }
1790 }
1791
1792 //
1793 // Overflow the receive buffer again by sending 3000 events.
1794 // Each send should succeed with the return value being the full number of
1795 // bytes the user sent.
1796 //
1797
1798 AddressLength = sizeof(SendAddress);
1799 memset(&SendAddress, 0, sizeof(SendAddress));
1800 SendAddress.nl_family = AF_NETLINK;
1801 SendAddress.nl_pid = 0;
1802 for (Index = 0; Index < 3000; Index++)
1803 {
1804 Request.nlmsg_seq = Sequence + Index;
1805 LxtCheckErrno(SendResult = sendto(Socket, &Request, sizeof(Request), 0, (struct sockaddr*)&SendAddress, AddressLength));
1806
1807 LxtCheckEqual(SendResult, sizeof(Request), "%d");
1808 }
1809
1810 //
1811 // Check the socket option SO_ERROR. This should be ENOBUFS,
1812 // since recvfrom() has not been called yet.
1813 //
1814
1815 SocketErrorSize = sizeof(SocketError);
1816 SocketError = 212;
1817 LxtCheckErrno(getsockopt(Socket, SOL_SOCKET, SO_ERROR, &SocketError, &SocketErrorSize));
1818
1819 LxtCheckEqual(SocketErrorSize, sizeof(SocketError), "%d");
1820 LxtCheckEqual(SocketError, ENOBUFS, "%d");
1821
1822 //
1823 // The first recvfrom() should be successful, since the ENOBUFS error
1824 // was already cleared when socket option SO_ERROR was retrieved.
1825 //
1826
1827 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1828 memset(&ReceiveAddress, 0, sizeof(ReceiveAddress));
1829 LxtCheckErrno(ReceiveResult = recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, (struct sockaddr*)&ReceiveAddress, &AddressLength));
1830
1831 ExpectedReceiveLength = NLMSG_LENGTH(sizeof(struct nlmsgerr));
1832 LxtCheckEqual(ReceiveResult, ExpectedReceiveLength, "%d");
1833 LxtCheckEqual(AddressLength, sizeof(struct sockaddr_nl), "%d");
1834 ReceiveHeader = (struct nlmsghdr*)ReceiveBuffer;
1835 LxtCheckEqual(ReceiveHeader->nlmsg_type, NLMSG_ERROR, "%d");
1836 LxtCheckEqual(ReceiveHeader->nlmsg_flags, 0, "%d");
1837 LxtCheckEqual(ReceiveHeader->nlmsg_seq, Sequence, "%d");
1838 LxtCheckEqual(ReceiveHeader->nlmsg_pid, getpid(), "%d");
1839 LxtCheckEqual(ReceiveAddress.nl_family, AF_NETLINK, "%d");
1840 LxtCheckEqual(ReceiveAddress.nl_pid, 0, "%d");
1841
1842 ErrorExit:
1843 if (Socket > 0)
1844 {
1845 close(Socket);
1846 }
1847
1848 return Result;
1849 }
1850
1851 int SocketNetlinkBlockedReader(PLXT_ARGS Args)
1852
1853 /*++
1854
1855 Routine Description:
1856
1857 This routine tests that blocked readers do not get unblocked when the socket
1858 is closed. Also verify that shutdown() is invalid on NETLINK sockets.
1859
1860 Arguments:
1861
1862 Args - Supplies the command line arguments.
1863
1864 Return Value:
1865
1866 Returns 0 on success, -1 on failure.
1867
1868 --*/
1869
1870 {
1871
1872 socklen_t AddressLength;
1873 struct sockaddr_nl BindAddress;
1874 void* PthreadResult;
1875 int Result;
1876 int Socket;
1877 pthread_t Thread;
1878 struct timespec Timeout = {0};
1879
1880 Result = LXT_RESULT_FAILURE;
1881 Socket = -1;
1882
1883 //
1884 // Create and bind socket.
1885 //
1886
1887 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
1888 memset(&BindAddress, 0, sizeof(BindAddress));
1889 BindAddress.nl_family = AF_NETLINK;
1890 AddressLength = sizeof(BindAddress);
1891 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
1892
1893 //
1894 // Create a reader thread that will block on 'recv'.
1895 //
1896
1897 LxtCheckResultError(pthread_create(&Thread, NULL, SocketBlockedReaderThread, &Socket));
1898
1899 //
1900 // Wait for sometime to allow the reader thread to block on read. There
1901 // is no other elegant way of knowing whether the thread has blocked.
1902 //
1903
1904 usleep(5000);
1905
1906 //
1907 // Shutdown is NOT supported for NETLINK sockets.
1908 //
1909
1910 LxtCheckErrnoFailure(shutdown(Socket, SHUT_RD), EOPNOTSUPP);
1911 LxtCheckErrnoFailure(shutdown(Socket, SHUT_WR), EOPNOTSUPP);
1912 LxtCheckErrnoFailure(shutdown(Socket, SHUT_RDWR), EOPNOTSUPP);
1913
1914 //
1915 // Closing the socket does not unblock the reader. The pthread_timedjoin_np()
1916 // should timeout since the reader thread is still blocked.
1917 //
1918
1919 LxtCheckErrnoZeroSuccess(close(Socket));
1920 usleep(5000);
1921 Timeout.tv_nsec = 5000;
1922 Result = pthread_timedjoin_np(Thread, &PthreadResult, &Timeout);
1923 if (Result != ETIMEDOUT)
1924 {
1925 LxtLogError(
1926 "Expecting pthread_tryjoin_np to return ETIMEDOUT(%d), "
1927 "but it returned with result: %d",
1928 ETIMEDOUT,
1929 Result);
1930
1931 goto ErrorExit;
1932 }
1933
1934 //
1935 // No other choice but to kill the reader thread.
1936 //
1937
1938 LxtCheckErrnoZeroSuccess(pthread_cancel(Thread));
1939 LxtCheckErrnoZeroSuccess(pthread_join(Thread, &PthreadResult));
1940 LxtCheckEqual(PthreadResult, PTHREAD_CANCELED, "%p");
1941
1942 ErrorExit:
1943 if (Socket > 0)
1944 {
1945 close(Socket);
1946 }
1947
1948 return Result;
1949 }
1950
1951 int SocketNetlinkEpoll(PLXT_ARGS Args)
1952
1953 /*++
1954
1955 Routine Description:
1956
1957 This routine tests that the epoll state is correct.
1958
1959 Arguments:
1960
1961 Args - Supplies the command line arguments.
1962
1963 Return Value:
1964
1965 Returns 0 on success, -1 on failure.
1966
1967 --*/
1968
1969 {
1970
1971 socklen_t AddressLength;
1972 struct sockaddr_nl BindAddress;
1973 int EdRead;
1974 int EdWrite;
1975 struct epoll_event EpollControlEvent;
1976 struct epoll_event EpollWaitEvent[2];
1977 int Index;
1978 char ReceiveBuffer[500];
1979 int ReceiveResult;
1980 struct nlmsghdr Request;
1981 int Result;
1982 int SendResult;
1983 int Socket;
1984
1985 Result = LXT_RESULT_FAILURE;
1986 Socket = -1;
1987
1988 //
1989 // Create socket.
1990 //
1991
1992 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW | SOCK_NONBLOCK, 0));
1993
1994 //
1995 // Create epoll containers for read and write and
1996 // add the socket descriptor to them.
1997 //
1998
1999 LxtCheckErrno(EdRead = epoll_create(1));
2000 EpollControlEvent.events = EPOLLIN;
2001 EpollControlEvent.data.fd = Socket;
2002 Result = epoll_ctl(EdRead, EPOLL_CTL_ADD, Socket, &EpollControlEvent);
2003 LxtCheckErrnoZeroSuccess(Result);
2004
2005 LxtCheckErrno(EdWrite = epoll_create(1));
2006 EpollControlEvent.events = EPOLLOUT;
2007 EpollControlEvent.data.fd = Socket;
2008 Result = epoll_ctl(EdWrite, EPOLL_CTL_ADD, Socket, &EpollControlEvent);
2009 LxtCheckErrnoZeroSuccess(Result);
2010
2011 //
2012 // Wait for data to be available with a timeout. This should timeout since
2013 // there is no data. Verify that write is available.
2014 //
2015
2016 Result = epoll_wait(EdRead, EpollWaitEvent, 2, 50);
2017 LxtCheckEqual(Result, 0, "%d");
2018 Result = epoll_wait(EdWrite, EpollWaitEvent, 2, 50);
2019 LxtCheckEqual(Result, 1, "%d");
2020
2021 //
2022 // Bind the socket.
2023 //
2024
2025 memset(&BindAddress, 0, sizeof(BindAddress));
2026 BindAddress.nl_family = AF_NETLINK;
2027 AddressLength = sizeof(BindAddress);
2028 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
2029
2030 //
2031 // Wait for data to be available with a timeout. This should timeout since
2032 // there is no data. Verify that write is available.
2033 //
2034
2035 Result = epoll_wait(EdRead, EpollWaitEvent, 2, 50);
2036 LxtCheckEqual(Result, 0, "%d");
2037 Result = epoll_wait(EdWrite, EpollWaitEvent, 2, 50);
2038 LxtCheckEqual(Result, 1, "%d");
2039
2040 //
2041 // Send 3000 messages. The receive buffer will overflow, but write is still
2042 // available. Read is available now.
2043 //
2044
2045 memset(&Request, 0, sizeof(Request));
2046 Request.nlmsg_len = NLMSG_LENGTH(0);
2047 Request.nlmsg_type = NLMSG_NOOP;
2048 Request.nlmsg_flags = NLM_F_ACK;
2049 for (Index = 0; Index < 3000; Index++)
2050 {
2051 LxtCheckErrno(SendResult = sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2052
2053 LxtCheckEqual(SendResult, sizeof(Request), "%d");
2054 }
2055
2056 Result = epoll_wait(EdRead, EpollWaitEvent, 2, 50);
2057 LxtCheckEqual(Result, 1, "%d");
2058 Result = epoll_wait(EdWrite, EpollWaitEvent, 2, 50);
2059 LxtCheckEqual(Result, 1, "%d");
2060
2061 //
2062 // Drain all the events. Write is still available, but read is not.
2063 //
2064
2065 LxtCheckErrnoFailure(recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, NULL, 0), ENOBUFS);
2066
2067 for (;;)
2068 {
2069 memset(&ReceiveBuffer, 0, sizeof(ReceiveBuffer));
2070 ReceiveResult = recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, NULL, 0);
2071
2072 if (ReceiveResult == -1)
2073 {
2074 LxtCheckErrnoFailure(ReceiveResult, EAGAIN);
2075 break;
2076 }
2077 }
2078
2079 Result = epoll_wait(EdRead, EpollWaitEvent, 2, 50);
2080 LxtCheckEqual(Result, 0, "%d");
2081 Result = epoll_wait(EdWrite, EpollWaitEvent, 2, 50);
2082 LxtCheckEqual(Result, 1, "%d");
2083
2084 //
2085 // Close the socket. Both read and write are not available.
2086 //
2087
2088 LxtCheckErrnoZeroSuccess(close(Socket));
2089 Result = epoll_wait(EdRead, EpollWaitEvent, 2, 50);
2090 LxtCheckEqual(Result, 0, "%d");
2091 Result = epoll_wait(EdWrite, EpollWaitEvent, 2, 50);
2092 LxtCheckEqual(Result, 0, "%d");
2093
2094 ErrorExit:
2095 if (Socket > 0)
2096 {
2097 close(Socket);
2098 }
2099
2100 if (EdRead > 0)
2101 {
2102 close(EdRead);
2103 }
2104
2105 if (EdWrite > 0)
2106 {
2107 close(EdWrite);
2108 }
2109
2110 return Result;
2111 }
2112
2113 int SocketNetlinkRecvmmsg(PLXT_ARGS Args)
2114
2115 /*++
2116
2117 Routine Description:
2118
2119 This routine tests the recvmmsg() syscall.
2120
2121 Arguments:
2122
2123 Args - Supplies the command line arguments.
2124
2125 Return Value:
2126
2127 Returns 0 on success, -1 on failure.
2128
2129 --*/
2130
2131 {
2132
2133 socklen_t AddressLength;
2134 struct sockaddr_nl BindAddress;
2135 NetlinkRecvmmsgBlockedReaderParams BlockedReaderParams;
2136 struct nlmsgerr* Error;
2137 struct nlmsghdr* Header;
2138 int Index;
2139 socklen_t OptionLength;
2140 void* PthreadResult;
2141 char ReceiveBuffers[10][1000];
2142 struct iovec ReceiveIovecs[10];
2143 struct mmsghdr ReceiveMessages[10];
2144 int ReceiveResult;
2145 int Result;
2146 int SendResult;
2147 int Socket;
2148 pthread_t Thread;
2149 struct timespec Timeout;
2150 struct timespec TimeoutPthread;
2151
2152 struct
2153 {
2154 struct nlmsghdr nlh;
2155 struct ifinfomsg ifm;
2156 struct rtattr ext_req __attribute__((aligned(NLMSG_ALIGNTO)));
2157 __u32 ext_filter_mask;
2158 } Request;
2159
2160 //
2161 // Create and bind socket. Create a RTM_GETLINK request. Note that the
2162 // request is not sent yet at this point.
2163 //
2164
2165 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
2166 memset(&BindAddress, 0, sizeof(BindAddress));
2167 BindAddress.nl_family = AF_NETLINK;
2168 AddressLength = sizeof(BindAddress);
2169 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
2170
2171 memset(&Request, 0, sizeof(Request));
2172 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP;
2173 Request.nlh.nlmsg_len = sizeof(Request);
2174 Request.nlh.nlmsg_type = RTM_GETLINK;
2175 Request.nlh.nlmsg_seq = 0x4567;
2176 Request.ifm.ifi_family = AF_NETLINK;
2177 Request.ext_req.rta_type = IFLA_EXT_MASK;
2178 Request.ext_req.rta_len = RTA_LENGTH(sizeof(__u32));
2179 Request.ext_filter_mask = RTEXT_FILTER_VF;
2180
2181 //
2182 // The timeout value passed to recvmmsg() is ignored - there is a bug in the
2183 // Linux kernel where the timeout does not work at all. In lxcore we ignore
2184 // this parameter.
2185 //
2186
2187 Timeout.tv_sec = 800;
2188 Timeout.tv_nsec = 0;
2189
2190 //
2191 // Set up the receive buffers.
2192 //
2193
2194 memset(ReceiveMessages, 0, sizeof(ReceiveMessages));
2195 for (Index = 0; Index < 10; Index++)
2196 {
2197 ReceiveIovecs[Index].iov_base = ReceiveBuffers[Index];
2198 ReceiveIovecs[Index].iov_len = 1000;
2199 ReceiveMessages[Index].msg_hdr.msg_iov = &ReceiveIovecs[Index];
2200 ReceiveMessages[Index].msg_hdr.msg_iovlen = 1;
2201 }
2202
2203 //
2204 // There is nothing to receive at this point. Test that MSG_DONTWAIT trumps
2205 // MSG_WAITFORONE and MSG_WAITALL, therefore EAGAIN is returned due to not waiting.
2206 //
2207
2208 LxtCheckErrnoFailure(Result = recvmmsg(Socket, ReceiveMessages, 1000, MSG_DONTWAIT | MSG_WAITFORONE | MSG_WAITALL, &Timeout), EAGAIN);
2209
2210 LxtCheckErrnoFailure(Result = recvmmsg(Socket, ReceiveMessages, 1000, MSG_DONTWAIT | MSG_WAITFORONE, &Timeout), EAGAIN);
2211
2212 LxtCheckErrnoFailure(Result = recvmmsg(Socket, ReceiveMessages, 1000, MSG_DONTWAIT | MSG_WAITALL, &Timeout), EAGAIN);
2213
2214 LxtCheckErrnoFailure(Result = recvmmsg(Socket, ReceiveMessages, 1000, MSG_DONTWAIT, &Timeout), EAGAIN);
2215
2216 //
2217 // Set a SO_RCVTIMEO timeout value of 8 milliseconds for the receive. This timeout
2218 // applies to each individual recvmsg() call and actually works. Both calls to
2219 // recvmmsg below should time out from the SO_RCVTIMEO.
2220 //
2221
2222 LxtCheckResult(SocketNetlinkSetAndVerifySocketOptionTimeout(Socket, SO_RCVTIMEO, 8000));
2223
2224 LxtCheckErrnoFailure(Result = recvmmsg(Socket, ReceiveMessages, 1000, MSG_WAITFORONE, &Timeout), EAGAIN);
2225
2226 LxtCheckErrnoFailure(Result = recvmmsg(Socket, ReceiveMessages, 1000, 0, &Timeout), EAGAIN);
2227
2228 //
2229 // Restore the SO_RCVTIMEO timeout to 0 (never times out).
2230 //
2231
2232 LxtCheckResult(SocketNetlinkSetAndVerifySocketOptionTimeout(Socket, SO_RCVTIMEO, 0));
2233
2234 //
2235 // Test blocking behavior when zero flags (option 0) and when MSG_WAITFORONE
2236 // (option 1) is passed to recvmmsg. Create a new thread that blocks forever,
2237 // then cancel the thread after waiting for some time.
2238 //
2239
2240 for (Index = 0; Index < 2; Index++)
2241 {
2242
2243 //
2244 // Create a reader thread that will block on 'recvmmsg'.
2245 //
2246
2247 BlockedReaderParams.Socket = Socket;
2248 BlockedReaderParams.Option = Index;
2249 LxtCheckResultError(pthread_create(&Thread, NULL, SocketNetlinkRecvmmsgBlockedReaderThread, &BlockedReaderParams));
2250
2251 //
2252 // Wait for sometime to allow the reader thread to block on read. There
2253 // is no other elegant way of knowing whether the thread has blocked.
2254 //
2255
2256 usleep(5000);
2257
2258 //
2259 // The pthread_timedjoin_np() should timeout since the reader thread is
2260 // still blocked.
2261 //
2262
2263 TimeoutPthread.tv_sec = 0;
2264 TimeoutPthread.tv_nsec = 5000;
2265 Result = pthread_timedjoin_np(Thread, &PthreadResult, &TimeoutPthread);
2266 if (Result != ETIMEDOUT)
2267 {
2268 LxtLogError(
2269 "Expecting pthread_tryjoin_np to return ETIMEDOUT(%d), "
2270 "but it returned with result: %d for index: %d",
2271 ETIMEDOUT,
2272 Result,
2273 Index);
2274
2275 goto ErrorExit;
2276 }
2277
2278 //
2279 // No other choice but to kill the reader thread.
2280 //
2281
2282 LxtCheckErrnoZeroSuccess(pthread_cancel(Thread));
2283 LxtCheckErrnoZeroSuccess(pthread_join(Thread, &PthreadResult));
2284 LxtCheckEqual(PthreadResult, PTHREAD_CANCELED, "%p");
2285 }
2286
2287 //
2288 // Now generate a lot of Netlink responses waiting to be read.
2289 //
2290
2291 for (Index = 0; Index < 10; Index++)
2292 {
2293 LxtCheckErrno(SendResult = send(Socket, &Request, sizeof(Request), 0));
2294 LxtCheckEqual(SendResult, sizeof(Request), "%d");
2295 }
2296
2297 //
2298 // Test various combinations of input parameters and verify the output.
2299 //
2300
2301 LxtCheckErrno(Result = recvmmsg(Socket, ReceiveMessages, 3, MSG_DONTWAIT | MSG_WAITFORONE | MSG_WAITALL | MSG_PEEK | MSG_TRUNC, &Timeout));
2302
2303 LxtCheckEqual(Result, 3, "%d");
2304 LxtCheckNotEqual(ReceiveMessages[0].msg_len, 0, "%d");
2305 LxtCheckNotEqual(ReceiveMessages[1].msg_len, 0, "%d");
2306 LxtCheckNotEqual(ReceiveMessages[2].msg_len, 0, "%d");
2307 LxtCheckEqual(ReceiveMessages[3].msg_len, 0, "%d");
2308 LxtCheckErrno(Result = recvmmsg(Socket, ReceiveMessages, 2, MSG_DONTWAIT, &Timeout));
2309 LxtCheckEqual(Result, 2, "%d");
2310 LxtCheckNotEqual(ReceiveMessages[0].msg_len, 0, "%d");
2311 LxtCheckNotEqual(ReceiveMessages[1].msg_len, 0, "%d");
2312 LxtCheckNotEqual(ReceiveMessages[2].msg_len, 0, "%d");
2313 LxtCheckEqual(ReceiveMessages[3].msg_len, 0, "%d");
2314 ReceiveMessages[0].msg_len = 0;
2315 ReceiveMessages[1].msg_len = 0;
2316 ReceiveMessages[2].msg_len = 0;
2317 LxtCheckErrno(Result = recvmmsg(Socket, ReceiveMessages, 1, 0, &Timeout));
2318 LxtCheckEqual(Result, 1, "%d");
2319 LxtCheckNotEqual(ReceiveMessages[0].msg_len, 0, "%d");
2320 LxtCheckEqual(ReceiveMessages[1].msg_len, 0, "%d");
2321 LxtCheckEqual(ReceiveMessages[2].msg_len, 0, "%d");
2322 LxtCheckEqual(ReceiveMessages[3].msg_len, 0, "%d");
2323 LxtCheckErrno(Result = recvmmsg(Socket, ReceiveMessages, 1, MSG_WAITFORONE, &Timeout));
2324 LxtCheckEqual(Result, 1, "%d");
2325 LxtCheckNotEqual(ReceiveMessages[0].msg_len, 0, "%d");
2326 LxtCheckEqual(ReceiveMessages[1].msg_len, 0, "%d");
2327 LxtCheckEqual(ReceiveMessages[2].msg_len, 0, "%d");
2328 LxtCheckEqual(ReceiveMessages[3].msg_len, 0, "%d");
2329 Result = LXT_RESULT_SUCCESS;
2330
2331 ErrorExit:
2332 if (Socket > 0)
2333 {
2334 close(Socket);
2335 }
2336
2337 return Result;
2338 }
2339
2340 void* SocketNetlinkRecvmmsgBlockedReaderThread(void* Arg)
2341
2342 /*++
2343
2344 Routine Description:
2345
2346 This routine will call recvmmsg on the given socket fd and block.
2347
2348 Arguments:
2349
2350 Arg - Supplies the socket fd to read and the options.
2351
2352 Return Value:
2353
2354 Returns 0 on success, -1 on failure.
2355
2356 --*/
2357
2358 {
2359
2360 NetlinkRecvmmsgBlockedReaderParams* BlockedReaderParams;
2361 int Flags;
2362 int Index;
2363 int MessagesRead;
2364 char ReceiveBuffers[20][1000];
2365 struct iovec ReceiveIovecs[20];
2366 struct mmsghdr ReceiveMessages[20];
2367 int Result = LXT_RESULT_FAILURE;
2368 int Socket;
2369 struct timespec Timeout;
2370
2371 //
2372 // The timeout value passed to recvmmsg() is ignored. Set up the receive
2373 // buffers.
2374 //
2375
2376 BlockedReaderParams = (NetlinkRecvmmsgBlockedReaderParams*)Arg;
2377 Socket = BlockedReaderParams->Socket;
2378 Timeout.tv_sec = 800;
2379 Timeout.tv_nsec = 0;
2380 memset(ReceiveMessages, 0, sizeof(ReceiveMessages));
2381 for (Index = 0; Index < 20; Index++)
2382 {
2383 ReceiveIovecs[Index].iov_base = ReceiveBuffers[Index];
2384 ReceiveIovecs[Index].iov_len = 1000;
2385 ReceiveMessages[Index].msg_hdr.msg_iov = &ReceiveIovecs[Index];
2386 ReceiveMessages[Index].msg_hdr.msg_iovlen = 1;
2387 }
2388
2389 //
2390 // The flags passed to recvmmsg() depend on the option value passed into
2391 // this function.
2392 //
2393
2394 switch (BlockedReaderParams->Option)
2395 {
2396 case 0:
2397 Flags = 0;
2398 break;
2399
2400 case 1:
2401 Flags = MSG_WAITFORONE;
2402 break;
2403
2404 default:
2405 LxtLogError("Incorrect option: %d", BlockedReaderParams->Option);
2406 goto ErrorExit;
2407 }
2408
2409 LxtCheckErrno(MessagesRead = recvmmsg(Socket, ReceiveMessages, 20, Flags, NULL));
2410 if (MessagesRead != 0)
2411 {
2412 LxtLogError(
2413 "recvmmsg should return 0 messages read, "
2414 "but it returned %d messages for flags %x",
2415 MessagesRead,
2416 Flags);
2417
2418 goto ErrorExit;
2419 }
2420
2421 LxtLogInfo("recvmmsg unblocked, flags %x", Flags);
2422 Result = LXT_RESULT_SUCCESS;
2423
2424 ErrorExit:
2425 pthread_exit((void*)(ssize_t)Result);
2426 }
2427
2428 int SocketNetlinkSendBadMessage(PLXT_ARGS Args)
2429
2430 /*++
2431
2432 Routine Description:
2433
2434 This routine sends bad Netlink messages, to test that the system does not crash.
2435
2436 Arguments:
2437
2438 Args - Supplies the command line arguments.
2439
2440 Return Value:
2441
2442 Returns 0 on success, -1 on failure.
2443
2444 --*/
2445
2446 {
2447
2448 socklen_t AddressLength;
2449 struct sockaddr_nl BindAddress;
2450 char* Buffer;
2451 struct nlmsghdr* Header;
2452 char ReceiveBuffer;
2453 int Result;
2454 int Socket;
2455 int TypeIterator;
2456
2457 Buffer = malloc(PAGE_SIZE * 2);
2458 LxtCheckTrue(Buffer != NULL);
2459 Header = (struct nlmsghdr*)(((uint64_t)(Buffer + PAGE_SIZE) & ~(PAGE_SIZE - 1)) - sizeof(struct nlmsghdr));
2460 LxtLogInfo("Malloc end of page: %p", Header);
2461 for (TypeIterator = 0; TypeIterator < sizeof(MessageTypes) / sizeof(int); TypeIterator++)
2462 {
2463
2464 LxtLogInfo("Checking message type: %d", MessageTypes[TypeIterator]);
2465 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
2466 memset(&BindAddress, 0, sizeof(BindAddress));
2467 BindAddress.nl_family = AF_NETLINK;
2468 AddressLength = sizeof(BindAddress);
2469 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
2470
2471 Header->nlmsg_flags = NLM_F_REQUEST;
2472 Header->nlmsg_len = sizeof(struct nlmsghdr);
2473 Header->nlmsg_type = MessageTypes[TypeIterator];
2474 Header->nlmsg_seq = 0x4567;
2475 sendto(Socket, Header, sizeof(struct nlmsghdr), 0, NULL, 0);
2476 }
2477
2478 Result = LXT_RESULT_SUCCESS;
2479
2480 ErrorExit:
2481 if (Socket > 0)
2482 {
2483 close(Socket);
2484 }
2485
2486 if (Buffer != NULL)
2487 {
2488 free(Buffer);
2489 }
2490
2491 return Result;
2492 }
2493
2494 void SocketNetlinkRouteDumpAttributeData(char* Buffer, int BufferSize, struct rtattr* Attribute)
2495
2496 /*++
2497
2498 Routine Description:
2499
2500 This routine dumps the data in the NETLINK_ROUTE protocol's RT attribute.
2501
2502 Arguments:
2503
2504 Buffer - Supplies a pointer to the buffer to write the dumped data to.
2505
2506 Attribute - Supplies a pointer to the RT attribute to dump.
2507
2508 Return Value:
2509
2510 None.
2511
2512 --*/
2513
2514 {
2515
2516 unsigned char* AttributeCurrent;
2517 char* BufferCurrent;
2518 int Index;
2519
2520 AttributeCurrent = (unsigned char*)RTA_DATA(Attribute);
2521 BufferCurrent = Buffer;
2522 memset(Buffer, 0, BufferSize);
2523
2524 //
2525 // Each char takes 3 bytes in the dump buffer.
2526 //
2527
2528 for (Index = 0; Index < min((BufferSize - 1) / 3, RTA_PAYLOAD(Attribute)); Index++)
2529 {
2530 sprintf(BufferCurrent, "%02x ", *AttributeCurrent);
2531 AttributeCurrent += 1;
2532 BufferCurrent += 3;
2533 }
2534
2535 return;
2536 }
2537
2538 int SocketNetlinkRouteGetAddr(PLXT_ARGS Args)
2539
2540 /*++
2541
2542 Routine Description:
2543
2544 This routine tests the NETLINK_ROUTE protocol's RTM_GETADDR message.
2545
2546 Arguments:
2547
2548 Args - Supplies the command line arguments.
2549
2550 Return Value:
2551
2552 Returns 0 on success, -1 on failure.
2553
2554 --*/
2555
2556 {
2557
2558 socklen_t AddressLength;
2559 struct rtattr* Attribute;
2560 char AttributeDump[ATTRIBUTE_DUMP_BUFFER_SIZE];
2561 int AttributeSeenAddress;
2562 int AttributeSeenCacheInfo;
2563 struct sockaddr_nl BindAddress;
2564 struct nlmsgerr* Error;
2565 int FoundDone;
2566 struct nlmsghdr* Header;
2567 struct ifaddrmsg* IfAddrMsg;
2568 char ReceiveBuffer[5000];
2569 int ReceiveResult;
2570 int RemainingLength;
2571 int Result;
2572 int Socket;
2573
2574 struct
2575 {
2576 struct nlmsghdr nlh;
2577 struct ifinfomsg ifm;
2578 struct rtattr ext_req __attribute__((aligned(NLMSG_ALIGNTO)));
2579 __u32 ext_filter_mask;
2580 } Request;
2581
2582 AttributeSeenAddress = 0;
2583 AttributeSeenCacheInfo = 0;
2584
2585 //
2586 // Create and bind socket. Create a RTM_GETADDR request.
2587 //
2588
2589 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
2590 memset(&BindAddress, 0, sizeof(BindAddress));
2591 BindAddress.nl_family = AF_NETLINK;
2592 AddressLength = sizeof(BindAddress);
2593 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
2594
2595 memset(&Request, 0, sizeof(Request));
2596 Request.nlh.nlmsg_len = sizeof(Request);
2597 Request.nlh.nlmsg_type = RTM_GETADDR;
2598 Request.nlh.nlmsg_seq = 0x4563;
2599 Request.ifm.ifi_family = AF_NETLINK;
2600 Request.ext_req.rta_type = IFLA_EXT_MASK;
2601 Request.ext_req.rta_len = RTA_LENGTH(sizeof(__u32));
2602 Request.ext_filter_mask = RTEXT_FILTER_VF;
2603
2604 //
2605 // Test flags. Only passing the NLM_F_REQUEST flag returns an Error.
2606 //
2607
2608 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
2609 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2610 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
2611
2612 Header = (struct nlmsghdr*)ReceiveBuffer;
2613 LxtCheckTrue(NLMSG_OK(Header, ReceiveResult));
2614 LxtCheckEqual(Header->nlmsg_type, NLMSG_ERROR, "%d");
2615 Error = (struct nlmsgerr*)NLMSG_DATA(Header);
2616 LxtCheckEqual(Error->error, -EOPNOTSUPP, "%d");
2617 LxtCheckEqual(memcmp(&Error->msg, &Request, sizeof(Request)), 0, "%d");
2618
2619 //
2620 // Test flags. Only passing the NLM_F_REQUEST flag returns an Error.
2621 // Verify that adding a NLM_F_ACK flag still returns an Error.
2622 //
2623
2624 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
2625 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2626 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
2627
2628 Header = (struct nlmsghdr*)ReceiveBuffer;
2629 LxtCheckTrue(NLMSG_OK(Header, ReceiveResult));
2630 LxtCheckEqual(Header->nlmsg_type, NLMSG_ERROR, "%d");
2631 Error = (struct nlmsgerr*)NLMSG_DATA(Header);
2632 LxtCheckEqual(Error->error, -EOPNOTSUPP, "%d");
2633 LxtCheckEqual(memcmp(&Error->msg, &Request, sizeof(Request)), 0, "%d");
2634
2635 //
2636 // Test flags. Only passing the NLM_F_ROOT and/or NLM_F_MATCH flag(s)
2637 // result in no response.
2638 //
2639
2640 Request.nlh.nlmsg_flags = NLM_F_ROOT;
2641 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2642 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
2643
2644 Request.nlh.nlmsg_flags = NLM_F_MATCH;
2645 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2646 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
2647
2648 Request.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH;
2649 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2650 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
2651
2652 //
2653 // Test flags. Passing 0 flags or invalid flags result in no response.
2654 //
2655
2656 Request.nlh.nlmsg_flags = 0;
2657 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2658 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
2659
2660 Request.nlh.nlmsg_flags = 0x40;
2661 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2662 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
2663
2664 //
2665 // Test flags. NLM_F_REQUEST and at least one of NLM_F_ROOT/NLM_F_MATCH
2666 // results in the correct response.
2667 // For the response, verify the presence of several attributes.
2668 //
2669
2670 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
2671 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2672 FoundDone = 0;
2673 for (;;)
2674 {
2675 LxtCheckErrno(ReceiveResult = recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, NULL, 0));
2676
2677 Header = (struct nlmsghdr*)ReceiveBuffer;
2678 while (NLMSG_OK(Header, ReceiveResult))
2679 {
2680 if (Header->nlmsg_type == NLMSG_DONE)
2681 {
2682 FoundDone = 1;
2683 break;
2684 }
2685
2686 IfAddrMsg = (struct ifaddrmsg*)NLMSG_DATA(Header);
2687 LxtLogInfo(
2688 "ifaddrmsg: ifa_family %d ifa_prefixlen %d "
2689 "ifa_flags %d ifa_scope %d ifa_index %d",
2690 IfAddrMsg->ifa_family,
2691 IfAddrMsg->ifa_prefixlen,
2692 IfAddrMsg->ifa_flags,
2693 IfAddrMsg->ifa_scope,
2694 IfAddrMsg->ifa_index);
2695
2696 Attribute = (struct rtattr*)((char*)IfAddrMsg + sizeof(struct ifaddrmsg));
2697
2698 RemainingLength = Header->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg));
2699
2700 while (RTA_OK(Attribute, RemainingLength))
2701 {
2702 SocketNetlinkRouteDumpAttributeData(AttributeDump, ATTRIBUTE_DUMP_BUFFER_SIZE, Attribute);
2703
2704 LxtLogInfo("RTATTR type: %2d len: %3d data: %s", Attribute->rta_type, Attribute->rta_len, AttributeDump);
2705
2706 if (Attribute->rta_type == IFA_ADDRESS)
2707 {
2708 AttributeSeenAddress += 1;
2709 }
2710 else if (Attribute->rta_type == IFA_CACHEINFO)
2711 {
2712 LxtCheckEqual(Attribute->rta_len, RTA_LENGTH(sizeof(struct ifa_cacheinfo)), "%d");
2713
2714 AttributeSeenCacheInfo += 1;
2715 }
2716
2717 Attribute = RTA_NEXT(Attribute, RemainingLength);
2718 }
2719
2720 Header = NLMSG_NEXT(Header, ReceiveResult);
2721 }
2722
2723 if (FoundDone == 1)
2724 {
2725 break;
2726 }
2727 }
2728
2729 LxtCheckTrue(AttributeSeenAddress > 0);
2730 LxtCheckTrue(AttributeSeenCacheInfo > 0);
2731
2732 ErrorExit:
2733 if (Socket > 0)
2734 {
2735 close(Socket);
2736 }
2737
2738 return Result;
2739 }
2740
2741 int SocketNetlinkRouteGetLink(PLXT_ARGS Args)
2742
2743 /*++
2744
2745 Routine Description:
2746
2747 This routine tests the NETLINK_ROUTE protocol's RTM_GETLINK message.
2748
2749 Arguments:
2750
2751 Args - Supplies the command line arguments.
2752
2753 Return Value:
2754
2755 Returns 0 on success, -1 on failure.
2756
2757 --*/
2758
2759 {
2760
2761 socklen_t AddressLength;
2762 struct sockaddr_nl BindAddress;
2763 pid_t ChildPid;
2764 int ChildSocket;
2765 struct nlmsgerr* Error;
2766 struct nlmsghdr* Header;
2767 int Index;
2768 char InterfaceName[32];
2769 int LoopbackIndex;
2770 char ReceiveBuffer[5000];
2771 int ReceiveResult;
2772 int Result;
2773 int SendResult;
2774 int Socket;
2775
2776 struct
2777 {
2778 struct nlmsghdr nlh;
2779 struct ifinfomsg ifm;
2780 char Attributes[200];
2781 } Request;
2782
2783 //
2784 // Create and bind socket. Create a RTM_GETLINK request.
2785 //
2786
2787 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
2788 memset(&BindAddress, 0, sizeof(BindAddress));
2789 BindAddress.nl_family = AF_NETLINK;
2790 AddressLength = sizeof(BindAddress);
2791 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
2792
2793 memset(&Request, 0, sizeof(Request));
2794 Request.nlh.nlmsg_len = sizeof(Request);
2795 Request.nlh.nlmsg_type = RTM_GETLINK;
2796 Request.nlh.nlmsg_seq = 0x4567;
2797 Request.ifm.ifi_family = AF_NETLINK;
2798
2799 //
2800 // Test flags. Only passing the NLM_F_REQUEST flag with no network interface
2801 // specified returns an Error.
2802 //
2803
2804 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
2805 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2806 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
2807
2808 Header = (struct nlmsghdr*)ReceiveBuffer;
2809 LxtCheckTrue(NLMSG_OK(Header, ReceiveResult));
2810 LxtCheckEqual(Header->nlmsg_type, NLMSG_ERROR, "%d");
2811 Error = (struct nlmsgerr*)NLMSG_DATA(Header);
2812 LxtCheckEqual(Error->error, -EINVAL, "%d");
2813 LxtCheckEqual(memcmp(&Error->msg, &Request, sizeof(Request)), 0, "%d");
2814
2815 //
2816 // Test flags. Only passing the NLM_F_REQUEST flag with no network interface
2817 // returns an Error. Verify that adding a NLM_F_ACK flag still returns an Error.
2818 //
2819
2820 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
2821 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2822 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
2823
2824 Header = (struct nlmsghdr*)ReceiveBuffer;
2825 LxtCheckTrue(NLMSG_OK(Header, ReceiveResult));
2826 LxtCheckEqual(Header->nlmsg_type, NLMSG_ERROR, "%d");
2827 Error = (struct nlmsgerr*)NLMSG_DATA(Header);
2828 LxtCheckEqual(Error->error, -EINVAL, "%d");
2829 LxtCheckEqual(memcmp(&Error->msg, &Request, sizeof(Request)), 0, "%d");
2830
2831 //
2832 // Test flags. Only passing the NLM_F_ROOT and/or NLM_F_MATCH flag(s)
2833 // result in no response.
2834 //
2835
2836 Request.nlh.nlmsg_flags = NLM_F_ROOT;
2837 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2838 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
2839
2840 Request.nlh.nlmsg_flags = NLM_F_MATCH;
2841 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2842 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
2843
2844 Request.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH;
2845 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2846 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
2847
2848 //
2849 // Test flags. Passing 0 flags or invalid flags result in no response.
2850 //
2851
2852 Request.nlh.nlmsg_flags = 0;
2853 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2854 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
2855
2856 Request.nlh.nlmsg_flags = 0x40;
2857 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2858 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
2859
2860 //
2861 // Test filter mode.
2862 // When passing only the NLM_F_REQUEST flag, "filter" mode is used.
2863 // In this mode, either ifinfomsg.ifi_index must be valid, or IFLA_IFNAME
2864 // must be present to filter the response to one network interface.
2865 //
2866
2867 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
2868
2869 //
2870 // Passing a zero ifi_index returns an Error.
2871 //
2872
2873 Request.ifm.ifi_index = 0;
2874 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2875 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
2876
2877 Header = (struct nlmsghdr*)ReceiveBuffer;
2878 LxtCheckTrue(NLMSG_OK(Header, ReceiveResult));
2879 LxtCheckEqual(Header->nlmsg_type, NLMSG_ERROR, "%d");
2880 Error = (struct nlmsgerr*)NLMSG_DATA(Header);
2881 LxtCheckEqual(Error->error, -EINVAL, "%d");
2882
2883 //
2884 // Passing a negative ifi_index returns an Error.
2885 //
2886
2887 Request.ifm.ifi_index = -1;
2888 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2889 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
2890
2891 Header = (struct nlmsghdr*)ReceiveBuffer;
2892 LxtCheckTrue(NLMSG_OK(Header, ReceiveResult));
2893 LxtCheckEqual(Header->nlmsg_type, NLMSG_ERROR, "%d");
2894 Error = (struct nlmsgerr*)NLMSG_DATA(Header);
2895 LxtCheckEqual(Error->error, -EINVAL, "%d");
2896
2897 //
2898 // Passing a bad ifi_index and the correct interface name returns an Error.
2899 //
2900
2901 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
2902 Request.ifm.ifi_index = 100;
2903 strcpy(InterfaceName, "lo");
2904 LxtCheckErrnoZeroSuccess(
2905 SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), IFLA_IFNAME, InterfaceName, strlen(InterfaceName) + 1));
2906
2907 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2908 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
2909
2910 Header = (struct nlmsghdr*)ReceiveBuffer;
2911 LxtCheckTrue(NLMSG_OK(Header, ReceiveResult));
2912 LxtCheckEqual(Header->nlmsg_type, NLMSG_ERROR, "%d");
2913 Error = (struct nlmsgerr*)NLMSG_DATA(Header);
2914 LxtCheckEqual(Error->error, -ENODEV, "%d");
2915
2916 //
2917 // Passing a negative ifi_index and the correct interface name results in the
2918 // correct response.
2919 //
2920
2921 Request.ifm.ifi_index = -1;
2922 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2923 LxtCheckResult(SocketNetlinkRouteGetLinkCheckResponse(Socket, TRUE));
2924
2925 //
2926 // Passing a zero ifi_index and the correct interface name results in the
2927 // correct response.
2928 //
2929
2930 Request.ifm.ifi_index = 0;
2931 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2932 LxtCheckResult(SocketNetlinkRouteGetLinkCheckResponse(Socket, TRUE));
2933
2934 //
2935 // Passing a bad ifi_index and a bad interface name returns an Error.
2936 //
2937
2938 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
2939 Request.ifm.ifi_index = 100;
2940 strcpy(InterfaceName, "loooo");
2941 LxtCheckErrnoZeroSuccess(
2942 SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), IFLA_IFNAME, InterfaceName, strlen(InterfaceName) + 1));
2943
2944 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2945 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
2946
2947 Header = (struct nlmsghdr*)ReceiveBuffer;
2948 LxtCheckTrue(NLMSG_OK(Header, ReceiveResult));
2949 LxtCheckEqual(Header->nlmsg_type, NLMSG_ERROR, "%d");
2950 Error = (struct nlmsgerr*)NLMSG_DATA(Header);
2951 LxtCheckEqual(Error->error, -ENODEV, "%d");
2952
2953 //
2954 // Passing a zero ifi_index and a bad interface name returns an Error.
2955 //
2956
2957 Request.ifm.ifi_index = 0;
2958 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2959 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
2960
2961 Header = (struct nlmsghdr*)ReceiveBuffer;
2962 LxtCheckTrue(NLMSG_OK(Header, ReceiveResult));
2963 LxtCheckEqual(Header->nlmsg_type, NLMSG_ERROR, "%d");
2964 Error = (struct nlmsgerr*)NLMSG_DATA(Header);
2965 LxtCheckEqual(Error->error, -ENODEV, "%d");
2966
2967 //
2968 // Passing a negative ifi_index and a bad interface name returns an Error.
2969 //
2970
2971 Request.ifm.ifi_index = -1;
2972 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2973 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
2974
2975 Header = (struct nlmsghdr*)ReceiveBuffer;
2976 LxtCheckTrue(NLMSG_OK(Header, ReceiveResult));
2977 LxtCheckEqual(Header->nlmsg_type, NLMSG_ERROR, "%d");
2978 Error = (struct nlmsgerr*)NLMSG_DATA(Header);
2979 LxtCheckEqual(Error->error, -ENODEV, "%d");
2980
2981 //
2982 // Get the interface index of the loopback adapter.
2983 //
2984
2985 LxtCheckErrnoZeroSuccess(SocketNetlinkGetLoopbackIndex(&LoopbackIndex));
2986 LxtCheckTrue(LoopbackIndex > 0);
2987
2988 //
2989 // Passing a correct ifi_index and a bad interface name results in the
2990 // correct response.
2991 //
2992
2993 Request.ifm.ifi_index = LoopbackIndex;
2994 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
2995 LxtCheckResult(SocketNetlinkRouteGetLinkCheckResponse(Socket, TRUE));
2996
2997 //
2998 // Passing a correct ifi_index and no interface name results in the
2999 // correct response.
3000 //
3001
3002 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
3003 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3004 LxtCheckResult(SocketNetlinkRouteGetLinkCheckResponse(Socket, TRUE));
3005
3006 //
3007 // Test dump mode.
3008 // NLM_F_REQUEST and at least one of NLM_F_ROOT/NLM_F_MATCH
3009 // results in the correct response.
3010 // For the response, verify that at least one interface is present (loopback),
3011 // and also verify the presence of several attributes.
3012 //
3013
3014 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
3015 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3016 LxtCheckResult(SocketNetlinkRouteGetLinkCheckResponse(Socket, FALSE));
3017
3018 //
3019 // Create a child process and switch it to a new network namespace.
3020 // RTM_GETLINK should only return one network interface - loopback.
3021 //
3022
3023 LxtCheckErrno(ChildPid = fork());
3024 if (ChildPid == 0)
3025 {
3026 LxtCheckErrnoZeroSuccess(unshare(CLONE_NEWNET));
3027
3028 //
3029 // N.B. The sleep is because it can take some time for the lxcore cache to get
3030 // the new network interface notification.
3031 //
3032
3033 usleep(1000 * 100);
3034 LxtLogInfo("Now testing child socket");
3035 LxtCheckErrno(ChildSocket = socket(AF_NETLINK, SOCK_RAW, 0));
3036 LxtCheckErrno(sendto(ChildSocket, &Request, sizeof(Request), 0, NULL, 0));
3037 LxtCheckResult(SocketNetlinkRouteGetLinkCheckResponse(ChildSocket, TRUE));
3038 LxtClose(ChildSocket);
3039 exit(0);
3040 }
3041
3042 LxtCheckResult(LxtWaitPidPoll(ChildPid, 0));
3043
3044 //
3045 // Check that sending is still successful even if the
3046 // receive buffer has overflown.
3047 //
3048
3049 for (Index = 0; Index < 1000; Index++)
3050 {
3051 LxtCheckErrno(SendResult = send(Socket, &Request, sizeof(Request), 0));
3052 LxtCheckEqual(SendResult, sizeof(Request), "%d");
3053 }
3054
3055 ErrorExit:
3056 if (Socket > 0)
3057 {
3058 close(Socket);
3059 }
3060
3061 return Result;
3062 }
3063
3064 int SocketNetlinkRouteGetLinkCheckResponse(int Socket, int OnlyOneInterface)
3065
3066 /*++
3067
3068 Routine Description:
3069
3070 This routine checks the response of the NETLINK_ROUTE protocol's
3071 RTM_GETLINK message.
3072
3073 Arguments:
3074
3075 Socket - Supplies the socket to read the response from.
3076
3077 OnlyOneInterface - Supplies a boolean indicating whether there should only
3078 be one network interface in the response.
3079
3080 Return Value:
3081
3082 Returns 0 on success, -1 on failure.
3083
3084 --*/
3085
3086 {
3087
3088 struct rtattr* Attribute;
3089 char AttributeDump[ATTRIBUTE_DUMP_BUFFER_SIZE];
3090 int AttributeSeenAddress;
3091 int AttributeSeenMtu;
3092 int AttributeSeenName;
3093 int FoundDone;
3094 struct nlmsghdr* Header;
3095 struct ifinfomsg* IfInfoMsg;
3096 int InterfaceCount;
3097 char ReceiveBuffer[5000];
3098 int ReceiveResult;
3099 int RemainingLength;
3100 int Result;
3101 int SeenLoopback;
3102
3103 AttributeSeenAddress = 0;
3104 AttributeSeenMtu = 0;
3105 AttributeSeenName = 0;
3106 SeenLoopback = 0;
3107 FoundDone = 0;
3108 InterfaceCount = 0;
3109 for (;;)
3110 {
3111 LxtCheckErrno(ReceiveResult = recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, NULL, 0));
3112
3113 Header = (struct nlmsghdr*)ReceiveBuffer;
3114 while (NLMSG_OK(Header, ReceiveResult))
3115 {
3116 if (Header->nlmsg_type == NLMSG_DONE)
3117 {
3118 FoundDone = 1;
3119 break;
3120 }
3121
3122 IfInfoMsg = (struct ifinfomsg*)NLMSG_DATA(Header);
3123 LxtLogInfo(
3124 "ifinfomsg: ifi_family %d ifi_type %d "
3125 "ifi_index %d ifi_flags %d ifi_change %d",
3126 IfInfoMsg->ifi_family,
3127 IfInfoMsg->ifi_type,
3128 IfInfoMsg->ifi_index,
3129 IfInfoMsg->ifi_flags,
3130 IfInfoMsg->ifi_change);
3131
3132 InterfaceCount += 1;
3133 if ((IfInfoMsg->ifi_flags & IFF_LOOPBACK) != 0)
3134 {
3135 SeenLoopback += 1;
3136 }
3137
3138 Attribute = (struct rtattr*)((char*)IfInfoMsg + sizeof(struct ifinfomsg));
3139
3140 RemainingLength = Header->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
3141
3142 while (RTA_OK(Attribute, RemainingLength))
3143 {
3144 SocketNetlinkRouteDumpAttributeData(AttributeDump, ATTRIBUTE_DUMP_BUFFER_SIZE, Attribute);
3145
3146 LxtLogInfo("RTATTR type: %2d len: %3d data: %s", Attribute->rta_type, Attribute->rta_len, AttributeDump);
3147
3148 if (Attribute->rta_type == IFLA_ADDRESS)
3149 {
3150 AttributeSeenAddress += 1;
3151 }
3152 else if (Attribute->rta_type == IFLA_MTU)
3153 {
3154 AttributeSeenMtu += 1;
3155 }
3156 else if (Attribute->rta_type == IFLA_IFNAME)
3157 {
3158 AttributeSeenName += 1;
3159 }
3160
3161 Attribute = RTA_NEXT(Attribute, RemainingLength);
3162 }
3163
3164 if ((Header->nlmsg_flags & NLM_F_MULTI) == 0)
3165 {
3166 goto LoopDone;
3167 }
3168
3169 Header = NLMSG_NEXT(Header, ReceiveResult);
3170 }
3171
3172 if (FoundDone == 1)
3173 {
3174 break;
3175 }
3176 }
3177
3178 LoopDone:
3179 LxtCheckTrue(AttributeSeenAddress > 0);
3180 LxtCheckTrue(AttributeSeenMtu > 0);
3181 LxtCheckTrue(AttributeSeenName > 0);
3182 LxtCheckEqual(SeenLoopback, 1, "%d");
3183 LxtLogInfo("Found %d interfaces total", InterfaceCount);
3184 if (OnlyOneInterface != FALSE)
3185 {
3186 LxtCheckEqual(InterfaceCount, 1, "%d");
3187 }
3188
3189 Result = LXT_RESULT_SUCCESS;
3190
3191 ErrorExit:
3192 return Result;
3193 }
3194
3195 int SocketNetlinkRouteGetRouteBestRoute(PLXT_ARGS Args)
3196
3197 /*++
3198
3199 Routine Description:
3200
3201 This routine tests the NETLINK_ROUTE protocol's RTM_GETROUTE message's
3202 get best route request.
3203
3204 Arguments:
3205
3206 Args - Supplies the command line arguments.
3207
3208 Return Value:
3209
3210 Returns 0 on success, -1 on failure.
3211
3212 --*/
3213
3214 {
3215
3216 socklen_t AddressLength;
3217 struct sockaddr_nl BindAddress;
3218 struct in_addr DestinationIpv4;
3219 struct in6_addr DestinationIpv6;
3220 struct in_addr GatewayIpv4;
3221 struct in6_addr GatewayIpv6;
3222 struct nlmsgerr* Error;
3223 struct nlmsghdr* Header;
3224 int Index;
3225 bool IsIpV6Configured;
3226 int LoopbackIndex;
3227 char ReceiveBuffer[5000];
3228 int ReceiveResult;
3229 int Result;
3230 int SendResult;
3231 int Socket;
3232
3233 struct
3234 {
3235 struct nlmsghdr nlh;
3236 struct rtmsg msg;
3237 char attr[200];
3238 } Request;
3239
3240 //
3241 // Get the interface index of the loopback adapter.
3242 //
3243
3244 LxtCheckErrnoZeroSuccess(SocketNetlinkGetLoopbackIndex(&LoopbackIndex));
3245 LxtCheckTrue(LoopbackIndex > 0);
3246
3247 //
3248 // Create and bind socket. Create a RTM_GETROUTE request.
3249 //
3250
3251 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
3252 memset(&BindAddress, 0, sizeof(BindAddress));
3253 BindAddress.nl_family = AF_NETLINK;
3254 AddressLength = sizeof(BindAddress);
3255 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
3256
3257 memset(&Request, 0, sizeof(Request));
3258 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3259 Request.nlh.nlmsg_type = RTM_GETROUTE;
3260 Request.nlh.nlmsg_seq = 0x4567;
3261
3262 //
3263 // NLM_F_REQUEST with no NLM_F_DUMP means "get best route" request.
3264 //
3265
3266 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
3267
3268 //
3269 // Test specifying an invalid address family.
3270 //
3271
3272 Request.msg.rtm_family = AF_UNSPEC;
3273 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3274 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
3275 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EOPNOTSUPP));
3276
3277 //
3278 // Test specifying AF_INET6 while really giving an IPv4 destination address.
3279 //
3280
3281 Request.msg.rtm_family = AF_INET6;
3282 inet_aton("1.1.1.1", &DestinationIpv4);
3283 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, NULL, -1);
3284
3285 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3286 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
3287 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EINVAL));
3288
3289 IsIpV6Configured = SocketNetlinkIsIpv6Configured();
3290
3291 //
3292 // Test not specifying the destination (both Ipv4 and Ipv6).
3293 //
3294
3295 memset(&Request, 0, sizeof(Request));
3296 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3297 Request.nlh.nlmsg_type = RTM_GETROUTE;
3298 Request.nlh.nlmsg_seq = 0x4567;
3299 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
3300 Request.msg.rtm_family = AF_INET;
3301 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3302 LxtCheckResult(SocketNetlinkRouteGetRouteBestRouteCheckResponse(Socket, FALSE));
3303 Request.msg.rtm_family = AF_INET6;
3304 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3305 if (IsIpV6Configured)
3306 {
3307 LxtCheckResult(SocketNetlinkRouteGetRouteBestRouteCheckResponse(Socket, FALSE));
3308 }
3309 else
3310 {
3311 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
3312
3313 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -ENETUNREACH));
3314 }
3315
3316 //
3317 // Test specifying the destination (Ipv4).
3318 //
3319
3320 inet_aton("1.1.1.1", &DestinationIpv4);
3321 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, NULL, -1);
3322
3323 Request.msg.rtm_family = AF_INET;
3324 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3325 LxtCheckResult(SocketNetlinkRouteGetRouteBestRouteCheckResponse(Socket, TRUE));
3326
3327 //
3328 // Test specifying the destination (Ipv6).
3329 //
3330 if (IsIpV6Configured)
3331 {
3332 memset(&Request, 0, sizeof(Request));
3333 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3334 Request.nlh.nlmsg_type = RTM_GETROUTE;
3335 Request.nlh.nlmsg_seq = 0x4567;
3336 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
3337 Request.msg.rtm_family = AF_INET6;
3338 inet_pton(AF_INET6, "12::", &GatewayIpv6);
3339 LxtCheckErrnoZeroSuccess(
3340 SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), RTA_DST, &DestinationIpv6, sizeof(DestinationIpv6)));
3341
3342 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3343 LxtCheckResult(SocketNetlinkRouteGetRouteBestRouteCheckResponse(Socket, TRUE));
3344 }
3345
3346 //
3347 // Test specifying the destination and gateway (Ipv4).
3348 //
3349
3350 memset(&Request, 0, sizeof(Request));
3351 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3352 Request.nlh.nlmsg_type = RTM_GETROUTE;
3353 Request.nlh.nlmsg_seq = 0x4567;
3354 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
3355 Request.msg.rtm_family = AF_INET;
3356 inet_aton("1.1.1.1", &DestinationIpv4);
3357 inet_aton("1.1.1.2", &GatewayIpv4);
3358 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, &GatewayIpv4, -1);
3359
3360 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3361 LxtCheckResult(SocketNetlinkRouteGetRouteBestRouteCheckResponse(Socket, TRUE));
3362
3363 //
3364 // Test specifying the destination and gateway (Ipv6).
3365 //
3366
3367 if (IsIpV6Configured)
3368 {
3369 memset(&Request, 0, sizeof(Request));
3370 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3371 Request.nlh.nlmsg_type = RTM_GETROUTE;
3372 Request.nlh.nlmsg_seq = 0x4567;
3373 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
3374 Request.msg.rtm_family = AF_INET6;
3375 inet_pton(AF_INET6, "12::", &DestinationIpv6);
3376 inet_pton(AF_INET6, "13::", &GatewayIpv6);
3377 LxtCheckErrnoZeroSuccess(
3378 SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), RTA_DST, &DestinationIpv6, sizeof(DestinationIpv6)));
3379
3380 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), RTA_GATEWAY, &GatewayIpv6, sizeof(GatewayIpv6)));
3381
3382 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3383 LxtCheckResult(SocketNetlinkRouteGetRouteBestRouteCheckResponse(Socket, TRUE));
3384 }
3385
3386 //
3387 // Test specifying the destination, gateway and interface index (Ipv4).
3388 //
3389
3390 memset(&Request, 0, sizeof(Request));
3391 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3392 Request.nlh.nlmsg_type = RTM_GETROUTE;
3393 Request.nlh.nlmsg_seq = 0x4567;
3394 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
3395 Request.msg.rtm_family = AF_INET;
3396 inet_aton("127.0.0.1", &DestinationIpv4);
3397 inet_aton("1.1.1.2", &GatewayIpv4);
3398 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, &GatewayIpv4, LoopbackIndex);
3399
3400 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3401 LxtCheckResult(SocketNetlinkRouteGetRouteBestRouteCheckResponse(Socket, FALSE));
3402
3403 //
3404 // Test specifying the destination, gateway and interface index (Ipv6).
3405 //
3406
3407 memset(&Request, 0, sizeof(Request));
3408 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3409 Request.nlh.nlmsg_type = RTM_GETROUTE;
3410 Request.nlh.nlmsg_seq = 0x4567;
3411 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
3412 Request.msg.rtm_family = AF_INET6;
3413 inet_pton(AF_INET6, "::1", &DestinationIpv6);
3414 inet_pton(AF_INET6, "13::", &GatewayIpv6);
3415 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), RTA_DST, &DestinationIpv6, sizeof(DestinationIpv6)));
3416
3417 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), RTA_GATEWAY, &GatewayIpv6, sizeof(GatewayIpv6)));
3418
3419 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), RTA_OIF, &LoopbackIndex, sizeof(LoopbackIndex)));
3420
3421 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3422 LxtCheckResult(SocketNetlinkRouteGetRouteBestRouteCheckResponse(Socket, FALSE));
3423
3424 ErrorExit:
3425 if (Socket > 0)
3426 {
3427 close(Socket);
3428 }
3429
3430 return Result;
3431 }
3432
3433 int SocketNetlinkRouteGetRouteBestRouteCheckResponse(int Socket, int CheckGateway)
3434
3435 /*++
3436
3437 Routine Description:
3438
3439 This routine tests the response to the NETLINK_ROUTE protocol's
3440 RTM_GETROUTE message's get best route request.
3441
3442 Arguments:
3443
3444 Socket - Supplies the socket to read the response from.
3445
3446 CheckGateway - Supplies a boolean indicating whether to check for the
3447 presence of the RTA_GATEWAY attribute.
3448
3449 Return Value:
3450
3451 Returns 0 on success, -1 on failure.
3452
3453 --*/
3454
3455 {
3456
3457 struct rtattr* Attribute;
3458 char AttributeDump[ATTRIBUTE_DUMP_BUFFER_SIZE];
3459 int AttributeSeenDst;
3460 int AttributeSeenGateway;
3461 int AttributeSeenOif;
3462 int FoundDone;
3463 struct nlmsghdr* Header;
3464 char ReceiveBuffer[5000];
3465 int ReceiveResult;
3466 int RemainingLength;
3467 int Result;
3468 struct rtmsg* RtMsg;
3469
3470 AttributeSeenDst = 0;
3471 AttributeSeenGateway = 0;
3472 AttributeSeenOif = 0;
3473 FoundDone = 0;
3474 LxtCheckErrno(ReceiveResult = recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, NULL, 0));
3475
3476 Header = (struct nlmsghdr*)ReceiveBuffer;
3477 RtMsg = (struct rtmsg*)NLMSG_DATA(Header);
3478 LxtLogInfo(
3479 "rtmsg: rtm_family %d rtm_dst_len %d rtm_src_len %d "
3480 "rtm_tos %d rtm_table %d rtm_protocol %d "
3481 "rtm_scope %d rtm_type %d rtm_flags %d",
3482 RtMsg->rtm_family,
3483 RtMsg->rtm_dst_len,
3484 RtMsg->rtm_src_len,
3485 RtMsg->rtm_tos,
3486 RtMsg->rtm_table,
3487 RtMsg->rtm_protocol,
3488 RtMsg->rtm_scope,
3489 RtMsg->rtm_type,
3490 RtMsg->rtm_flags);
3491
3492 Attribute = (struct rtattr*)((char*)RtMsg + sizeof(struct rtmsg));
3493 RemainingLength = Header->nlmsg_len - NLMSG_LENGTH(sizeof(struct rtmsg));
3494 while (RTA_OK(Attribute, RemainingLength))
3495 {
3496 SocketNetlinkRouteDumpAttributeData(AttributeDump, ATTRIBUTE_DUMP_BUFFER_SIZE, Attribute);
3497
3498 LxtLogInfo("RTATTR type: %2d len: %3d data: %s", Attribute->rta_type, Attribute->rta_len, AttributeDump);
3499
3500 if (Attribute->rta_type == RTA_DST)
3501 {
3502 AttributeSeenDst += 1;
3503 }
3504 else if (Attribute->rta_type == RTA_GATEWAY)
3505 {
3506 AttributeSeenGateway += 1;
3507 }
3508 else if (Attribute->rta_type == RTA_OIF)
3509 {
3510 AttributeSeenOif += 1;
3511 }
3512
3513 Attribute = RTA_NEXT(Attribute, RemainingLength);
3514 }
3515
3516 LxtCheckTrue(AttributeSeenDst > 0);
3517 if (CheckGateway != FALSE)
3518 {
3519 LxtCheckTrue(AttributeSeenGateway > 0);
3520 }
3521
3522 LxtCheckTrue(AttributeSeenOif > 0);
3523 Result = LXT_RESULT_SUCCESS;
3524
3525 ErrorExit:
3526 return Result;
3527 }
3528
3529 int SocketNetlinkRouteGetRouteDump(PLXT_ARGS Args)
3530
3531 /*++
3532
3533 Routine Description:
3534
3535 This routine tests the NETLINK_ROUTE protocol's RTM_GETROUTE message's
3536 dump request.
3537
3538 Arguments:
3539
3540 Args - Supplies the command line arguments.
3541
3542 Return Value:
3543
3544 Returns 0 on success, -1 on failure.
3545
3546 --*/
3547
3548 {
3549
3550 socklen_t AddressLength;
3551 struct rtattr* Attribute;
3552 char AttributeDump[ATTRIBUTE_DUMP_BUFFER_SIZE];
3553 int AttributeSeenDst;
3554 int AttributeSeenGateway;
3555 int AttributeSeenOif;
3556 int AttributeSeenPriority;
3557 struct sockaddr_nl BindAddress;
3558 struct nlmsgerr* Error;
3559 int FoundDone;
3560 struct nlmsghdr* Header;
3561 int Index;
3562 char ReceiveBuffer[5000];
3563 int ReceiveResult;
3564 int RemainingLength;
3565 int Result;
3566 struct rtmsg* RtMsg;
3567 int SendResult;
3568 int Socket;
3569
3570 struct
3571 {
3572 struct nlmsghdr nlh;
3573 struct rtmsg msg;
3574 } Request;
3575
3576 AttributeSeenDst = 0;
3577 AttributeSeenGateway = 0;
3578 AttributeSeenOif = 0;
3579 AttributeSeenPriority = 0;
3580
3581 //
3582 // Create and bind socket. Create a RTM_GETROUTE request.
3583 //
3584
3585 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
3586 memset(&BindAddress, 0, sizeof(BindAddress));
3587 BindAddress.nl_family = AF_NETLINK;
3588 AddressLength = sizeof(BindAddress);
3589 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
3590
3591 memset(&Request, 0, sizeof(Request));
3592 Request.nlh.nlmsg_len = sizeof(Request);
3593 Request.nlh.nlmsg_type = RTM_GETROUTE;
3594 Request.nlh.nlmsg_seq = 0x4567;
3595 Request.msg.rtm_family = AF_UNSPEC;
3596
3597 //
3598 // Test flags. Only passing the NLM_F_ROOT and/or NLM_F_MATCH flag(s)
3599 // result in no response.
3600 //
3601
3602 Request.nlh.nlmsg_flags = NLM_F_ROOT;
3603 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3604 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
3605
3606 Request.nlh.nlmsg_flags = NLM_F_MATCH;
3607 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3608 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
3609
3610 Request.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH;
3611 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3612 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
3613
3614 //
3615 // Test flags. Passing 0 flags or invalid flags result in no response.
3616 //
3617
3618 Request.nlh.nlmsg_flags = 0;
3619 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3620 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
3621
3622 Request.nlh.nlmsg_flags = 0x40;
3623 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3624 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
3625
3626 //
3627 // Test flags. NLM_F_REQUEST and at least one of NLM_F_ROOT/NLM_F_MATCH
3628 // results in the correct response.
3629 // For the response, verify that at least one interface is present (loopback),
3630 // and also verify the presence of several attributes.
3631 //
3632
3633 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
3634 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
3635 FoundDone = 0;
3636 for (;;)
3637 {
3638 LxtCheckErrno(ReceiveResult = recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, NULL, 0));
3639
3640 Header = (struct nlmsghdr*)ReceiveBuffer;
3641 while (NLMSG_OK(Header, ReceiveResult))
3642 {
3643 if (Header->nlmsg_type == NLMSG_DONE)
3644 {
3645 FoundDone = 1;
3646 break;
3647 }
3648
3649 RtMsg = (struct rtmsg*)NLMSG_DATA(Header);
3650 LxtLogInfo(
3651 "rtmsg: rtm_family %d rtm_dst_len %d rtm_src_len %d "
3652 "rtm_tos %d rtm_table %d rtm_protocol %d "
3653 "rtm_scope %d rtm_type %d rtm_flags %d",
3654 RtMsg->rtm_family,
3655 RtMsg->rtm_dst_len,
3656 RtMsg->rtm_src_len,
3657 RtMsg->rtm_tos,
3658 RtMsg->rtm_table,
3659 RtMsg->rtm_protocol,
3660 RtMsg->rtm_scope,
3661 RtMsg->rtm_type,
3662 RtMsg->rtm_flags);
3663
3664 Attribute = (struct rtattr*)((char*)RtMsg + sizeof(struct rtmsg));
3665
3666 RemainingLength = Header->nlmsg_len - NLMSG_LENGTH(sizeof(struct rtmsg));
3667
3668 while (RTA_OK(Attribute, RemainingLength))
3669 {
3670 SocketNetlinkRouteDumpAttributeData(AttributeDump, ATTRIBUTE_DUMP_BUFFER_SIZE, Attribute);
3671
3672 LxtLogInfo("RTATTR type: %2d len: %3d data: %s", Attribute->rta_type, Attribute->rta_len, AttributeDump);
3673
3674 if (Attribute->rta_type == RTA_DST)
3675 {
3676 AttributeSeenDst += 1;
3677 }
3678 else if (Attribute->rta_type == RTA_GATEWAY)
3679 {
3680 AttributeSeenGateway += 1;
3681 }
3682 else if (Attribute->rta_type == RTA_OIF)
3683 {
3684 AttributeSeenOif += 1;
3685 }
3686 else if (Attribute->rta_type == RTA_PRIORITY)
3687 {
3688 AttributeSeenPriority += 1;
3689 }
3690
3691 Attribute = RTA_NEXT(Attribute, RemainingLength);
3692 }
3693
3694 Header = NLMSG_NEXT(Header, ReceiveResult);
3695 }
3696
3697 if (FoundDone == 1)
3698 {
3699 break;
3700 }
3701 }
3702
3703 LxtCheckTrue(AttributeSeenDst > 0);
3704 LxtCheckTrue(AttributeSeenGateway > 0);
3705 LxtCheckTrue(AttributeSeenOif > 0);
3706 LxtCheckTrue(AttributeSeenPriority > 0);
3707
3708 //
3709 // Check that sending is still successful even if the
3710 // receive buffer has overflown.
3711 //
3712
3713 for (Index = 0; Index < 1000; Index++)
3714 {
3715 LxtCheckErrno(SendResult = send(Socket, &Request, sizeof(Request), 0));
3716 LxtCheckEqual(SendResult, sizeof(Request), "%d");
3717 }
3718
3719 ErrorExit:
3720 if (Socket > 0)
3721 {
3722 close(Socket);
3723 }
3724
3725 return Result;
3726 }
3727
3728 int SocketNetlinkGetLoopbackIndex(int* LoopbackIndex)
3729
3730 /*++
3731
3732 Routine Description:
3733
3734 This routine obtains the interface index of the loopback adapter.
3735
3736 Arguments:
3737
3738 LoopbackIndex - Supplies a pointer to an integer that receives the
3739 interface index of the loopback adapter.
3740
3741 Return Value:
3742
3743 Returns 0 on success, -1 on failure.
3744
3745 --*/
3746
3747 {
3748
3749 struct ifreq InterfaceRequest;
3750 int Result;
3751 int Socket;
3752
3753 LxtCheckErrno(Socket = socket(AF_INET, SOCK_STREAM, 0));
3754 memset(&InterfaceRequest, 0, sizeof(InterfaceRequest));
3755 strncpy(InterfaceRequest.ifr_name, SOCKET_LOOPBACK_IF_NAME, sizeof(InterfaceRequest.ifr_name) - 1);
3756
3757 LxtCheckErrnoZeroSuccess(ioctl(Socket, SIOCGIFINDEX, &InterfaceRequest));
3758 *LoopbackIndex = InterfaceRequest.ifr_ifindex;
3759
3760 ErrorExit:
3761 if (Socket > 0)
3762 {
3763 close(Socket);
3764 }
3765
3766 return Result;
3767 }
3768
3769 int SocketNetlinkCheckResponseError(void* ReceiveBuffer, int ReceiveResult, int Error)
3770
3771 /*++
3772
3773 Routine Description:
3774
3775 This routine checks the Netlink error message response.
3776
3777 Arguments:
3778
3779 ReceiveBuffer - Supplies a pointer to the error message.
3780
3781 ReceiveResult - Supplies the total size of the error message.
3782
3783 Error - Supplies the error number to check for in the error message.
3784
3785 Return Value:
3786
3787 Returns 0 on success, -1 on failure.
3788
3789 --*/
3790
3791 {
3792
3793 struct nlmsgerr* ErrorMessage;
3794 struct nlmsghdr* ReceiveHeader;
3795 int Result;
3796
3797 ReceiveHeader = (struct nlmsghdr*)ReceiveBuffer;
3798 LxtCheckTrue(NLMSG_OK(ReceiveHeader, ReceiveResult));
3799 LxtCheckEqual(ReceiveHeader->nlmsg_type, NLMSG_ERROR, "%d");
3800 ErrorMessage = (struct nlmsgerr*)NLMSG_DATA(ReceiveHeader);
3801 LxtCheckEqual(ErrorMessage->error, Error, "%d");
3802 Result = 0;
3803
3804 ErrorExit:
3805 return Result;
3806 }
3807
3808 int SocketNetlinkRouteAddAttribute(struct nlmsghdr* Msghdr, int MessageSize, int AttributeType, void* AttributeData, int AttributeSize)
3809
3810 /*++
3811
3812 Routine Description:
3813
3814 This routine adds a RT attribute to the Netlink message.
3815
3816 Arguments:
3817
3818 Msghdr - Supplies the message header.
3819
3820 MessageSize - Supplies the total possible size of the message.
3821
3822 AttributeType - Supplies the RT attribute type.
3823
3824 AttributeData - Supplies the RT attribute data.
3825
3826 AttributeSize - Supplies the RT attribute size.
3827
3828 Return Value:
3829
3830 Returns 0 on success, -1 on failure.
3831
3832 --*/
3833
3834 {
3835
3836 int Length;
3837 struct rtattr* Attribute;
3838
3839 Length = RTA_LENGTH(AttributeSize);
3840 if (NLMSG_ALIGN(Msghdr->nlmsg_len) + RTA_ALIGN(Length) > MessageSize)
3841 {
3842 LxtLogError("Adding RT attribute, message size overflowed: %d %d %d", Msghdr->nlmsg_len, Length, MessageSize);
3843
3844 return -1;
3845 }
3846
3847 Attribute = NLMSG_TAIL(Msghdr);
3848 Attribute->rta_type = AttributeType;
3849 Attribute->rta_len = Length;
3850 memcpy(RTA_DATA(Attribute), AttributeData, AttributeSize);
3851 Msghdr->nlmsg_len = NLMSG_ALIGN(Msghdr->nlmsg_len) + RTA_ALIGN(Length);
3852 return 0;
3853 }
3854
3855 void SocketNetlinkRouteAddAddressAttributes(struct nlmsghdr* Msghdr, int MessageSize, struct in_addr* AddressIpv4)
3856
3857 /*++
3858
3859 Routine Description:
3860
3861 This routine appends the RTM_*ADDR message RT attributes to the message.
3862
3863 Arguments:
3864
3865 Msghdr - Supplies the message header.
3866
3867 MessageSize - Supplies the total possible size of the message.
3868
3869 AddressIpv4 - Supplies a pointer to the IPv4 address RT attribute.
3870
3871 Return Value:
3872
3873 None.
3874
3875 --*/
3876
3877 {
3878
3879 int Result;
3880
3881 if (AddressIpv4 != NULL)
3882 {
3883 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(Msghdr, MessageSize, IFA_ADDRESS, AddressIpv4, sizeof(*AddressIpv4)));
3884
3885 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(Msghdr, MessageSize, IFA_LOCAL, AddressIpv4, sizeof(*AddressIpv4)));
3886 }
3887
3888 ErrorExit:
3889 return;
3890 }
3891
3892 void SocketNetlinkRouteAddRouteAttributes(struct nlmsghdr* Msghdr, int MessageSize, struct in_addr* DestinationIpv4, struct in_addr* GatewayIpv4, int InterfaceIndex)
3893
3894 /*++
3895
3896 Routine Description:
3897
3898 This routine appends the RTM_*ROUTE message RT attributes to the message.
3899
3900 Arguments:
3901
3902 Msghdr - Supplies the message header.
3903
3904 MessageSize - Supplies the total possible size of the message.
3905
3906 DestinationIpv4 - Supplies a pointer to the destination IPv4 address RT attribute.
3907
3908 GatewayIpv4 - Supplies a pointer to the gateway IPv4 address RT attribute.
3909
3910 InterfaceIndex - Supplies the interface index RT attribute.
3911
3912 Return Value:
3913
3914 None.
3915
3916 --*/
3917
3918 {
3919
3920 int Result;
3921
3922 if (DestinationIpv4 != NULL)
3923 {
3924 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(Msghdr, MessageSize, RTA_DST, DestinationIpv4, sizeof(*DestinationIpv4)));
3925 }
3926
3927 if (GatewayIpv4 != NULL)
3928 {
3929 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(Msghdr, MessageSize, RTA_GATEWAY, GatewayIpv4, sizeof(*GatewayIpv4)));
3930 }
3931
3932 if (InterfaceIndex > 0)
3933 {
3934 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(Msghdr, MessageSize, RTA_OIF, &InterfaceIndex, sizeof(InterfaceIndex)));
3935 }
3936
3937 ErrorExit:
3938 return;
3939 }
3940
3941 int SocketNetlinkRouteNewDelAddress(PLXT_ARGS Args)
3942
3943 /*++
3944
3945 Routine Description:
3946
3947 This routine tests the NETLINK_ROUTE protocol's
3948 RTM_NEWADDR and RTM_DELADDR messages.
3949
3950 Arguments:
3951
3952 Args - Supplies the command line arguments.
3953
3954 Return Value:
3955
3956 Returns 0 on success, -1 on failure.
3957
3958 --*/
3959
3960 {
3961
3962 struct in_addr AddressIpv4;
3963 struct in6_addr AddressIpv6;
3964 socklen_t AddressLength;
3965 struct sockaddr_nl BindAddress;
3966 struct nlmsgerr* Error;
3967 struct in_addr GatewayIpv4;
3968 struct in6_addr GatewayIpv6;
3969 int LoopbackIndex;
3970 char ReceiveBuffer[5000];
3971 struct nlmsghdr* ReceiveHeader;
3972 int ReceiveResult;
3973 struct
3974 {
3975 struct nlmsghdr nlh;
3976 struct ifaddrmsg msg;
3977 char attr[200];
3978 } Request;
3979 int Result;
3980 int Retries;
3981 int Socket;
3982
3983 //
3984 // Create and bind socket. Create a RTM_GETROUTE request.
3985 //
3986
3987 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
3988 memset(&BindAddress, 0, sizeof(BindAddress));
3989 BindAddress.nl_family = AF_NETLINK;
3990 AddressLength = sizeof(BindAddress);
3991 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
3992
3993 memset(&Request, 0, sizeof(Request));
3994 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
3995 Request.nlh.nlmsg_type = RTM_NEWADDR;
3996 Request.nlh.nlmsg_seq = 0x4567;
3997 Request.msg.ifa_family = AF_UNSPEC;
3998
3999 //
4000 // Get the interface index of the loopback adapter. All the tests
4001 // below operate on the loopback adapter.
4002 //
4003
4004 LxtCheckErrnoZeroSuccess(SocketNetlinkGetLoopbackIndex(&LoopbackIndex));
4005 LxtCheckTrue(LoopbackIndex > 0);
4006
4007 //
4008 // Test flags. Passing in (invalid) flags for RTM_GET* results in no response.
4009 //
4010
4011 Request.nlh.nlmsg_flags = NLM_F_ROOT;
4012 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4013 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4014
4015 Request.nlh.nlmsg_flags = NLM_F_MATCH;
4016 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4017 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4018
4019 Request.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH;
4020 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4021 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4022
4023 //
4024 // Test invalid flags with NLM_F_ACK.
4025 //
4026
4027 Request.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_ACK;
4028 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4029 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4030 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4031
4032 //
4033 // Test flags. Passing 0 flags or invalid flags result in no response.
4034 //
4035
4036 Request.nlh.nlmsg_flags = 0;
4037 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4038 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4039
4040 Request.nlh.nlmsg_flags = 0x40;
4041 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4042 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4043
4044 //
4045 // Add an ip address 2.1.1.1/30.
4046 //
4047
4048 memset(&Request, 0, sizeof(Request));
4049 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
4050 Request.nlh.nlmsg_type = RTM_NEWADDR;
4051 Request.nlh.nlmsg_seq = 0x4567;
4052 Request.msg.ifa_prefixlen = 30;
4053 Request.msg.ifa_index = LoopbackIndex;
4054 inet_aton("2.1.1.1", &AddressIpv4);
4055
4056 //
4057 // Test specifying an invalid address family.
4058 //
4059
4060 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
4061 Request.msg.ifa_family = AF_UNSPEC;
4062 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4063 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4064 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EOPNOTSUPP));
4065
4066 //
4067 // Test not specifying the ip address, which should fail.
4068 //
4069
4070 Request.msg.ifa_family = AF_INET;
4071 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_EXCL | NLM_F_ACK;
4072 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4073 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4074 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EINVAL));
4075
4076 //
4077 // Basically any flag allows you to create.
4078 // Windows can take up to 10 seconds before sending the WNF notification that lxcore
4079 // uses to update its internal network interface and address cache. Before the cache
4080 // is updated, this create operation will fail, so wait for 20 seconds for the
4081 // operation to succeed.
4082 //
4083
4084 SocketNetlinkRouteAddAddressAttributes(&Request.nlh, sizeof(Request), &AddressIpv4);
4085
4086 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_EXCL | NLM_F_ACK;
4087 LxtCheckResult(SocketNetlinkSendAndWaitForExpectedError(Socket, &Request, sizeof(Request), 0));
4088
4089 //
4090 // Test NLM_F_REPLACE, which should succeed.
4091 // Windows can take up to 10 seconds before sending the WNF notification that lxcore
4092 // uses to update its internal network interface and address cache. Before the cache
4093 // is updated, this replace operation will fail, so wait for 20 seconds for the
4094 // operation to succeed.
4095 //
4096
4097 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_ACK;
4098 LxtCheckResult(SocketNetlinkSendAndWaitForExpectedError(Socket, &Request, sizeof(Request), 0));
4099
4100 //
4101 // Test NLM_F_EXCL, which should fail since it prevents existing addresses
4102 // from being changed.
4103 //
4104
4105 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_EXCL | NLM_F_ACK;
4106 LxtCheckResult(SocketNetlinkSendAndWaitForExpectedError(Socket, &Request, sizeof(Request), -EEXIST));
4107
4108 //
4109 // Even if NLM_F_REPLACE is added to NLM_F_EXCL, it still fails.
4110 //
4111
4112 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_EXCL | NLM_F_ACK;
4113 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4114 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4115 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EEXIST));
4116
4117 //
4118 // NLM_F_CREATE without NLM_F_REPLACE fails.
4119 //
4120
4121 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
4122 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4123 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4124 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EEXIST));
4125
4126 //
4127 // NLM_F_CREATE with NLM_F_REPLACE succeeds.
4128 //
4129
4130 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE | NLM_F_ACK;
4131 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4132 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4133 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4134
4135 //
4136 // Test giving an invalid interface index, which should fail.
4137 //
4138
4139 Request.msg.ifa_index = 90000;
4140 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_ACK;
4141 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4142 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4143 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -ENODEV));
4144
4145 //
4146 // Add an ip address 2.1.1.2/32.
4147 //
4148
4149 memset(&Request, 0, sizeof(Request));
4150 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
4151 Request.nlh.nlmsg_type = RTM_NEWADDR;
4152 Request.nlh.nlmsg_seq = 0x4567;
4153 Request.msg.ifa_family = AF_INET;
4154 Request.msg.ifa_prefixlen = 32;
4155 Request.msg.ifa_index = LoopbackIndex;
4156 inet_aton("2.1.1.2", &AddressIpv4);
4157 SocketNetlinkRouteAddAddressAttributes(&Request.nlh, sizeof(Request), &AddressIpv4);
4158
4159 //
4160 // Only setting the NLM_F_REQUEST flag allows creating a new ip address.
4161 //
4162
4163 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
4164 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4165 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4166 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4167
4168 //
4169 // Add an ip address 11::/31.
4170 //
4171
4172 memset(&Request, 0, sizeof(Request));
4173 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
4174 Request.nlh.nlmsg_type = RTM_NEWADDR;
4175 Request.nlh.nlmsg_seq = 0x4567;
4176 Request.msg.ifa_family = AF_INET6;
4177 Request.msg.ifa_prefixlen = 31;
4178 Request.msg.ifa_index = LoopbackIndex;
4179 inet_pton(AF_INET6, "11::", &AddressIpv6);
4180 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), IFA_ADDRESS, &AddressIpv6, sizeof(AddressIpv6)));
4181
4182 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), IFA_LOCAL, &AddressIpv6, sizeof(AddressIpv6)));
4183
4184 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
4185 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4186 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4187 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4188
4189 //
4190 // Delete 2.1.1.1/30.
4191 //
4192
4193 usleep(1000 * 40);
4194 memset(&Request, 0, sizeof(Request));
4195 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
4196 Request.nlh.nlmsg_type = RTM_DELADDR;
4197 Request.nlh.nlmsg_seq = 0x4567;
4198 Request.msg.ifa_family = AF_INET;
4199 Request.msg.ifa_prefixlen = 30;
4200 Request.msg.ifa_index = LoopbackIndex;
4201 inet_aton("2.1.1.1", &AddressIpv4);
4202 SocketNetlinkRouteAddAddressAttributes(&Request.nlh, sizeof(Request), &AddressIpv4);
4203
4204 //
4205 // Passing 0 flags results in no response.
4206 //
4207
4208 Request.nlh.nlmsg_flags = 0;
4209 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4210 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4211
4212 //
4213 // Need at least NLM_F_REQUEST.
4214 //
4215
4216 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
4217 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4218 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4219 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4220
4221 //
4222 // Try deleting again, which should fail.
4223 //
4224
4225 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4226 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4227 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EADDRNOTAVAIL));
4228
4229 //
4230 // Delete 2.1.1.2/32.
4231 //
4232
4233 memset(&Request, 0, sizeof(Request));
4234 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
4235 Request.nlh.nlmsg_type = RTM_DELADDR;
4236 Request.nlh.nlmsg_seq = 0x4567;
4237 Request.msg.ifa_family = AF_INET;
4238 Request.msg.ifa_prefixlen = 32;
4239 Request.msg.ifa_index = LoopbackIndex;
4240 inet_aton("2.1.1.2", &AddressIpv4);
4241 SocketNetlinkRouteAddAddressAttributes(&Request.nlh, sizeof(Request), &AddressIpv4);
4242
4243 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_EXCL | NLM_F_ACK;
4244 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4245 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4246 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4247
4248 //
4249 // Test giving an invalid interface index, which should fail.
4250 //
4251
4252 Request.msg.ifa_index = 90000;
4253 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4254 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4255 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -ENODEV));
4256
4257 //
4258 // Delete ip address 11::/31.
4259 //
4260
4261 memset(&Request, 0, sizeof(Request));
4262 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
4263 Request.nlh.nlmsg_type = RTM_DELADDR;
4264 Request.nlh.nlmsg_seq = 0x4567;
4265 Request.msg.ifa_family = AF_INET6;
4266 Request.msg.ifa_prefixlen = 31;
4267 Request.msg.ifa_index = LoopbackIndex;
4268 inet_pton(AF_INET6, "11::", &AddressIpv6);
4269
4270 //
4271 // Test not specifying the ip address, which should fail.
4272 //
4273
4274 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
4275 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4276 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4277 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EINVAL));
4278
4279 //
4280 // Now, this should succeed.
4281 //
4282
4283 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), IFA_ADDRESS, &AddressIpv6, sizeof(AddressIpv6)));
4284
4285 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), IFA_LOCAL, &AddressIpv6, sizeof(AddressIpv6)));
4286
4287 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
4288 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4289 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4290 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4291
4292 ErrorExit:
4293 if (Socket > 0)
4294 {
4295 close(Socket);
4296 }
4297
4298 return Result;
4299 }
4300
4301 int SocketNetlinkRouteNewDelRoute(PLXT_ARGS Args)
4302
4303 /*++
4304
4305 Routine Description:
4306
4307 This routine tests the NETLINK_ROUTE protocol's
4308 RTM_NEWROUTE and RTM_DELROUTE messages.
4309
4310 Arguments:
4311
4312 Args - Supplies the command line arguments.
4313
4314 Return Value:
4315
4316 Returns 0 on success, -1 on failure.
4317
4318 --*/
4319
4320 {
4321
4322 socklen_t AddressLength;
4323 struct sockaddr_nl BindAddress;
4324 struct in_addr DestinationIpv4;
4325 struct in6_addr DestinationIpv6;
4326 struct in_addr GatewayIpv4;
4327 struct in6_addr GatewayIpv6;
4328 int LoopbackIndex;
4329 char ReceiveBuffer[5000];
4330 int ReceiveResult;
4331 struct
4332 {
4333 struct nlmsghdr nlh;
4334 struct rtmsg msg;
4335 char attr[200];
4336 } Request;
4337 int Result;
4338 int Socket;
4339
4340 //
4341 // Create and bind socket. Create a RTM_GETROUTE request.
4342 //
4343
4344 LxtCheckErrno(Socket = socket(AF_NETLINK, SOCK_RAW, 0));
4345 memset(&BindAddress, 0, sizeof(BindAddress));
4346 BindAddress.nl_family = AF_NETLINK;
4347 AddressLength = sizeof(BindAddress);
4348 LxtCheckErrno(bind(Socket, (struct sockaddr*)&BindAddress, AddressLength));
4349
4350 memset(&Request, 0, sizeof(Request));
4351 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4352 Request.nlh.nlmsg_type = RTM_NEWROUTE;
4353 Request.nlh.nlmsg_seq = 0x4567;
4354 Request.msg.rtm_family = AF_UNSPEC;
4355
4356 //
4357 // Get the interface index of the loopback adapter. All the tests
4358 // below operate on the loopback adapter.
4359 //
4360
4361 LxtCheckErrnoZeroSuccess(SocketNetlinkGetLoopbackIndex(&LoopbackIndex));
4362 LxtCheckTrue(LoopbackIndex > 0);
4363
4364 //
4365 // Test flags. Passing in (invalid) flags for RTM_GET* results in no response.
4366 //
4367
4368 Request.nlh.nlmsg_flags = NLM_F_ROOT;
4369 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4370 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4371
4372 Request.nlh.nlmsg_flags = NLM_F_MATCH;
4373 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4374 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4375
4376 Request.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH;
4377 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4378 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4379
4380 //
4381 // Test invalid flags with NLM_F_ACK.
4382 //
4383
4384 Request.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_ACK;
4385 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4386 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4387 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4388
4389 //
4390 // Test flags. Passing 0 flags or invalid flags result in no response.
4391 //
4392
4393 Request.nlh.nlmsg_flags = 0;
4394 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4395 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4396
4397 Request.nlh.nlmsg_flags = 0x40;
4398 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4399 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4400
4401 //
4402 // Add a routing entry to lo with destination 1.1.1.1 and on-link gateway.
4403 //
4404
4405 memset(&Request, 0, sizeof(Request));
4406 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4407 Request.nlh.nlmsg_type = RTM_NEWROUTE;
4408 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
4409 Request.nlh.nlmsg_seq = 0x4567;
4410 Request.msg.rtm_dst_len = 32;
4411 Request.msg.rtm_table = RT_TABLE_MAIN;
4412 Request.msg.rtm_protocol = RTPROT_BOOT;
4413 Request.msg.rtm_scope = RT_SCOPE_LINK;
4414 Request.msg.rtm_type = RTN_UNICAST;
4415 inet_aton("1.1.1.1", &DestinationIpv4);
4416 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, NULL, -1);
4417
4418 //
4419 // Test specifying an invalid address family.
4420 //
4421
4422 Request.msg.rtm_family = AF_UNSPEC;
4423 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4424 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4425 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EOPNOTSUPP));
4426
4427 //
4428 // Only send the request with the destination and no interface index.
4429 // The request should fail with ENODEV, because no interface index was specified.
4430 //
4431
4432 Request.msg.rtm_family = AF_INET;
4433 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4434 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4435 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -ENODEV));
4436
4437 //
4438 // Send the request with only NLM_F_REQUEST. The request should fail with ENOENT,
4439 // because destination 1.1.1.1 does not exist and NLM_F_CREATE was not specified.
4440 //
4441
4442 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
4443 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), RTA_OIF, &LoopbackIndex, sizeof(LoopbackIndex)));
4444
4445 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4446 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4447 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -ENOENT));
4448
4449 //
4450 // Now add the NLM_F_REPLACE flag, and the request should still fail.
4451 //
4452
4453 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE;
4454 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4455 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4456 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -ENOENT));
4457
4458 //
4459 // Now add the NLM_F_CREATE flag, and the request should succeed.
4460 // Since the NLM_F_ACK flag was not specified, there should be no response,
4461 // even though the operation succeeded.
4462 //
4463
4464 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
4465 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4466 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4467
4468 //
4469 // Sending again gets an error message EEXIST.
4470 //
4471 // N.B. The sleep is to wait for the lxcore internal cache to be updated
4472 // with the latest routing info from NETIO.
4473 //
4474
4475 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
4476 LxtCheckResult(SocketNetlinkSendAndWaitForExpectedError(Socket, &Request, sizeof(Request), -EEXIST));
4477
4478 //
4479 // Sending again with only NLM_F_REQUEST still gets an error message EEXIST.
4480 //
4481
4482 Request.nlh.nlmsg_flags = NLM_F_REQUEST;
4483 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4484 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4485 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EEXIST));
4486
4487 //
4488 // Sending again with NLM_F_REQUEST and NLM_F_EXCL still gets an error message EEXIST.
4489 //
4490
4491 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_EXCL;
4492 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4493 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4494 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EEXIST));
4495
4496 //
4497 // Sending again after adding NLM_F_REPLACE still gets an error message EEXIST.
4498 //
4499
4500 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_EXCL | NLM_F_REPLACE;
4501 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4502 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4503 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EEXIST));
4504
4505 //
4506 // Sending again with NLM_F_REPLACE is successful.
4507 //
4508
4509 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_APPEND | NLM_F_ACK;
4510 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4511 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4512 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4513
4514 //
4515 // Add a routing entry to lo with destination 1.1.1.2 and on-link gateway.
4516 // Send the request with various flags. The request should succeed.
4517 //
4518
4519 usleep(1000 * 60);
4520 memset(&Request, 0, sizeof(Request));
4521 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4522 Request.nlh.nlmsg_type = RTM_NEWROUTE;
4523 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE | NLM_F_EXCL;
4524 Request.nlh.nlmsg_seq = 0x4567;
4525 Request.msg.rtm_family = AF_INET;
4526 Request.msg.rtm_dst_len = 32;
4527 Request.msg.rtm_table = RT_TABLE_MAIN;
4528 Request.msg.rtm_protocol = RTPROT_BOOT;
4529 Request.msg.rtm_scope = RT_SCOPE_LINK;
4530 Request.msg.rtm_type = RTN_UNICAST;
4531 inet_aton("1.1.1.2", &DestinationIpv4);
4532 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, NULL, LoopbackIndex);
4533
4534 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4535 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4536
4537 //
4538 // Sending again gets an error message EEXIST.
4539 //
4540
4541 usleep(1000 * 60);
4542 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;
4543 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4544 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4545 LxtCheckEqual(ReceiveResult, Request.nlh.nlmsg_len + NLMSG_LENGTH(sizeof(int)), "%d");
4546 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EEXIST));
4547
4548 //
4549 // Sending again with the following flags still gets an error message EEXIST.
4550 //
4551
4552 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_EXCL | NLM_F_ACK;
4553 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4554 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4555 LxtCheckEqual(ReceiveResult, Request.nlh.nlmsg_len + NLMSG_LENGTH(sizeof(int)), "%d");
4556 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EEXIST));
4557
4558 //
4559 // Use NLM_F_REPLACE to change the gateway from on-link to 1.1.1.1.
4560 // Note that including the NLM_F_EXCL flag fails the operation.
4561 //
4562
4563 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE | NLM_F_EXCL;
4564 inet_aton("1.1.1.1", &GatewayIpv4);
4565 Request.msg.rtm_scope = RT_SCOPE_UNIVERSE;
4566 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), RTA_GATEWAY, &GatewayIpv4, sizeof(GatewayIpv4)));
4567
4568 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4569 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4570 LxtCheckEqual(ReceiveResult, Request.nlh.nlmsg_len + NLMSG_LENGTH(sizeof(int)), "%d");
4571 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -EEXIST));
4572
4573 //
4574 // Now remove the NLM_F_EXCL flag, and the operation should succeed.
4575 //
4576
4577 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE | NLM_F_ACK;
4578 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4579 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4580 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4581
4582 //
4583 // Add a routing entry to lo with destination 1.1.1.3 and gateway 1.1.1.1.
4584 // Send the request with various flags. The request should succeed.
4585 //
4586
4587 usleep(1000 * 60);
4588 memset(&Request, 0, sizeof(Request));
4589 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4590 Request.nlh.nlmsg_type = RTM_NEWROUTE;
4591 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE;
4592 Request.nlh.nlmsg_seq = 0x4567;
4593 Request.msg.rtm_family = AF_INET;
4594 Request.msg.rtm_dst_len = 32;
4595 Request.msg.rtm_table = RT_TABLE_MAIN;
4596 Request.msg.rtm_protocol = RTPROT_BOOT;
4597 Request.msg.rtm_scope = RT_SCOPE_UNIVERSE;
4598 Request.msg.rtm_type = RTN_UNICAST;
4599 inet_aton("1.1.1.3", &DestinationIpv4);
4600 inet_aton("1.1.1.1", &GatewayIpv4);
4601 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, &GatewayIpv4, LoopbackIndex);
4602
4603 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4604 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4605
4606 //
4607 // Change the gateway from 1.1.1.1 to on-link.
4608 // Note that invalid flags are silently dropped.
4609 //
4610
4611 usleep(1000 * 60);
4612 memset(&Request, 0, sizeof(Request));
4613 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4614 Request.nlh.nlmsg_type = RTM_NEWROUTE;
4615 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | 0xF800;
4616 Request.nlh.nlmsg_seq = 0x4567;
4617 Request.msg.rtm_family = AF_INET;
4618 Request.msg.rtm_dst_len = 32;
4619 Request.msg.rtm_table = RT_TABLE_MAIN;
4620 Request.msg.rtm_protocol = RTPROT_BOOT;
4621 Request.msg.rtm_scope = RT_SCOPE_LINK;
4622 Request.msg.rtm_type = RTN_UNICAST;
4623 inet_aton("1.1.1.3", &DestinationIpv4);
4624 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, NULL, LoopbackIndex);
4625
4626 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4627 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4628
4629 //
4630 // Add two more routing entries: destination 1.1.2 and 1.3,
4631 // with 1.1.1.1 as their gateway.
4632 //
4633
4634 usleep(1000 * 60);
4635 memset(&Request, 0, sizeof(Request));
4636 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4637 Request.nlh.nlmsg_type = RTM_NEWROUTE;
4638 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE | NLM_F_ACK;
4639 Request.nlh.nlmsg_seq = 0x4567;
4640 Request.msg.rtm_family = AF_INET;
4641 Request.msg.rtm_dst_len = 32;
4642 Request.msg.rtm_table = RT_TABLE_MAIN;
4643 Request.msg.rtm_protocol = RTPROT_BOOT;
4644 Request.msg.rtm_scope = RT_SCOPE_UNIVERSE;
4645 Request.msg.rtm_type = RTN_UNICAST;
4646 inet_aton("1.1.2", &DestinationIpv4);
4647 inet_aton("1.1.1.1", &GatewayIpv4);
4648 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, &GatewayIpv4, LoopbackIndex);
4649
4650 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4651 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4652 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4653
4654 usleep(1000 * 60);
4655 memset(&Request, 0, sizeof(Request));
4656 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4657 Request.nlh.nlmsg_type = RTM_NEWROUTE;
4658 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE;
4659 Request.nlh.nlmsg_seq = 0x4567;
4660 Request.msg.rtm_family = AF_INET;
4661 Request.msg.rtm_dst_len = 32;
4662 Request.msg.rtm_table = RT_TABLE_MAIN;
4663 Request.msg.rtm_protocol = RTPROT_BOOT;
4664 Request.msg.rtm_scope = RT_SCOPE_UNIVERSE;
4665 Request.msg.rtm_type = RTN_UNICAST;
4666 inet_aton("1.3", &DestinationIpv4);
4667 inet_aton("1.1.1.1", &GatewayIpv4);
4668 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, &GatewayIpv4, LoopbackIndex);
4669
4670 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4671 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4672
4673 //
4674 // Add three more routing entries: destination 1.1.1.0,
4675 // with 1.1.1.1 as their gateway, and prefix lengths 30, 31 and 32.
4676 //
4677
4678 usleep(1000 * 60);
4679 memset(&Request, 0, sizeof(Request));
4680 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4681 Request.nlh.nlmsg_type = RTM_NEWROUTE;
4682 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE;
4683 Request.nlh.nlmsg_seq = 0x4567;
4684 Request.msg.rtm_family = AF_INET;
4685 Request.msg.rtm_dst_len = 30;
4686 Request.msg.rtm_table = RT_TABLE_MAIN;
4687 Request.msg.rtm_protocol = RTPROT_BOOT;
4688 Request.msg.rtm_scope = RT_SCOPE_UNIVERSE;
4689 Request.msg.rtm_type = RTN_UNICAST;
4690 inet_aton("1.1.1.0", &DestinationIpv4);
4691 inet_aton("1.1.1.1", &GatewayIpv4);
4692 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, &GatewayIpv4, LoopbackIndex);
4693
4694 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4695 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4696
4697 usleep(1000 * 60);
4698 memset(&Request, 0, sizeof(Request));
4699 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4700 Request.nlh.nlmsg_type = RTM_NEWROUTE;
4701 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE;
4702 Request.nlh.nlmsg_seq = 0x4567;
4703 Request.msg.rtm_family = AF_INET;
4704 Request.msg.rtm_dst_len = 31;
4705 Request.msg.rtm_table = RT_TABLE_MAIN;
4706 Request.msg.rtm_protocol = RTPROT_BOOT;
4707 Request.msg.rtm_scope = RT_SCOPE_UNIVERSE;
4708 Request.msg.rtm_type = RTN_UNICAST;
4709 inet_aton("1.1.1.0", &DestinationIpv4);
4710 inet_aton("1.1.1.1", &GatewayIpv4);
4711 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, &GatewayIpv4, LoopbackIndex);
4712
4713 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4714 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4715
4716 usleep(1000 * 60);
4717 memset(&Request, 0, sizeof(Request));
4718 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4719 Request.nlh.nlmsg_type = RTM_NEWROUTE;
4720 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
4721 Request.nlh.nlmsg_seq = 0x4567;
4722 Request.msg.rtm_family = AF_INET;
4723 Request.msg.rtm_dst_len = 32;
4724 Request.msg.rtm_table = RT_TABLE_MAIN;
4725 Request.msg.rtm_protocol = RTPROT_BOOT;
4726 Request.msg.rtm_scope = RT_SCOPE_UNIVERSE;
4727 Request.msg.rtm_type = RTN_UNICAST;
4728 inet_aton("1.1.1.0", &DestinationIpv4);
4729 inet_aton("1.1.1.1", &GatewayIpv4);
4730 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, &GatewayIpv4, LoopbackIndex);
4731
4732 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4733 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4734 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4735
4736 //
4737 // Test giving an invalid interface index, which should fail.
4738 //
4739
4740 memset(&Request, 0, sizeof(Request));
4741 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4742 Request.nlh.nlmsg_type = RTM_NEWROUTE;
4743 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
4744 Request.nlh.nlmsg_seq = 0x4567;
4745 Request.msg.rtm_family = AF_INET;
4746 Request.msg.rtm_dst_len = 32;
4747 Request.msg.rtm_table = RT_TABLE_MAIN;
4748 Request.msg.rtm_protocol = RTPROT_BOOT;
4749 Request.msg.rtm_scope = RT_SCOPE_UNIVERSE;
4750 Request.msg.rtm_type = RTN_UNICAST;
4751 inet_aton("1.1.1.10", &DestinationIpv4);
4752 inet_aton("1.1.1.1", &GatewayIpv4);
4753 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, &GatewayIpv4, 90000);
4754
4755 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4756 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4757 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -ENETUNREACH));
4758
4759 //
4760 // Add 2 Ipv6 entries.
4761 //
4762
4763 usleep(1000 * 60);
4764 memset(&Request, 0, sizeof(Request));
4765 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4766 Request.nlh.nlmsg_type = RTM_NEWROUTE;
4767 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
4768 Request.nlh.nlmsg_seq = 0x4567;
4769 Request.msg.rtm_family = AF_INET6;
4770 Request.msg.rtm_dst_len = 31;
4771 Request.msg.rtm_table = RT_TABLE_MAIN;
4772 Request.msg.rtm_protocol = RTPROT_BOOT;
4773 Request.msg.rtm_scope = RT_SCOPE_UNIVERSE;
4774 Request.msg.rtm_type = RTN_UNICAST;
4775 inet_pton(AF_INET6, "3ffa::", &DestinationIpv6);
4776 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), RTA_DST, &DestinationIpv6, sizeof(DestinationIpv6)));
4777
4778 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), RTA_OIF, &LoopbackIndex, sizeof(LoopbackIndex)));
4779
4780 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4781 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4782
4783 usleep(1000 * 60);
4784 memset(&Request, 0, sizeof(Request));
4785 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4786 Request.nlh.nlmsg_type = RTM_NEWROUTE;
4787 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
4788 Request.nlh.nlmsg_seq = 0x4567;
4789 Request.msg.rtm_family = AF_INET6;
4790 Request.msg.rtm_dst_len = 32;
4791 Request.msg.rtm_table = RT_TABLE_MAIN;
4792 Request.msg.rtm_protocol = RTPROT_BOOT;
4793 Request.msg.rtm_scope = RT_SCOPE_UNIVERSE;
4794 Request.msg.rtm_type = RTN_UNICAST;
4795 inet_pton(AF_INET6, "3ffa::", &DestinationIpv6);
4796 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), RTA_DST, &DestinationIpv6, sizeof(DestinationIpv6)));
4797
4798 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), RTA_OIF, &LoopbackIndex, sizeof(LoopbackIndex)));
4799
4800 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4801 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4802 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4803
4804 //
4805 // Now test RTM_DELROUTE!
4806 // Now, we have the following routing entries for the loopback adapter:
4807 // Destination Gateway
4808 // 1.1.1.0/30 1.1.1.1
4809 // 1.1.1.0/31 1.1.1.1
4810 // 1.1.1.0/32 1.1.1.1
4811 // 1.1.1.1 on-link (zero)
4812 // 1.1.1.2 1.1.1.1
4813 // 1.1.1.3 on-link (zero)
4814 // 1.1.2 1.1.1.1
4815 // 1.3 1.1.1.1
4816 // === IPv6 ===
4817 // 3ffa::/31 on-link
4818 // 3ffa::/32 on-link
4819 //
4820
4821 //
4822 // Try to delete the routing entry with destination 1.1.1.1 and
4823 // gateway 1.2.3.4, which does not exist, returning ESRCH.
4824 //
4825
4826 memset(&Request, 0, sizeof(Request));
4827 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4828 Request.nlh.nlmsg_type = RTM_DELROUTE;
4829 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE | NLM_F_EXCL | 0x4321;
4830 Request.nlh.nlmsg_seq = 0x4567;
4831 Request.msg.rtm_family = AF_INET;
4832 Request.msg.rtm_dst_len = 32;
4833 Request.msg.rtm_table = RT_TABLE_MAIN;
4834 Request.msg.rtm_scope = RT_SCOPE_NOWHERE;
4835 inet_aton("1.1.1.1", &DestinationIpv4);
4836 inet_aton("1.2.3.4", &GatewayIpv4);
4837 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, &GatewayIpv4, LoopbackIndex);
4838
4839 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4840 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4841 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -ESRCH));
4842
4843 //
4844 // Passing 0 flags results in no response.
4845 //
4846
4847 Request.nlh.nlmsg_flags = 0;
4848 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4849 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4850
4851 //
4852 // Try to delete the routing entry with destination 1.1.1.1 and
4853 // gateway 0.0.0.0, which should succeed.
4854 // Note that as long as the NLM_F_REQUEST flag is present, it does
4855 // not matter what the rest of the flags are.
4856 //
4857
4858 memset(&Request, 0, sizeof(Request));
4859 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4860 Request.nlh.nlmsg_type = RTM_DELROUTE;
4861 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE | NLM_F_EXCL | 0x4321;
4862 Request.nlh.nlmsg_seq = 0x4567;
4863 Request.msg.rtm_family = AF_INET;
4864 Request.msg.rtm_dst_len = 32;
4865 Request.msg.rtm_table = RT_TABLE_MAIN;
4866 Request.msg.rtm_scope = RT_SCOPE_NOWHERE;
4867 inet_aton("1.1.1.1", &DestinationIpv4);
4868 inet_aton("0.0.0.0", &GatewayIpv4);
4869 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, &GatewayIpv4, LoopbackIndex);
4870
4871 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4872 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4873
4874 //
4875 // Try to delete the routing entry with destination 1.1.1.2 and
4876 // gateway 1.2.3.4, which does not exist, returning ESRCH.
4877 //
4878
4879 memset(&Request, 0, sizeof(Request));
4880 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4881 Request.nlh.nlmsg_type = RTM_DELROUTE;
4882 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE | NLM_F_EXCL | 0x4321;
4883 Request.nlh.nlmsg_seq = 0x4567;
4884 Request.msg.rtm_family = AF_INET;
4885 Request.msg.rtm_dst_len = 32;
4886 Request.msg.rtm_table = RT_TABLE_MAIN;
4887 Request.msg.rtm_scope = RT_SCOPE_NOWHERE;
4888 inet_aton("1.1.1.2", &DestinationIpv4);
4889 inet_aton("1.2.3.4", &GatewayIpv4);
4890 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, &GatewayIpv4, LoopbackIndex);
4891
4892 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4893 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4894 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -ESRCH));
4895
4896 //
4897 // Try to delete the routing entry with destination 1.1.1.2 and
4898 // gateway 0.0.0.0, which should succeed.
4899 // Note that even though the gateway is 1.1.1.1, specifying
4900 // 0.0.0.0 in the request specifies a wildcard gateway.
4901 //
4902
4903 memset(&Request, 0, sizeof(Request));
4904 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4905 Request.nlh.nlmsg_type = RTM_DELROUTE;
4906 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE | NLM_F_EXCL | 0x4321;
4907 Request.nlh.nlmsg_seq = 0x4567;
4908 Request.msg.rtm_family = AF_INET;
4909 Request.msg.rtm_dst_len = 32;
4910 Request.msg.rtm_table = RT_TABLE_MAIN;
4911 Request.msg.rtm_scope = RT_SCOPE_NOWHERE;
4912 inet_aton("1.1.1.2", &DestinationIpv4);
4913 inet_aton("0.0.0.0", &GatewayIpv4);
4914 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, &GatewayIpv4, LoopbackIndex);
4915
4916 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4917 LxtCheckErrnoFailure(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), MSG_DONTWAIT), EAGAIN);
4918
4919 //
4920 // Test giving an invalid interface index, which should fail.
4921 //
4922
4923 memset(&Request, 0, sizeof(Request));
4924 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4925 Request.nlh.nlmsg_type = RTM_DELROUTE;
4926 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK | 0x4321;
4927 Request.nlh.nlmsg_seq = 0x4567;
4928 Request.msg.rtm_family = AF_INET;
4929 Request.msg.rtm_dst_len = 32;
4930 Request.msg.rtm_table = RT_TABLE_MAIN;
4931 Request.msg.rtm_scope = RT_SCOPE_NOWHERE;
4932 inet_aton("1.1.1.3", &DestinationIpv4);
4933 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, NULL, 90000);
4934
4935 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4936 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4937 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, -ESRCH));
4938
4939 //
4940 // Try to delete the routing entry with destination 1.1.1.3 and
4941 // no gateway specified, which should succeed.
4942 //
4943
4944 memset(&Request, 0, sizeof(Request));
4945 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4946 Request.nlh.nlmsg_type = RTM_DELROUTE;
4947 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK | 0x4321;
4948 Request.nlh.nlmsg_seq = 0x4567;
4949 Request.msg.rtm_family = AF_INET;
4950 Request.msg.rtm_dst_len = 32;
4951 Request.msg.rtm_table = RT_TABLE_MAIN;
4952 Request.msg.rtm_scope = RT_SCOPE_NOWHERE;
4953 inet_aton("1.1.1.3", &DestinationIpv4);
4954 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, NULL, LoopbackIndex);
4955
4956 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4957 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4958 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4959
4960 //
4961 // Try to delete the routing entry with destination 1.1.2 and
4962 // no gateway specified, which should succeed.
4963 //
4964
4965 memset(&Request, 0, sizeof(Request));
4966 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4967 Request.nlh.nlmsg_type = RTM_DELROUTE;
4968 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK | 0x4321;
4969 Request.nlh.nlmsg_seq = 0x4567;
4970 Request.msg.rtm_family = AF_INET;
4971 Request.msg.rtm_dst_len = 32;
4972 Request.msg.rtm_table = RT_TABLE_MAIN;
4973 Request.msg.rtm_scope = RT_SCOPE_NOWHERE;
4974 inet_aton("1.1.2", &DestinationIpv4);
4975 SocketNetlinkRouteAddRouteAttributes(&Request.nlh, sizeof(Request), &DestinationIpv4, NULL, LoopbackIndex);
4976
4977 LxtCheckErrno(sendto(Socket, &Request, sizeof(Request), 0, NULL, 0));
4978 LxtCheckErrno(ReceiveResult = recv(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0));
4979 LxtCheckResult(SocketNetlinkCheckResponseError(ReceiveBuffer, ReceiveResult, 0));
4980
4981 //
4982 // Try to delete the routing entry with destination 1.3 and
4983 // gateway 1.1.1.1 specified, which should succeed.
4984 //
4985
4986 memset(&Request, 0, sizeof(Request));
4987 Request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
4988 Request.nlh.nlmsg_type = RTM_DELROUTE;
4989 Request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE | NLM_F_CREATE | NLM_F_EXCL | 0x4321;
4990 Request.nlh.nlmsg_seq = 0x4567;
4991 Request.msg.rtm_family = AF_INET;
4992 Request.msg.rtm_dst_len = 32;
4993 Request.msg.rtm_table = RT_TABLE_MAIN;
4994 Request.msg.rtm_scope = RT_SCOPE_NOWHERE;
4995 inet_aton("1.3", &DestinationIpv4);
4996 inet_aton("1.1.1.1", &GatewayIpv4);
4997 LxtCheckErrnoZeroSuccess(SocketNetlinkRouteAddAttribute(&Request.nlh, sizeof(Request), RTA_GATEWAY, &GatewayIpv4, sizeof(GatewayIpv4)));
4998
4999 //
5000 // First try sending incomplete information (only sending the gateway
Showing first 5,000 of 5,394 lines. View raw