1 /* 2 * Copyright (c) 2016 Fabien Siron <fabien.siron (at) epita.fr> 3 * Copyright (c) 2017 JingPiao Chen <chenjingpiao (at) gmail.com> 4 * Copyright (c) 2017 The strace developers. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "tests.h" 31 #include <stdio.h> 32 #include <string.h> 33 #include <stdint.h> 34 #include <unistd.h> 35 #include <sys/socket.h> 36 #include <arpa/inet.h> 37 #include <netinet/tcp.h> 38 #include "test_netlink.h" 39 #include <linux/if_ether.h> 40 #include <linux/inet_diag.h> 41 #include <linux/netlink_diag.h> 42 #include <linux/packet_diag.h> 43 #ifdef AF_SMC 44 # include <linux/smc_diag.h> 45 #endif 46 #include <linux/sock_diag.h> 47 #include <linux/unix_diag.h> 48 49 #define SMC_ACTIVE 1 50 51 #define TEST_SOCK_DIAG(fd_, nlh0_, \ 52 family_, type_, flags_, \ 53 obj_, print_family_, ...) \ 54 \ 55 do { \ 56 /* family only */ \ 57 uint8_t family = (family_); \ 58 TEST_NETLINK_((fd_), (nlh0_), \ 59 type_, #type_, \ 60 flags_, #flags_, \ 61 sizeof(family), &family, sizeof(family), \ 62 printf("{family=%s}", #family_)); \ 63 \ 64 /* family and string */ \ 65 char buf[sizeof(family) + 4]; \ 66 memcpy(buf, &family, sizeof(family)); \ 67 memcpy(buf + sizeof(family), "1234", 4); \ 68 TEST_NETLINK_((fd_), (nlh0_), \ 69 type_, #type_, \ 70 flags_, #flags_, \ 71 sizeof(buf), buf, sizeof(buf), \ 72 (print_family_); \ 73 printf(", ...}")); \ 74 \ 75 /* sizeof(obj_) */ \ 76 TEST_NETLINK_((fd_), (nlh0_), \ 77 type_, #type_, \ 78 flags_, #flags_, \ 79 sizeof(obj_), &(obj_), sizeof(obj_), \ 80 (print_family_); \ 81 __VA_ARGS__); \ 82 \ 83 /* short read of sizeof(obj_) */ \ 84 TEST_NETLINK_((fd_), (nlh0_), \ 85 type_, #type_, \ 86 flags_, #flags_, \ 87 sizeof(obj_), &(obj_), sizeof(obj_) - 1, \ 88 (print_family_); \ 89 printf(", %p}", \ 90 NLMSG_DATA(TEST_NETLINK_nlh) + 1));\ 91 } while (0) 92 93 static void 94 test_nlmsg_type(const int fd) 95 { 96 long rc; 97 struct nlmsghdr nlh = { 98 .nlmsg_len = sizeof(nlh), 99 .nlmsg_type = SOCK_DIAG_BY_FAMILY, 100 .nlmsg_flags = NLM_F_REQUEST, 101 }; 102 103 rc = sendto(fd, &nlh, sizeof(nlh), MSG_DONTWAIT, NULL, 0); 104 printf("sendto(%d, {len=%u, type=SOCK_DIAG_BY_FAMILY" 105 ", flags=NLM_F_REQUEST, seq=0, pid=0}" 106 ", %u, MSG_DONTWAIT, NULL, 0) = %s\n", 107 fd, nlh.nlmsg_len, (unsigned) sizeof(nlh), sprintrc(rc)); 108 } 109 110 static void 111 test_nlmsg_flags(const int fd) 112 { 113 long rc; 114 struct nlmsghdr nlh = { 115 .nlmsg_len = sizeof(nlh), 116 .nlmsg_type = SOCK_DIAG_BY_FAMILY, 117 .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP, 118 }; 119 120 rc = sendto(fd, &nlh, sizeof(nlh), MSG_DONTWAIT, NULL, 0); 121 printf("sendto(%d, {len=%u, type=SOCK_DIAG_BY_FAMILY" 122 ", flags=NLM_F_REQUEST|NLM_F_DUMP, seq=0, pid=0}" 123 ", %u, MSG_DONTWAIT, NULL, 0) = %s\n", 124 fd, nlh.nlmsg_len, (unsigned) sizeof(nlh), sprintrc(rc)); 125 } 126 127 static void 128 test_odd_family_req(const int fd) 129 { 130 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 131 132 /* unspecified family only */ 133 uint8_t family = 0; 134 TEST_NETLINK(fd, nlh0, 135 SOCK_DIAG_BY_FAMILY, 136 NLM_F_REQUEST, 137 sizeof(family), &family, sizeof(family), 138 printf("{family=AF_UNSPEC}")); 139 140 /* unknown family only */ 141 family = 0xff; 142 TEST_NETLINK(fd, nlh0, 143 SOCK_DIAG_BY_FAMILY, 144 NLM_F_REQUEST, 145 sizeof(family), &family, sizeof(family), 146 printf("{family=%#x /* AF_??? */}", family)); 147 148 /* short read of family */ 149 TEST_NETLINK(fd, nlh0, 150 SOCK_DIAG_BY_FAMILY, 151 NLM_F_REQUEST, 152 sizeof(family), &family, sizeof(family) - 1, 153 printf("%p", NLMSG_DATA(TEST_NETLINK_nlh))); 154 155 /* unspecified family and string */ 156 char buf[sizeof(family) + 4]; 157 family = 0; 158 memcpy(buf, &family, sizeof(family)); 159 memcpy(buf + sizeof(family), "1234", 4); 160 TEST_NETLINK(fd, nlh0, 161 SOCK_DIAG_BY_FAMILY, 162 NLM_F_REQUEST, 163 sizeof(buf), buf, sizeof(buf), 164 printf("{family=AF_UNSPEC, \"\\x31\\x32\\x33\\x34\"}")); 165 166 /* unknown family and string */ 167 family = 0xfd; 168 memcpy(buf, &family, sizeof(family)); 169 TEST_NETLINK(fd, nlh0, 170 SOCK_DIAG_BY_FAMILY, 171 NLM_F_REQUEST, 172 sizeof(buf), buf, sizeof(buf), 173 printf("{family=%#x /* AF_??? */" 174 ", \"\\x31\\x32\\x33\\x34\"}", family)); 175 } 176 177 static void 178 test_odd_family_msg(const int fd) 179 { 180 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 181 182 /* unspecified family only */ 183 uint8_t family = 0; 184 TEST_NETLINK(fd, nlh0, 185 SOCK_DIAG_BY_FAMILY, NLM_F_DUMP, 186 sizeof(family), &family, sizeof(family), 187 printf("{family=AF_UNSPEC}")); 188 189 /* unknown family only */ 190 family = 0xff; 191 TEST_NETLINK(fd, nlh0, 192 SOCK_DIAG_BY_FAMILY, NLM_F_DUMP, 193 sizeof(family), &family, sizeof(family), 194 printf("{family=%#x /* AF_??? */}", family)); 195 196 /* short read of family */ 197 TEST_NETLINK(fd, nlh0, 198 SOCK_DIAG_BY_FAMILY, NLM_F_DUMP, 199 sizeof(family), &family, sizeof(family) - 1, 200 printf("%p", NLMSG_DATA(TEST_NETLINK_nlh))); 201 202 /* unspecified family and string */ 203 char buf[sizeof(family) + 4]; 204 family = 0; 205 memcpy(buf, &family, sizeof(family)); 206 memcpy(buf + sizeof(family), "1234", 4); 207 TEST_NETLINK(fd, nlh0, 208 SOCK_DIAG_BY_FAMILY, NLM_F_DUMP, 209 sizeof(buf), buf, sizeof(buf), 210 printf("{family=AF_UNSPEC, \"\\x31\\x32\\x33\\x34\"}")); 211 212 /* unknown family and string */ 213 family = 0xfd; 214 memcpy(buf, &family, sizeof(family)); 215 TEST_NETLINK(fd, nlh0, 216 SOCK_DIAG_BY_FAMILY, NLM_F_DUMP, 217 sizeof(buf), buf, sizeof(buf), 218 printf("{family=%#x /* AF_??? */" 219 ", \"\\x31\\x32\\x33\\x34\"}", family)); 220 } 221 222 static void 223 test_unix_diag_req(const int fd) 224 { 225 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 226 static const struct unix_diag_req req = { 227 .sdiag_family = AF_UNIX, 228 .sdiag_protocol = 253, 229 .udiag_states = 1 << TCP_ESTABLISHED | 1 << TCP_LISTEN, 230 .udiag_ino = 0xfacefeed, 231 .udiag_show = UDIAG_SHOW_NAME, 232 .udiag_cookie = { 0xdeadbeef, 0xbadc0ded } 233 }; 234 TEST_SOCK_DIAG(fd, nlh0, AF_UNIX, 235 SOCK_DIAG_BY_FAMILY, NLM_F_REQUEST, req, 236 printf("{sdiag_family=AF_UNIX"), 237 PRINT_FIELD_U(", ", req, sdiag_protocol); 238 printf(", udiag_states=1<<TCP_ESTABLISHED|1<<TCP_LISTEN"); 239 PRINT_FIELD_U(", ", req, udiag_ino); 240 printf(", udiag_show=UDIAG_SHOW_NAME"); 241 PRINT_FIELD_COOKIE(", ", req, udiag_cookie); 242 printf("}")); 243 } 244 245 static void 246 test_unix_diag_msg(const int fd) 247 { 248 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 249 static const struct unix_diag_msg msg = { 250 .udiag_family = AF_UNIX, 251 .udiag_type = SOCK_STREAM, 252 .udiag_state = TCP_FIN_WAIT1, 253 .udiag_ino = 0xfacefeed, 254 .udiag_cookie = { 0xdeadbeef, 0xbadc0ded } 255 }; 256 TEST_SOCK_DIAG(fd, nlh0, AF_UNIX, 257 SOCK_DIAG_BY_FAMILY, NLM_F_DUMP, msg, 258 printf("{udiag_family=AF_UNIX"), 259 printf(", udiag_type=SOCK_STREAM" 260 ", udiag_state=TCP_FIN_WAIT1"); 261 PRINT_FIELD_U(", ", msg, udiag_ino); 262 PRINT_FIELD_COOKIE(", ", msg, udiag_cookie); 263 printf("}")); 264 } 265 266 static void 267 test_netlink_diag_req(const int fd) 268 { 269 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 270 struct netlink_diag_req req = { 271 .sdiag_family = AF_NETLINK, 272 .sdiag_protocol = NDIAG_PROTO_ALL, 273 .ndiag_ino = 0xfacefeed, 274 .ndiag_show = NDIAG_SHOW_MEMINFO, 275 .ndiag_cookie = { 0xdeadbeef, 0xbadc0ded } 276 }; 277 TEST_SOCK_DIAG(fd, nlh0, AF_NETLINK, 278 SOCK_DIAG_BY_FAMILY, NLM_F_REQUEST, req, 279 printf("{sdiag_family=AF_NETLINK"), 280 printf(", sdiag_protocol=NDIAG_PROTO_ALL"); 281 PRINT_FIELD_U(", ", req, ndiag_ino); 282 printf(", ndiag_show=NDIAG_SHOW_MEMINFO"); 283 PRINT_FIELD_COOKIE(", ", req, ndiag_cookie); 284 printf("}")); 285 286 req.sdiag_protocol = NETLINK_ROUTE; 287 req.ndiag_show = NDIAG_SHOW_GROUPS; 288 TEST_SOCK_DIAG(fd, nlh0, AF_NETLINK, 289 SOCK_DIAG_BY_FAMILY, NLM_F_REQUEST, req, 290 printf("{sdiag_family=AF_NETLINK"), 291 printf(", sdiag_protocol=NETLINK_ROUTE"); 292 PRINT_FIELD_U(", ", req, ndiag_ino); 293 printf(", ndiag_show=NDIAG_SHOW_GROUPS"); 294 PRINT_FIELD_COOKIE(", ", req, ndiag_cookie); 295 printf("}")); 296 } 297 298 static void 299 test_netlink_diag_msg(const int fd) 300 { 301 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 302 static const struct netlink_diag_msg msg = { 303 .ndiag_family = AF_NETLINK, 304 .ndiag_type = SOCK_RAW, 305 .ndiag_protocol = NETLINK_ROUTE, 306 .ndiag_state = NETLINK_CONNECTED, 307 .ndiag_portid = 0xbadc0ded, 308 .ndiag_dst_portid = 0xdeadbeef, 309 .ndiag_dst_group = 0xfacefeed, 310 .ndiag_ino = 0xdaeefacd, 311 .ndiag_cookie = { 0xbadc0ded, 0xdeadbeef } 312 }; 313 TEST_SOCK_DIAG(fd, nlh0, AF_NETLINK, 314 SOCK_DIAG_BY_FAMILY, NLM_F_DUMP, msg, 315 printf("{ndiag_family=AF_NETLINK"), 316 printf(", ndiag_type=SOCK_RAW" 317 ", ndiag_protocol=NETLINK_ROUTE" 318 ", ndiag_state=NETLINK_CONNECTED"); 319 PRINT_FIELD_U(", ", msg, ndiag_portid); 320 PRINT_FIELD_U(", ", msg, ndiag_dst_portid); 321 PRINT_FIELD_U(", ", msg, ndiag_dst_group); 322 PRINT_FIELD_U(", ", msg, ndiag_ino); 323 PRINT_FIELD_COOKIE(", ", msg, ndiag_cookie); 324 printf("}")); 325 } 326 327 static void 328 test_packet_diag_req(const int fd) 329 { 330 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 331 static const struct packet_diag_req req = { 332 .sdiag_family = AF_PACKET, 333 .sdiag_protocol = ETH_P_LOOP, 334 .pdiag_ino = 0xfacefeed, 335 .pdiag_show = PACKET_SHOW_INFO, 336 .pdiag_cookie = { 0xdeadbeef, 0xbadc0ded } 337 }; 338 TEST_SOCK_DIAG(fd, nlh0, AF_PACKET, 339 SOCK_DIAG_BY_FAMILY, NLM_F_REQUEST, req, 340 printf("{sdiag_family=AF_PACKET"), 341 printf(", sdiag_protocol=ETH_P_LOOP"); 342 PRINT_FIELD_U(", ", req, pdiag_ino); 343 printf(", pdiag_show=PACKET_SHOW_INFO"); 344 PRINT_FIELD_COOKIE(", ", req, pdiag_cookie); 345 printf("}")); 346 } 347 348 static void 349 test_packet_diag_msg(const int fd) 350 { 351 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 352 static const struct packet_diag_msg msg = { 353 .pdiag_family = AF_PACKET, 354 .pdiag_type = SOCK_STREAM, 355 .pdiag_num = 0xbadc, 356 .pdiag_ino = 0xfacefeed, 357 .pdiag_cookie = { 0xdeadbeef, 0xbadc0ded } 358 }; 359 TEST_SOCK_DIAG(fd, nlh0, AF_PACKET, 360 SOCK_DIAG_BY_FAMILY, NLM_F_DUMP, msg, 361 printf("{pdiag_family=AF_PACKET"), 362 printf(", pdiag_type=SOCK_STREAM"); 363 PRINT_FIELD_U(", ", msg, pdiag_num); 364 PRINT_FIELD_U(", ", msg, pdiag_ino); 365 PRINT_FIELD_COOKIE(", ", msg, pdiag_cookie); 366 printf("}")); 367 } 368 369 static void 370 test_inet_diag_sockid(const int fd) 371 { 372 const char address[] = "12.34.56.78"; 373 const char address6[] = "12:34:56:78:90:ab:cd:ef"; 374 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 375 struct inet_diag_req_v2 req = { 376 .sdiag_family = AF_INET, 377 .idiag_ext = 1 << (INET_DIAG_CONG - 1), 378 .sdiag_protocol = IPPROTO_TCP, 379 .idiag_states = 1 << TCP_CLOSE, 380 .id = { 381 .idiag_sport = 0xfacd, 382 .idiag_dport = 0xdead, 383 .idiag_if = ifindex_lo(), 384 .idiag_cookie = { 0xdeadbeef, 0xbadc0ded } 385 }, 386 }; 387 388 if (!inet_pton(AF_INET, address, &req.id.idiag_src) || 389 !inet_pton(AF_INET, address, &req.id.idiag_dst)) 390 perror_msg_and_skip("inet_pton"); 391 392 TEST_NETLINK(fd, nlh0, 393 SOCK_DIAG_BY_FAMILY, NLM_F_REQUEST, 394 sizeof(req), &req, sizeof(req), 395 printf("{sdiag_family=AF_INET"), 396 printf(", sdiag_protocol=IPPROTO_TCP" 397 ", idiag_ext=1<<(INET_DIAG_CONG-1)" 398 ", idiag_states=1<<TCP_CLOSE" 399 ", id={idiag_sport=htons(%u)" 400 ", idiag_dport=htons(%u)" 401 ", idiag_src=inet_addr(\"%s\")" 402 ", idiag_dst=inet_addr(\"%s\")", 403 ntohs(req.id.idiag_sport), 404 ntohs(req.id.idiag_dport), 405 address, address); 406 printf(", idiag_if=" IFINDEX_LO_STR); 407 PRINT_FIELD_COOKIE(", ", req.id, idiag_cookie); 408 printf("}}")); 409 410 req.sdiag_family = AF_INET6; 411 if (!inet_pton(AF_INET6, address6, &req.id.idiag_src) || 412 !inet_pton(AF_INET6, address6, &req.id.idiag_dst)) 413 perror_msg_and_skip("inet_pton"); 414 415 TEST_NETLINK(fd, nlh0, 416 SOCK_DIAG_BY_FAMILY, NLM_F_REQUEST, 417 sizeof(req), &req, sizeof(req), 418 printf("{sdiag_family=AF_INET6"), 419 printf(", sdiag_protocol=IPPROTO_TCP" 420 ", idiag_ext=1<<(INET_DIAG_CONG-1)" 421 ", idiag_states=1<<TCP_CLOSE" 422 ", id={idiag_sport=htons(%u)" 423 ", idiag_dport=htons(%u)" 424 ", inet_pton(AF_INET6, \"%s\", &idiag_src)" 425 ", inet_pton(AF_INET6, \"%s\", &idiag_dst)", 426 ntohs(req.id.idiag_sport), 427 ntohs(req.id.idiag_dport), 428 address6, address6); 429 printf(", idiag_if=" IFINDEX_LO_STR); 430 PRINT_FIELD_COOKIE(", ", req.id, idiag_cookie); 431 printf("}}")); 432 } 433 434 static void 435 test_inet_diag_req(const int fd) 436 { 437 const char address[] = "12.34.56.78"; 438 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 439 struct inet_diag_req req = { 440 .idiag_family = AF_INET, 441 .idiag_src_len = 0xde, 442 .idiag_dst_len = 0xba, 443 .idiag_ext = 1 << (INET_DIAG_TOS - 1), 444 .id = { 445 .idiag_sport = 0xdead, 446 .idiag_dport = 0xadcd, 447 .idiag_if = ifindex_lo(), 448 .idiag_cookie = { 0xdeadbeef, 0xbadc0ded } 449 }, 450 .idiag_states = 1 << TCP_LAST_ACK, 451 .idiag_dbs = 0xfacefeed, 452 }; 453 454 if (!inet_pton(AF_INET, address, &req.id.idiag_src) || 455 !inet_pton(AF_INET, address, &req.id.idiag_dst)) 456 perror_msg_and_skip("inet_pton"); 457 458 TEST_SOCK_DIAG(fd, nlh0, AF_INET, 459 TCPDIAG_GETSOCK, NLM_F_REQUEST, req, 460 printf("{idiag_family=AF_INET"), 461 PRINT_FIELD_U(", ", req, idiag_src_len); 462 PRINT_FIELD_U(", ", req, idiag_dst_len); 463 printf(", idiag_ext=1<<(INET_DIAG_TOS-1)"); 464 printf(", id={idiag_sport=htons(%u)" 465 ", idiag_dport=htons(%u)" 466 ", idiag_src=inet_addr(\"%s\")" 467 ", idiag_dst=inet_addr(\"%s\")", 468 ntohs(req.id.idiag_sport), 469 ntohs(req.id.idiag_dport), 470 address, address); 471 printf(", idiag_if=" IFINDEX_LO_STR); 472 PRINT_FIELD_COOKIE(", ", req.id, idiag_cookie); 473 printf("}, idiag_states=1<<TCP_LAST_ACK"); 474 PRINT_FIELD_U(", ", req, idiag_dbs); 475 printf("}")); 476 } 477 478 static void 479 test_inet_diag_req_v2(const int fd) 480 { 481 const char address[] = "87.65.43.21"; 482 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 483 struct inet_diag_req_v2 req = { 484 .sdiag_family = AF_INET, 485 .idiag_ext = 1 << (INET_DIAG_CONG - 1), 486 .sdiag_protocol = IPPROTO_TCP, 487 .idiag_states = 1 << TCP_CLOSE, 488 .id = { 489 .idiag_sport = 0xfacd, 490 .idiag_dport = 0xdead, 491 .idiag_if = ifindex_lo(), 492 .idiag_cookie = { 0xdeadbeef, 0xbadc0ded } 493 }, 494 }; 495 496 if (!inet_pton(AF_INET, address, &req.id.idiag_src) || 497 !inet_pton(AF_INET, address, &req.id.idiag_dst)) 498 perror_msg_and_skip("inet_pton"); 499 500 TEST_SOCK_DIAG(fd, nlh0, AF_INET, 501 SOCK_DIAG_BY_FAMILY, NLM_F_REQUEST, req, 502 printf("{sdiag_family=AF_INET"), 503 printf(", sdiag_protocol=IPPROTO_TCP" 504 ", idiag_ext=1<<(INET_DIAG_CONG-1)" 505 ", idiag_states=1<<TCP_CLOSE" 506 ", id={idiag_sport=htons(%u)" 507 ", idiag_dport=htons(%u)" 508 ", idiag_src=inet_addr(\"%s\")" 509 ", idiag_dst=inet_addr(\"%s\")", 510 ntohs(req.id.idiag_sport), 511 ntohs(req.id.idiag_dport), 512 address, address); 513 printf(", idiag_if=" IFINDEX_LO_STR); 514 PRINT_FIELD_COOKIE(", ", req.id, idiag_cookie); 515 printf("}}")); 516 } 517 518 static void 519 test_inet_diag_msg(const int fd) 520 { 521 const char address[] = "11.22.33.44"; 522 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 523 struct inet_diag_msg msg = { 524 .idiag_family = AF_INET, 525 .idiag_state = TCP_LISTEN, 526 .idiag_timer = 0xfa, 527 .idiag_retrans = 0xde, 528 .id = { 529 .idiag_sport = 0xfacf, 530 .idiag_dport = 0xdead, 531 .idiag_if = ifindex_lo(), 532 .idiag_cookie = { 0xdeadbeef, 0xbadc0ded } 533 }, 534 .idiag_expires = 0xfacefeed, 535 .idiag_rqueue = 0xdeadbeef, 536 .idiag_wqueue = 0xadcdfafc, 537 .idiag_uid = 0xdecefaeb, 538 .idiag_inode = 0xbadc0ded, 539 }; 540 541 if (!inet_pton(AF_INET, address, &msg.id.idiag_src) || 542 !inet_pton(AF_INET, address, &msg.id.idiag_dst)) 543 perror_msg_and_skip("inet_pton"); 544 545 TEST_SOCK_DIAG(fd, nlh0, AF_INET, 546 SOCK_DIAG_BY_FAMILY, NLM_F_DUMP, msg, 547 printf("{idiag_family=AF_INET"), 548 printf(", idiag_state=TCP_LISTEN"); 549 PRINT_FIELD_U(", ", msg, idiag_timer); 550 PRINT_FIELD_U(", ", msg, idiag_retrans); 551 printf(", id={idiag_sport=htons(%u)" 552 ", idiag_dport=htons(%u)" 553 ", idiag_src=inet_addr(\"%s\")" 554 ", idiag_dst=inet_addr(\"%s\")", 555 ntohs(msg.id.idiag_sport), 556 ntohs(msg.id.idiag_dport), 557 address, address); 558 printf(", idiag_if=" IFINDEX_LO_STR); 559 PRINT_FIELD_COOKIE(", ", msg.id, idiag_cookie); 560 PRINT_FIELD_U("}, ", msg, idiag_expires); 561 PRINT_FIELD_U(", ", msg, idiag_rqueue); 562 PRINT_FIELD_U(", ", msg, idiag_wqueue); 563 PRINT_FIELD_U(", ", msg, idiag_uid); 564 PRINT_FIELD_U(", ", msg, idiag_inode); 565 printf("}")); 566 } 567 568 #ifdef AF_SMC 569 static void 570 test_smc_diag_req(const int fd) 571 { 572 const char address[] = "43.21.56.78"; 573 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 574 struct smc_diag_req req = { 575 .diag_family = AF_SMC, 576 .diag_ext = 1 << (SMC_DIAG_CONNINFO - 1), 577 .id = { 578 .idiag_sport = 0xdead, 579 .idiag_dport = 0xadcd, 580 .idiag_if = ifindex_lo(), 581 .idiag_cookie = { 0xdeadbeef, 0xbadc0ded }, 582 }, 583 }; 584 585 if (!inet_pton(AF_INET, address, &req.id.idiag_src) || 586 !inet_pton(AF_INET, address, &req.id.idiag_dst)) 587 perror_msg_and_skip("inet_pton"); 588 589 TEST_SOCK_DIAG(fd, nlh0, AF_SMC, 590 SOCK_DIAG_BY_FAMILY, NLM_F_REQUEST, req, 591 printf("{diag_family=AF_SMC"), 592 printf(", diag_ext=1<<(SMC_DIAG_CONNINFO-1)"); 593 printf(", id={idiag_sport=htons(%u)" 594 ", idiag_dport=htons(%u)" 595 ", idiag_src=inet_addr(\"%s\")" 596 ", idiag_dst=inet_addr(\"%s\")", 597 ntohs(req.id.idiag_sport), 598 ntohs(req.id.idiag_dport), 599 address, address); 600 printf(", idiag_if=" IFINDEX_LO_STR); 601 PRINT_FIELD_COOKIE(", ", req.id, idiag_cookie); 602 printf("}}")); 603 } 604 605 static void 606 test_smc_diag_msg(const int fd) 607 { 608 const char address[] = "34.87.12.90"; 609 void *const nlh0 = tail_alloc(NLMSG_HDRLEN); 610 struct smc_diag_msg msg = { 611 .diag_family = AF_SMC, 612 .diag_state = SMC_ACTIVE, 613 .diag_fallback = 0xde, 614 .diag_shutdown = 0xba, 615 .id = { 616 .idiag_sport = 0xdead, 617 .idiag_dport = 0xadcd, 618 .idiag_if = ifindex_lo(), 619 .idiag_cookie = { 0xdeadbeef, 0xbadc0ded }, 620 }, 621 .diag_uid = 0xadcdfafc, 622 .diag_inode = 0xbadc0ded, 623 }; 624 625 if (!inet_pton(AF_INET, address, &msg.id.idiag_src) || 626 !inet_pton(AF_INET, address, &msg.id.idiag_dst)) 627 perror_msg_and_skip("inet_pton"); 628 629 TEST_SOCK_DIAG(fd, nlh0, AF_SMC, 630 SOCK_DIAG_BY_FAMILY, NLM_F_DUMP, msg, 631 printf("{diag_family=AF_SMC"), 632 printf(", diag_state=SMC_ACTIVE"); 633 PRINT_FIELD_U(", ", msg, diag_fallback); 634 PRINT_FIELD_U(", ", msg, diag_shutdown); 635 printf(", id={idiag_sport=htons(%u)" 636 ", idiag_dport=htons(%u)" 637 ", idiag_src=inet_addr(\"%s\")" 638 ", idiag_dst=inet_addr(\"%s\")", 639 ntohs(msg.id.idiag_sport), 640 ntohs(msg.id.idiag_dport), 641 address, address); 642 printf(", idiag_if=" IFINDEX_LO_STR); 643 PRINT_FIELD_COOKIE(", ", msg.id, idiag_cookie); 644 PRINT_FIELD_U("}, ", msg, diag_uid); 645 PRINT_FIELD_U(", ", msg, diag_inode); 646 printf("}")); 647 } 648 #endif 649 650 int 651 main(void) 652 { 653 skip_if_unavailable("/proc/self/fd/"); 654 655 int fd = create_nl_socket(NETLINK_SOCK_DIAG); 656 657 test_nlmsg_type(fd); 658 test_nlmsg_flags(fd); 659 test_odd_family_req(fd); 660 test_odd_family_msg(fd); 661 test_unix_diag_req(fd); 662 test_unix_diag_msg(fd); 663 test_netlink_diag_req(fd); 664 test_netlink_diag_msg(fd); 665 test_packet_diag_req(fd); 666 test_packet_diag_msg(fd); 667 test_inet_diag_sockid(fd); 668 test_inet_diag_req(fd); 669 test_inet_diag_req_v2(fd); 670 test_inet_diag_msg(fd); 671 #ifdef AF_SMC 672 test_smc_diag_req(fd); 673 test_smc_diag_msg(fd); 674 #endif 675 676 printf("+++ exited with 0 +++\n"); 677 678 return 0; 679 } 680