1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <errno.h> 4 #include <error.h> 5 #include <stdbool.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <unistd.h> 10 #include <limits.h> 11 12 #include <sys/socket.h> 13 #include <sys/types.h> 14 15 #include <arpa/inet.h> 16 #include <net/if.h> 17 18 #include <linux/rtnetlink.h> 19 #include <linux/genetlink.h> 20 21 #include "linux/mptcp.h" 22 23 #ifndef IPPROTO_MPTCP 24 #define IPPROTO_MPTCP 262 25 #endif 26 27 static void syntax(char *argv[]) 28 { 29 fprintf(stderr, "%s add|ann|rem|csf|dsf|get|set|del|flush|dump|events|listen|accept [<args>]\n", argv[0]); 30 fprintf(stderr, "\tadd [flags signal|subflow|backup|fullmesh] [id <nr>] [dev <name>] <ip>\n"); 31 fprintf(stderr, "\tann <local-ip> id <local-id> token <token> [port <local-port>] [dev <name>]\n"); 32 fprintf(stderr, "\trem id <local-id> token <token>\n"); 33 fprintf(stderr, "\tcsf lip <local-ip> lid <local-id> rip <remote-ip> rport <remote-port> token <token>\n"); 34 fprintf(stderr, "\tdsf lip <local-ip> lport <local-port> rip <remote-ip> rport <remote-port> token <token>\n"); 35 fprintf(stderr, "\tdel <id> [<ip>]\n"); 36 fprintf(stderr, "\tget <id>\n"); 37 fprintf(stderr, "\tset [<ip>] [id <nr>] flags [no]backup|[no]fullmesh [port <nr>] [token <token>] [rip <ip>] [rport <port>]\n"); 38 fprintf(stderr, "\tflush\n"); 39 fprintf(stderr, "\tdump\n"); 40 fprintf(stderr, "\tlimits [<rcv addr max> <subflow max>]\n"); 41 fprintf(stderr, "\tevents\n"); 42 fprintf(stderr, "\tlisten <local-ip> <local-port>\n"); 43 exit(0); 44 } 45 46 static int init_genl_req(char *data, int family, int cmd, int version) 47 { 48 struct nlmsghdr *nh = (void *)data; 49 struct genlmsghdr *gh; 50 int off = 0; 51 52 nh->nlmsg_type = family; 53 nh->nlmsg_flags = NLM_F_REQUEST; 54 nh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); 55 off += NLMSG_ALIGN(sizeof(*nh)); 56 57 gh = (void *)(data + off); 58 gh->cmd = cmd; 59 gh->version = version; 60 off += NLMSG_ALIGN(sizeof(*gh)); 61 return off; 62 } 63 64 static int nl_error(struct nlmsghdr *nh) 65 { 66 struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(nh); 67 int len = nh->nlmsg_len - sizeof(*nh); 68 uint32_t off; 69 70 if (len < sizeof(struct nlmsgerr)) { 71 error(1, 0, "netlink error message truncated %d min %ld", len, 72 sizeof(struct nlmsgerr)); 73 return -1; 74 } 75 76 if (err->error) { 77 /* check messages from kernel */ 78 struct rtattr *attrs = (struct rtattr *)NLMSG_DATA(nh); 79 80 fprintf(stderr, "netlink error %d (%s)\n", 81 err->error, strerror(-err->error)); 82 83 while (RTA_OK(attrs, len)) { 84 if (attrs->rta_type == NLMSGERR_ATTR_MSG) 85 fprintf(stderr, "netlink ext ack msg: %s\n", 86 (char *)RTA_DATA(attrs)); 87 if (attrs->rta_type == NLMSGERR_ATTR_OFFS) { 88 memcpy(&off, RTA_DATA(attrs), 4); 89 fprintf(stderr, "netlink err off %d\n", 90 (int)off); 91 } 92 attrs = RTA_NEXT(attrs, len); 93 } 94 return -1; 95 } 96 97 return 0; 98 } 99 100 static int capture_events(int fd, int event_group) 101 { 102 u_int8_t buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 103 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 1024]; 104 struct genlmsghdr *ghdr; 105 struct rtattr *attrs; 106 struct nlmsghdr *nh; 107 int ret = 0; 108 int res_len; 109 int msg_len; 110 fd_set rfds; 111 112 if (setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, 113 &event_group, sizeof(event_group)) < 0) 114 error(1, errno, "could not join the " MPTCP_PM_EV_GRP_NAME " mcast group"); 115 116 do { 117 bool server_side = false; 118 119 FD_ZERO(&rfds); 120 FD_SET(fd, &rfds); 121 res_len = NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 122 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 1024; 123 124 ret = select(FD_SETSIZE, &rfds, NULL, NULL, NULL); 125 126 if (ret < 0) 127 error(1, ret, "error in select() on NL socket"); 128 129 res_len = recv(fd, buffer, res_len, 0); 130 if (res_len < 0) 131 error(1, res_len, "error on recv() from NL socket"); 132 133 nh = (struct nlmsghdr *)buffer; 134 135 for (; NLMSG_OK(nh, res_len); nh = NLMSG_NEXT(nh, res_len)) { 136 if (nh->nlmsg_type == NLMSG_ERROR) 137 error(1, NLMSG_ERROR, "received invalid NL message"); 138 139 ghdr = (struct genlmsghdr *)NLMSG_DATA(nh); 140 141 if (ghdr->cmd == 0) 142 continue; 143 144 fprintf(stderr, "type:%d", ghdr->cmd); 145 146 msg_len = nh->nlmsg_len - NLMSG_LENGTH(GENL_HDRLEN); 147 148 attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN); 149 while (RTA_OK(attrs, msg_len)) { 150 if (attrs->rta_type == MPTCP_ATTR_TOKEN) 151 fprintf(stderr, ",token:%u", *(__u32 *)RTA_DATA(attrs)); 152 else if (attrs->rta_type == MPTCP_ATTR_FAMILY) 153 fprintf(stderr, ",family:%u", *(__u16 *)RTA_DATA(attrs)); 154 else if (attrs->rta_type == MPTCP_ATTR_LOC_ID) 155 fprintf(stderr, ",loc_id:%u", *(__u8 *)RTA_DATA(attrs)); 156 else if (attrs->rta_type == MPTCP_ATTR_REM_ID) 157 fprintf(stderr, ",rem_id:%u", *(__u8 *)RTA_DATA(attrs)); 158 else if (attrs->rta_type == MPTCP_ATTR_SADDR4) { 159 u_int32_t saddr4 = ntohl(*(__u32 *)RTA_DATA(attrs)); 160 161 fprintf(stderr, ",saddr4:%u.%u.%u.%u", saddr4 >> 24, 162 (saddr4 >> 16) & 0xFF, (saddr4 >> 8) & 0xFF, 163 (saddr4 & 0xFF)); 164 } else if (attrs->rta_type == MPTCP_ATTR_SADDR6) { 165 char buf[INET6_ADDRSTRLEN]; 166 167 if (inet_ntop(AF_INET6, RTA_DATA(attrs), buf, 168 sizeof(buf)) != NULL) 169 fprintf(stderr, ",saddr6:%s", buf); 170 } else if (attrs->rta_type == MPTCP_ATTR_DADDR4) { 171 u_int32_t daddr4 = ntohl(*(__u32 *)RTA_DATA(attrs)); 172 173 fprintf(stderr, ",daddr4:%u.%u.%u.%u", daddr4 >> 24, 174 (daddr4 >> 16) & 0xFF, (daddr4 >> 8) & 0xFF, 175 (daddr4 & 0xFF)); 176 } else if (attrs->rta_type == MPTCP_ATTR_DADDR6) { 177 char buf[INET6_ADDRSTRLEN]; 178 179 if (inet_ntop(AF_INET6, RTA_DATA(attrs), buf, 180 sizeof(buf)) != NULL) 181 fprintf(stderr, ",daddr6:%s", buf); 182 } else if (attrs->rta_type == MPTCP_ATTR_SPORT) 183 fprintf(stderr, ",sport:%u", 184 ntohs(*(__u16 *)RTA_DATA(attrs))); 185 else if (attrs->rta_type == MPTCP_ATTR_DPORT) 186 fprintf(stderr, ",dport:%u", 187 ntohs(*(__u16 *)RTA_DATA(attrs))); 188 else if (attrs->rta_type == MPTCP_ATTR_BACKUP) 189 fprintf(stderr, ",backup:%u", *(__u8 *)RTA_DATA(attrs)); 190 else if (attrs->rta_type == MPTCP_ATTR_ERROR) 191 fprintf(stderr, ",error:%u", *(__u8 *)RTA_DATA(attrs)); 192 else if (attrs->rta_type == MPTCP_ATTR_SERVER_SIDE) 193 server_side = !!*(__u8 *)RTA_DATA(attrs); 194 else if (attrs->rta_type == MPTCP_ATTR_FLAGS) { 195 __u16 flags = *(__u16 *)RTA_DATA(attrs); 196 197 /* only print when present, easier */ 198 if (flags & MPTCP_PM_EV_FLAG_DENY_JOIN_ID0) 199 fprintf(stderr, ",deny_join_id0:1"); 200 if (flags & MPTCP_PM_EV_FLAG_SERVER_SIDE) 201 server_side = true; 202 } 203 204 attrs = RTA_NEXT(attrs, msg_len); 205 } 206 } 207 if (server_side) 208 fprintf(stderr, ",server_side:1"); 209 fprintf(stderr, "\n"); 210 } while (1); 211 212 return 0; 213 } 214 215 /* do a netlink command and, if max > 0, fetch the reply ; nh's size >1024B */ 216 static int do_nl_req(int fd, struct nlmsghdr *nh, int len, int max) 217 { 218 struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK }; 219 socklen_t addr_len; 220 void *data = nh; 221 int rem, ret; 222 int err = 0; 223 224 /* If no expected answer, ask for an ACK to look for errors if any */ 225 if (max == 0) { 226 nh->nlmsg_flags |= NLM_F_ACK; 227 max = 1024; 228 } 229 230 nh->nlmsg_len = len; 231 ret = sendto(fd, data, len, 0, (void *)&nladdr, sizeof(nladdr)); 232 if (ret != len) 233 error(1, errno, "send netlink: %uB != %uB\n", ret, len); 234 235 addr_len = sizeof(nladdr); 236 rem = ret = recvfrom(fd, data, max, 0, (void *)&nladdr, &addr_len); 237 if (ret < 0) 238 error(1, errno, "recv netlink: %uB\n", ret); 239 240 /* Beware: the NLMSG_NEXT macro updates the 'rem' argument */ 241 for (; NLMSG_OK(nh, rem); nh = NLMSG_NEXT(nh, rem)) { 242 if (nh->nlmsg_type == NLMSG_DONE) 243 break; 244 245 if (nh->nlmsg_type == NLMSG_ERROR && nl_error(nh)) 246 err = 1; 247 } 248 if (err) 249 error(1, 0, "bailing out due to netlink error[s]"); 250 return ret; 251 } 252 253 static int genl_parse_getfamily(struct nlmsghdr *nlh, int *pm_family, 254 int *events_mcast_grp) 255 { 256 struct genlmsghdr *ghdr = NLMSG_DATA(nlh); 257 int len = nlh->nlmsg_len; 258 struct rtattr *attrs; 259 struct rtattr *grps; 260 struct rtattr *grp; 261 int got_events_grp; 262 int got_family; 263 int grps_len; 264 int grp_len; 265 266 if (nlh->nlmsg_type != GENL_ID_CTRL) 267 error(1, errno, "Not a controller message, len=%d type=0x%x\n", 268 nlh->nlmsg_len, nlh->nlmsg_type); 269 270 len -= NLMSG_LENGTH(GENL_HDRLEN); 271 272 if (len < 0) 273 error(1, errno, "wrong controller message len %d\n", len); 274 275 if (ghdr->cmd != CTRL_CMD_NEWFAMILY) 276 error(1, errno, "Unknown controller command %d\n", ghdr->cmd); 277 278 attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN); 279 got_family = 0; 280 got_events_grp = 0; 281 282 while (RTA_OK(attrs, len)) { 283 if (attrs->rta_type == CTRL_ATTR_FAMILY_ID) { 284 *pm_family = *(__u16 *)RTA_DATA(attrs); 285 got_family = 1; 286 } else if (attrs->rta_type == CTRL_ATTR_MCAST_GROUPS) { 287 grps = RTA_DATA(attrs); 288 grps_len = RTA_PAYLOAD(attrs); 289 290 while (RTA_OK(grps, grps_len)) { 291 grp = RTA_DATA(grps); 292 grp_len = RTA_PAYLOAD(grps); 293 got_events_grp = 0; 294 295 while (RTA_OK(grp, grp_len)) { 296 if (grp->rta_type == CTRL_ATTR_MCAST_GRP_ID) 297 *events_mcast_grp = *(__u32 *)RTA_DATA(grp); 298 else if (grp->rta_type == CTRL_ATTR_MCAST_GRP_NAME && 299 !strcmp(RTA_DATA(grp), MPTCP_PM_EV_GRP_NAME)) 300 got_events_grp = 1; 301 302 grp = RTA_NEXT(grp, grp_len); 303 } 304 305 if (got_events_grp) 306 break; 307 308 grps = RTA_NEXT(grps, grps_len); 309 } 310 } 311 312 if (got_family && got_events_grp) 313 return 0; 314 315 attrs = RTA_NEXT(attrs, len); 316 } 317 318 error(1, errno, "can't find CTRL_ATTR_FAMILY_ID attr"); 319 return -1; 320 } 321 322 static int resolve_mptcp_pm_netlink(int fd, int *pm_family, int *events_mcast_grp) 323 { 324 char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 325 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 326 1024]; 327 struct nlmsghdr *nh; 328 struct rtattr *rta; 329 int namelen; 330 int off = 0; 331 332 memset(data, 0, sizeof(data)); 333 nh = (void *)data; 334 off = init_genl_req(data, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, 0); 335 336 rta = (void *)(data + off); 337 namelen = strlen(MPTCP_PM_NAME) + 1; 338 rta->rta_type = CTRL_ATTR_FAMILY_NAME; 339 rta->rta_len = RTA_LENGTH(namelen); 340 memcpy(RTA_DATA(rta), MPTCP_PM_NAME, namelen); 341 off += NLMSG_ALIGN(rta->rta_len); 342 343 do_nl_req(fd, nh, off, sizeof(data)); 344 return genl_parse_getfamily((void *)data, pm_family, events_mcast_grp); 345 } 346 347 int dsf(int fd, int pm_family, int argc, char *argv[]) 348 { 349 char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 350 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 351 1024]; 352 struct rtattr *rta, *addr; 353 u_int16_t family, port; 354 struct nlmsghdr *nh; 355 u_int32_t token; 356 int addr_start; 357 int off = 0; 358 int arg; 359 360 const char *params[5]; 361 362 memset(params, 0, 5 * sizeof(const char *)); 363 364 memset(data, 0, sizeof(data)); 365 nh = (void *)data; 366 off = init_genl_req(data, pm_family, MPTCP_PM_CMD_SUBFLOW_DESTROY, 367 MPTCP_PM_VER); 368 369 if (argc < 12) 370 syntax(argv); 371 372 /* Params recorded in this order: 373 * <local-ip>, <local-port>, <remote-ip>, <remote-port>, <token> 374 */ 375 for (arg = 2; arg < argc; arg++) { 376 if (!strcmp(argv[arg], "lip")) { 377 if (++arg >= argc) 378 error(1, 0, " missing local IP"); 379 380 params[0] = argv[arg]; 381 } else if (!strcmp(argv[arg], "lport")) { 382 if (++arg >= argc) 383 error(1, 0, " missing local port"); 384 385 params[1] = argv[arg]; 386 } else if (!strcmp(argv[arg], "rip")) { 387 if (++arg >= argc) 388 error(1, 0, " missing remote IP"); 389 390 params[2] = argv[arg]; 391 } else if (!strcmp(argv[arg], "rport")) { 392 if (++arg >= argc) 393 error(1, 0, " missing remote port"); 394 395 params[3] = argv[arg]; 396 } else if (!strcmp(argv[arg], "token")) { 397 if (++arg >= argc) 398 error(1, 0, " missing token"); 399 400 params[4] = argv[arg]; 401 } else 402 error(1, 0, "unknown keyword %s", argv[arg]); 403 } 404 405 for (arg = 0; arg < 4; arg = arg + 2) { 406 /* addr header */ 407 addr_start = off; 408 addr = (void *)(data + off); 409 addr->rta_type = NLA_F_NESTED | 410 ((arg == 0) ? MPTCP_PM_ATTR_ADDR : MPTCP_PM_ATTR_ADDR_REMOTE); 411 addr->rta_len = RTA_LENGTH(0); 412 off += NLMSG_ALIGN(addr->rta_len); 413 414 /* addr data */ 415 rta = (void *)(data + off); 416 if (inet_pton(AF_INET, params[arg], RTA_DATA(rta))) { 417 family = AF_INET; 418 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4; 419 rta->rta_len = RTA_LENGTH(4); 420 } else if (inet_pton(AF_INET6, params[arg], RTA_DATA(rta))) { 421 family = AF_INET6; 422 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6; 423 rta->rta_len = RTA_LENGTH(16); 424 } else 425 error(1, errno, "can't parse ip %s", params[arg]); 426 off += NLMSG_ALIGN(rta->rta_len); 427 428 /* family */ 429 rta = (void *)(data + off); 430 rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY; 431 rta->rta_len = RTA_LENGTH(2); 432 memcpy(RTA_DATA(rta), &family, 2); 433 off += NLMSG_ALIGN(rta->rta_len); 434 435 /* port */ 436 port = atoi(params[arg + 1]); 437 rta = (void *)(data + off); 438 rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT; 439 rta->rta_len = RTA_LENGTH(2); 440 memcpy(RTA_DATA(rta), &port, 2); 441 off += NLMSG_ALIGN(rta->rta_len); 442 443 addr->rta_len = off - addr_start; 444 } 445 446 /* token */ 447 token = strtoul(params[4], NULL, 10); 448 rta = (void *)(data + off); 449 rta->rta_type = MPTCP_PM_ATTR_TOKEN; 450 rta->rta_len = RTA_LENGTH(4); 451 memcpy(RTA_DATA(rta), &token, 4); 452 off += NLMSG_ALIGN(rta->rta_len); 453 454 do_nl_req(fd, nh, off, 0); 455 456 return 0; 457 } 458 459 int csf(int fd, int pm_family, int argc, char *argv[]) 460 { 461 char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 462 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 463 1024]; 464 u_int32_t flags = MPTCP_PM_ADDR_FLAG_SUBFLOW; 465 const char *params[5]; 466 struct nlmsghdr *nh; 467 struct rtattr *addr; 468 struct rtattr *rta; 469 u_int16_t family; 470 u_int32_t token; 471 u_int16_t port; 472 int addr_start; 473 u_int8_t id; 474 int off = 0; 475 int arg; 476 477 memset(params, 0, 5 * sizeof(const char *)); 478 479 memset(data, 0, sizeof(data)); 480 nh = (void *)data; 481 off = init_genl_req(data, pm_family, MPTCP_PM_CMD_SUBFLOW_CREATE, 482 MPTCP_PM_VER); 483 484 if (argc < 12) 485 syntax(argv); 486 487 /* Params recorded in this order: 488 * <local-ip>, <local-id>, <remote-ip>, <remote-port>, <token> 489 */ 490 for (arg = 2; arg < argc; arg++) { 491 if (!strcmp(argv[arg], "lip")) { 492 if (++arg >= argc) 493 error(1, 0, " missing local IP"); 494 495 params[0] = argv[arg]; 496 } else if (!strcmp(argv[arg], "lid")) { 497 if (++arg >= argc) 498 error(1, 0, " missing local id"); 499 500 params[1] = argv[arg]; 501 } else if (!strcmp(argv[arg], "rip")) { 502 if (++arg >= argc) 503 error(1, 0, " missing remote ip"); 504 505 params[2] = argv[arg]; 506 } else if (!strcmp(argv[arg], "rport")) { 507 if (++arg >= argc) 508 error(1, 0, " missing remote port"); 509 510 params[3] = argv[arg]; 511 } else if (!strcmp(argv[arg], "token")) { 512 if (++arg >= argc) 513 error(1, 0, " missing token"); 514 515 params[4] = argv[arg]; 516 } else 517 error(1, 0, "unknown param %s", argv[arg]); 518 } 519 520 for (arg = 0; arg < 4; arg = arg + 2) { 521 /* addr header */ 522 addr_start = off; 523 addr = (void *)(data + off); 524 addr->rta_type = NLA_F_NESTED | 525 ((arg == 0) ? MPTCP_PM_ATTR_ADDR : MPTCP_PM_ATTR_ADDR_REMOTE); 526 addr->rta_len = RTA_LENGTH(0); 527 off += NLMSG_ALIGN(addr->rta_len); 528 529 /* addr data */ 530 rta = (void *)(data + off); 531 if (inet_pton(AF_INET, params[arg], RTA_DATA(rta))) { 532 family = AF_INET; 533 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4; 534 rta->rta_len = RTA_LENGTH(4); 535 } else if (inet_pton(AF_INET6, params[arg], RTA_DATA(rta))) { 536 family = AF_INET6; 537 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6; 538 rta->rta_len = RTA_LENGTH(16); 539 } else 540 error(1, errno, "can't parse ip %s", params[arg]); 541 off += NLMSG_ALIGN(rta->rta_len); 542 543 /* family */ 544 rta = (void *)(data + off); 545 rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY; 546 rta->rta_len = RTA_LENGTH(2); 547 memcpy(RTA_DATA(rta), &family, 2); 548 off += NLMSG_ALIGN(rta->rta_len); 549 550 if (arg == 2) { 551 /* port */ 552 port = atoi(params[arg + 1]); 553 rta = (void *)(data + off); 554 rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT; 555 rta->rta_len = RTA_LENGTH(2); 556 memcpy(RTA_DATA(rta), &port, 2); 557 off += NLMSG_ALIGN(rta->rta_len); 558 } 559 560 if (arg == 0) { 561 /* id */ 562 id = atoi(params[arg + 1]); 563 rta = (void *)(data + off); 564 rta->rta_type = MPTCP_PM_ADDR_ATTR_ID; 565 rta->rta_len = RTA_LENGTH(1); 566 memcpy(RTA_DATA(rta), &id, 1); 567 off += NLMSG_ALIGN(rta->rta_len); 568 } 569 570 /* addr flags */ 571 rta = (void *)(data + off); 572 rta->rta_type = MPTCP_PM_ADDR_ATTR_FLAGS; 573 rta->rta_len = RTA_LENGTH(4); 574 memcpy(RTA_DATA(rta), &flags, 4); 575 off += NLMSG_ALIGN(rta->rta_len); 576 577 addr->rta_len = off - addr_start; 578 } 579 580 /* token */ 581 token = strtoul(params[4], NULL, 10); 582 rta = (void *)(data + off); 583 rta->rta_type = MPTCP_PM_ATTR_TOKEN; 584 rta->rta_len = RTA_LENGTH(4); 585 memcpy(RTA_DATA(rta), &token, 4); 586 off += NLMSG_ALIGN(rta->rta_len); 587 588 do_nl_req(fd, nh, off, 0); 589 590 return 0; 591 } 592 593 int remove_addr(int fd, int pm_family, int argc, char *argv[]) 594 { 595 char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 596 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 597 1024]; 598 struct nlmsghdr *nh; 599 struct rtattr *rta; 600 u_int32_t token; 601 u_int8_t id; 602 int off = 0; 603 int arg; 604 605 memset(data, 0, sizeof(data)); 606 nh = (void *)data; 607 off = init_genl_req(data, pm_family, MPTCP_PM_CMD_REMOVE, 608 MPTCP_PM_VER); 609 610 if (argc < 6) 611 syntax(argv); 612 613 for (arg = 2; arg < argc; arg++) { 614 if (!strcmp(argv[arg], "id")) { 615 if (++arg >= argc) 616 error(1, 0, " missing id value"); 617 618 id = atoi(argv[arg]); 619 rta = (void *)(data + off); 620 rta->rta_type = MPTCP_PM_ATTR_LOC_ID; 621 rta->rta_len = RTA_LENGTH(1); 622 memcpy(RTA_DATA(rta), &id, 1); 623 off += NLMSG_ALIGN(rta->rta_len); 624 } else if (!strcmp(argv[arg], "token")) { 625 if (++arg >= argc) 626 error(1, 0, " missing token value"); 627 628 token = strtoul(argv[arg], NULL, 10); 629 rta = (void *)(data + off); 630 rta->rta_type = MPTCP_PM_ATTR_TOKEN; 631 rta->rta_len = RTA_LENGTH(4); 632 memcpy(RTA_DATA(rta), &token, 4); 633 off += NLMSG_ALIGN(rta->rta_len); 634 } else 635 error(1, 0, "unknown keyword %s", argv[arg]); 636 } 637 638 do_nl_req(fd, nh, off, 0); 639 return 0; 640 } 641 642 int announce_addr(int fd, int pm_family, int argc, char *argv[]) 643 { 644 char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 645 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 646 1024]; 647 u_int32_t flags = MPTCP_PM_ADDR_FLAG_SIGNAL; 648 u_int32_t token = UINT_MAX; 649 struct rtattr *rta, *addr; 650 u_int32_t id = UINT_MAX; 651 struct nlmsghdr *nh; 652 u_int16_t family; 653 int addr_start; 654 int off = 0; 655 int arg; 656 657 memset(data, 0, sizeof(data)); 658 nh = (void *)data; 659 off = init_genl_req(data, pm_family, MPTCP_PM_CMD_ANNOUNCE, 660 MPTCP_PM_VER); 661 662 if (argc < 7) 663 syntax(argv); 664 665 /* local-ip header */ 666 addr_start = off; 667 addr = (void *)(data + off); 668 addr->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR; 669 addr->rta_len = RTA_LENGTH(0); 670 off += NLMSG_ALIGN(addr->rta_len); 671 672 /* local-ip data */ 673 /* record addr type */ 674 rta = (void *)(data + off); 675 if (inet_pton(AF_INET, argv[2], RTA_DATA(rta))) { 676 family = AF_INET; 677 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4; 678 rta->rta_len = RTA_LENGTH(4); 679 } else if (inet_pton(AF_INET6, argv[2], RTA_DATA(rta))) { 680 family = AF_INET6; 681 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6; 682 rta->rta_len = RTA_LENGTH(16); 683 } else 684 error(1, errno, "can't parse ip %s", argv[2]); 685 off += NLMSG_ALIGN(rta->rta_len); 686 687 /* addr family */ 688 rta = (void *)(data + off); 689 rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY; 690 rta->rta_len = RTA_LENGTH(2); 691 memcpy(RTA_DATA(rta), &family, 2); 692 off += NLMSG_ALIGN(rta->rta_len); 693 694 for (arg = 3; arg < argc; arg++) { 695 if (!strcmp(argv[arg], "id")) { 696 /* local-id */ 697 if (++arg >= argc) 698 error(1, 0, " missing id value"); 699 700 id = atoi(argv[arg]); 701 rta = (void *)(data + off); 702 rta->rta_type = MPTCP_PM_ADDR_ATTR_ID; 703 rta->rta_len = RTA_LENGTH(1); 704 memcpy(RTA_DATA(rta), &id, 1); 705 off += NLMSG_ALIGN(rta->rta_len); 706 } else if (!strcmp(argv[arg], "dev")) { 707 /* for the if_index */ 708 int32_t ifindex; 709 710 if (++arg >= argc) 711 error(1, 0, " missing dev name"); 712 713 ifindex = if_nametoindex(argv[arg]); 714 if (!ifindex) 715 error(1, errno, "unknown device %s", argv[arg]); 716 717 rta = (void *)(data + off); 718 rta->rta_type = MPTCP_PM_ADDR_ATTR_IF_IDX; 719 rta->rta_len = RTA_LENGTH(4); 720 memcpy(RTA_DATA(rta), &ifindex, 4); 721 off += NLMSG_ALIGN(rta->rta_len); 722 } else if (!strcmp(argv[arg], "port")) { 723 /* local-port (optional) */ 724 u_int16_t port; 725 726 if (++arg >= argc) 727 error(1, 0, " missing port value"); 728 729 port = atoi(argv[arg]); 730 rta = (void *)(data + off); 731 rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT; 732 rta->rta_len = RTA_LENGTH(2); 733 memcpy(RTA_DATA(rta), &port, 2); 734 off += NLMSG_ALIGN(rta->rta_len); 735 } else if (!strcmp(argv[arg], "token")) { 736 /* MPTCP connection token */ 737 if (++arg >= argc) 738 error(1, 0, " missing token value"); 739 740 token = strtoul(argv[arg], NULL, 10); 741 } else 742 error(1, 0, "unknown keyword %s", argv[arg]); 743 } 744 745 /* addr flags */ 746 rta = (void *)(data + off); 747 rta->rta_type = MPTCP_PM_ADDR_ATTR_FLAGS; 748 rta->rta_len = RTA_LENGTH(4); 749 memcpy(RTA_DATA(rta), &flags, 4); 750 off += NLMSG_ALIGN(rta->rta_len); 751 752 addr->rta_len = off - addr_start; 753 754 if (id == UINT_MAX || token == UINT_MAX) 755 error(1, 0, " missing mandatory inputs"); 756 757 /* token */ 758 rta = (void *)(data + off); 759 rta->rta_type = MPTCP_PM_ATTR_TOKEN; 760 rta->rta_len = RTA_LENGTH(4); 761 memcpy(RTA_DATA(rta), &token, 4); 762 off += NLMSG_ALIGN(rta->rta_len); 763 764 do_nl_req(fd, nh, off, 0); 765 766 return 0; 767 } 768 769 int add_addr(int fd, int pm_family, int argc, char *argv[]) 770 { 771 char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 772 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 773 1024]; 774 struct rtattr *rta, *nest; 775 struct nlmsghdr *nh; 776 u_int32_t flags = 0; 777 u_int16_t family; 778 int nest_start; 779 u_int8_t id; 780 int off = 0; 781 int arg; 782 783 memset(data, 0, sizeof(data)); 784 nh = (void *)data; 785 off = init_genl_req(data, pm_family, MPTCP_PM_CMD_ADD_ADDR, 786 MPTCP_PM_VER); 787 788 if (argc < 3) 789 syntax(argv); 790 791 nest_start = off; 792 nest = (void *)(data + off); 793 nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR; 794 nest->rta_len = RTA_LENGTH(0); 795 off += NLMSG_ALIGN(nest->rta_len); 796 797 /* addr data */ 798 rta = (void *)(data + off); 799 if (inet_pton(AF_INET, argv[2], RTA_DATA(rta))) { 800 family = AF_INET; 801 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4; 802 rta->rta_len = RTA_LENGTH(4); 803 } else if (inet_pton(AF_INET6, argv[2], RTA_DATA(rta))) { 804 family = AF_INET6; 805 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6; 806 rta->rta_len = RTA_LENGTH(16); 807 } else 808 error(1, errno, "can't parse ip %s", argv[2]); 809 off += NLMSG_ALIGN(rta->rta_len); 810 811 /* family */ 812 rta = (void *)(data + off); 813 rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY; 814 rta->rta_len = RTA_LENGTH(2); 815 memcpy(RTA_DATA(rta), &family, 2); 816 off += NLMSG_ALIGN(rta->rta_len); 817 818 for (arg = 3; arg < argc; arg++) { 819 if (!strcmp(argv[arg], "flags")) { 820 char *tok, *str; 821 822 /* flags */ 823 if (++arg >= argc) 824 error(1, 0, " missing flags value"); 825 826 /* do not support flag list yet */ 827 for (str = argv[arg]; (tok = strtok(str, ",")); 828 str = NULL) { 829 if (!strcmp(tok, "subflow")) 830 flags |= MPTCP_PM_ADDR_FLAG_SUBFLOW; 831 else if (!strcmp(tok, "signal")) 832 flags |= MPTCP_PM_ADDR_FLAG_SIGNAL; 833 else if (!strcmp(tok, "laminar")) 834 flags |= MPTCP_PM_ADDR_FLAG_LAMINAR; 835 else if (!strcmp(tok, "backup")) 836 flags |= MPTCP_PM_ADDR_FLAG_BACKUP; 837 else if (!strcmp(tok, "fullmesh")) 838 flags |= MPTCP_PM_ADDR_FLAG_FULLMESH; 839 else 840 error(1, errno, 841 "unknown flag %s", argv[arg]); 842 } 843 844 if (flags & MPTCP_PM_ADDR_FLAG_SIGNAL && 845 flags & MPTCP_PM_ADDR_FLAG_FULLMESH) { 846 error(1, errno, "error flag fullmesh"); 847 } 848 849 rta = (void *)(data + off); 850 rta->rta_type = MPTCP_PM_ADDR_ATTR_FLAGS; 851 rta->rta_len = RTA_LENGTH(4); 852 memcpy(RTA_DATA(rta), &flags, 4); 853 off += NLMSG_ALIGN(rta->rta_len); 854 } else if (!strcmp(argv[arg], "id")) { 855 if (++arg >= argc) 856 error(1, 0, " missing id value"); 857 858 id = atoi(argv[arg]); 859 rta = (void *)(data + off); 860 rta->rta_type = MPTCP_PM_ADDR_ATTR_ID; 861 rta->rta_len = RTA_LENGTH(1); 862 memcpy(RTA_DATA(rta), &id, 1); 863 off += NLMSG_ALIGN(rta->rta_len); 864 } else if (!strcmp(argv[arg], "dev")) { 865 int32_t ifindex; 866 867 if (++arg >= argc) 868 error(1, 0, " missing dev name"); 869 870 ifindex = if_nametoindex(argv[arg]); 871 if (!ifindex) 872 error(1, errno, "unknown device %s", argv[arg]); 873 874 rta = (void *)(data + off); 875 rta->rta_type = MPTCP_PM_ADDR_ATTR_IF_IDX; 876 rta->rta_len = RTA_LENGTH(4); 877 memcpy(RTA_DATA(rta), &ifindex, 4); 878 off += NLMSG_ALIGN(rta->rta_len); 879 } else if (!strcmp(argv[arg], "port")) { 880 u_int16_t port; 881 882 if (++arg >= argc) 883 error(1, 0, " missing port value"); 884 if (!(flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) 885 error(1, 0, " flags must be signal when using port"); 886 887 port = atoi(argv[arg]); 888 rta = (void *)(data + off); 889 rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT; 890 rta->rta_len = RTA_LENGTH(2); 891 memcpy(RTA_DATA(rta), &port, 2); 892 off += NLMSG_ALIGN(rta->rta_len); 893 } else 894 error(1, 0, "unknown keyword %s", argv[arg]); 895 } 896 nest->rta_len = off - nest_start; 897 898 do_nl_req(fd, nh, off, 0); 899 return 0; 900 } 901 902 int del_addr(int fd, int pm_family, int argc, char *argv[]) 903 { 904 char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 905 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 906 1024]; 907 struct rtattr *rta, *nest; 908 struct nlmsghdr *nh; 909 u_int16_t family; 910 int nest_start; 911 u_int8_t id; 912 int off = 0; 913 914 memset(data, 0, sizeof(data)); 915 nh = (void *)data; 916 off = init_genl_req(data, pm_family, MPTCP_PM_CMD_DEL_ADDR, 917 MPTCP_PM_VER); 918 919 /* the only argument is the address id (nonzero) */ 920 if (argc != 3 && argc != 4) 921 syntax(argv); 922 923 id = atoi(argv[2]); 924 /* zero id with the IP address */ 925 if (!id && argc != 4) 926 syntax(argv); 927 928 nest_start = off; 929 nest = (void *)(data + off); 930 nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR; 931 nest->rta_len = RTA_LENGTH(0); 932 off += NLMSG_ALIGN(nest->rta_len); 933 934 /* build a dummy addr with only the ID set */ 935 rta = (void *)(data + off); 936 rta->rta_type = MPTCP_PM_ADDR_ATTR_ID; 937 rta->rta_len = RTA_LENGTH(1); 938 memcpy(RTA_DATA(rta), &id, 1); 939 off += NLMSG_ALIGN(rta->rta_len); 940 941 if (!id) { 942 /* addr data */ 943 rta = (void *)(data + off); 944 if (inet_pton(AF_INET, argv[3], RTA_DATA(rta))) { 945 family = AF_INET; 946 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4; 947 rta->rta_len = RTA_LENGTH(4); 948 } else if (inet_pton(AF_INET6, argv[3], RTA_DATA(rta))) { 949 family = AF_INET6; 950 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6; 951 rta->rta_len = RTA_LENGTH(16); 952 } else { 953 error(1, errno, "can't parse ip %s", argv[3]); 954 } 955 off += NLMSG_ALIGN(rta->rta_len); 956 957 /* family */ 958 rta = (void *)(data + off); 959 rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY; 960 rta->rta_len = RTA_LENGTH(2); 961 memcpy(RTA_DATA(rta), &family, 2); 962 off += NLMSG_ALIGN(rta->rta_len); 963 } 964 nest->rta_len = off - nest_start; 965 966 do_nl_req(fd, nh, off, 0); 967 return 0; 968 } 969 970 static void print_addr(struct rtattr *attrs, int len) 971 { 972 uint16_t family = 0; 973 uint16_t port = 0; 974 char str[1024]; 975 uint32_t flags; 976 uint8_t id; 977 978 while (RTA_OK(attrs, len)) { 979 if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_FAMILY) 980 memcpy(&family, RTA_DATA(attrs), 2); 981 if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_PORT) 982 memcpy(&port, RTA_DATA(attrs), 2); 983 if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_ADDR4) { 984 if (family != AF_INET) 985 error(1, errno, "wrong IP (v4) for family %d", 986 family); 987 inet_ntop(AF_INET, RTA_DATA(attrs), str, sizeof(str)); 988 printf("%s", str); 989 if (port) 990 printf(" %d", port); 991 } 992 if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_ADDR6) { 993 if (family != AF_INET6) 994 error(1, errno, "wrong IP (v6) for family %d", 995 family); 996 inet_ntop(AF_INET6, RTA_DATA(attrs), str, sizeof(str)); 997 printf("%s", str); 998 if (port) 999 printf(" %d", port); 1000 } 1001 if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_ID) { 1002 memcpy(&id, RTA_DATA(attrs), 1); 1003 printf("id %d ", id); 1004 } 1005 if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_FLAGS) { 1006 memcpy(&flags, RTA_DATA(attrs), 4); 1007 1008 printf("flags "); 1009 if (flags & MPTCP_PM_ADDR_FLAG_SIGNAL) { 1010 printf("signal"); 1011 flags &= ~MPTCP_PM_ADDR_FLAG_SIGNAL; 1012 if (flags) 1013 printf(","); 1014 } 1015 1016 if (flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) { 1017 printf("subflow"); 1018 flags &= ~MPTCP_PM_ADDR_FLAG_SUBFLOW; 1019 if (flags) 1020 printf(","); 1021 } 1022 1023 if (flags & MPTCP_PM_ADDR_FLAG_LAMINAR) { 1024 printf("laminar"); 1025 flags &= ~MPTCP_PM_ADDR_FLAG_LAMINAR; 1026 if (flags) 1027 printf(","); 1028 } 1029 1030 if (flags & MPTCP_PM_ADDR_FLAG_BACKUP) { 1031 printf("backup"); 1032 flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP; 1033 if (flags) 1034 printf(","); 1035 } 1036 1037 if (flags & MPTCP_PM_ADDR_FLAG_FULLMESH) { 1038 printf("fullmesh"); 1039 flags &= ~MPTCP_PM_ADDR_FLAG_FULLMESH; 1040 if (flags) 1041 printf(","); 1042 } 1043 1044 if (flags & MPTCP_PM_ADDR_FLAG_IMPLICIT) { 1045 printf("implicit"); 1046 flags &= ~MPTCP_PM_ADDR_FLAG_IMPLICIT; 1047 if (flags) 1048 printf(","); 1049 } 1050 1051 /* bump unknown flags, if any */ 1052 if (flags) 1053 printf("0x%x", flags); 1054 printf(" "); 1055 } 1056 if (attrs->rta_type == MPTCP_PM_ADDR_ATTR_IF_IDX) { 1057 char name[IF_NAMESIZE], *ret; 1058 int32_t ifindex; 1059 1060 memcpy(&ifindex, RTA_DATA(attrs), 4); 1061 ret = if_indextoname(ifindex, name); 1062 if (ret) 1063 printf("dev %s ", ret); 1064 else 1065 printf("dev unknown/%d", ifindex); 1066 } 1067 1068 attrs = RTA_NEXT(attrs, len); 1069 } 1070 printf("\n"); 1071 } 1072 1073 static void print_addrs(struct nlmsghdr *nh, int pm_family, int total_len) 1074 { 1075 struct rtattr *attrs; 1076 1077 for (; NLMSG_OK(nh, total_len); nh = NLMSG_NEXT(nh, total_len)) { 1078 int len = nh->nlmsg_len; 1079 1080 if (nh->nlmsg_type == NLMSG_DONE) 1081 break; 1082 if (nh->nlmsg_type == NLMSG_ERROR) 1083 nl_error(nh); 1084 if (nh->nlmsg_type != pm_family) 1085 continue; 1086 1087 len -= NLMSG_LENGTH(GENL_HDRLEN); 1088 attrs = (struct rtattr *) ((char *) NLMSG_DATA(nh) + 1089 GENL_HDRLEN); 1090 while (RTA_OK(attrs, len)) { 1091 if (attrs->rta_type == 1092 (MPTCP_PM_ATTR_ADDR | NLA_F_NESTED)) 1093 print_addr((void *)RTA_DATA(attrs), 1094 attrs->rta_len); 1095 attrs = RTA_NEXT(attrs, len); 1096 } 1097 } 1098 } 1099 1100 int get_addr(int fd, int pm_family, int argc, char *argv[]) 1101 { 1102 char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 1103 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 1104 1024]; 1105 struct rtattr *rta, *nest; 1106 struct nlmsghdr *nh; 1107 u_int32_t token = 0; 1108 int nest_start; 1109 u_int8_t id; 1110 int off = 0; 1111 1112 memset(data, 0, sizeof(data)); 1113 nh = (void *)data; 1114 off = init_genl_req(data, pm_family, MPTCP_PM_CMD_GET_ADDR, 1115 MPTCP_PM_VER); 1116 1117 /* the only argument is the address id */ 1118 if (argc != 3 && argc != 5) 1119 syntax(argv); 1120 1121 id = atoi(argv[2]); 1122 if (argc == 5 && !strcmp(argv[3], "token")) 1123 token = strtoul(argv[4], NULL, 10); 1124 1125 nest_start = off; 1126 nest = (void *)(data + off); 1127 nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR; 1128 nest->rta_len = RTA_LENGTH(0); 1129 off += NLMSG_ALIGN(nest->rta_len); 1130 1131 /* build a dummy addr with only the ID set */ 1132 rta = (void *)(data + off); 1133 rta->rta_type = MPTCP_PM_ADDR_ATTR_ID; 1134 rta->rta_len = RTA_LENGTH(1); 1135 memcpy(RTA_DATA(rta), &id, 1); 1136 off += NLMSG_ALIGN(rta->rta_len); 1137 nest->rta_len = off - nest_start; 1138 1139 /* token */ 1140 if (token) { 1141 rta = (void *)(data + off); 1142 rta->rta_type = MPTCP_PM_ATTR_TOKEN; 1143 rta->rta_len = RTA_LENGTH(4); 1144 memcpy(RTA_DATA(rta), &token, 4); 1145 off += NLMSG_ALIGN(rta->rta_len); 1146 } 1147 1148 print_addrs(nh, pm_family, do_nl_req(fd, nh, off, sizeof(data))); 1149 return 0; 1150 } 1151 1152 int dump_addrs(int fd, int pm_family, int argc, char *argv[]) 1153 { 1154 char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 1155 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 1156 1024]; 1157 pid_t pid = getpid(); 1158 struct nlmsghdr *nh; 1159 u_int32_t token = 0; 1160 struct rtattr *rta; 1161 int off = 0; 1162 1163 if (argc != 2 && argc != 4) 1164 syntax(argv); 1165 1166 if (argc == 4 && !strcmp(argv[2], "token")) 1167 token = strtoul(argv[3], NULL, 10); 1168 1169 memset(data, 0, sizeof(data)); 1170 nh = (void *)data; 1171 off = init_genl_req(data, pm_family, MPTCP_PM_CMD_GET_ADDR, 1172 MPTCP_PM_VER); 1173 nh->nlmsg_flags |= NLM_F_DUMP; 1174 nh->nlmsg_seq = 1; 1175 nh->nlmsg_pid = pid; 1176 nh->nlmsg_len = off; 1177 1178 /* token */ 1179 if (token) { 1180 rta = (void *)(data + off); 1181 rta->rta_type = MPTCP_PM_ATTR_TOKEN; 1182 rta->rta_len = RTA_LENGTH(4); 1183 memcpy(RTA_DATA(rta), &token, 4); 1184 off += NLMSG_ALIGN(rta->rta_len); 1185 } 1186 1187 print_addrs(nh, pm_family, do_nl_req(fd, nh, off, sizeof(data))); 1188 return 0; 1189 } 1190 1191 int flush_addrs(int fd, int pm_family, int argc, char *argv[]) 1192 { 1193 char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 1194 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 1195 1024]; 1196 struct nlmsghdr *nh; 1197 int off = 0; 1198 1199 memset(data, 0, sizeof(data)); 1200 nh = (void *)data; 1201 off = init_genl_req(data, pm_family, MPTCP_PM_CMD_FLUSH_ADDRS, 1202 MPTCP_PM_VER); 1203 1204 do_nl_req(fd, nh, off, 0); 1205 return 0; 1206 } 1207 1208 static void print_limits(struct nlmsghdr *nh, int pm_family, int total_len) 1209 { 1210 struct rtattr *attrs; 1211 uint32_t max; 1212 1213 for (; NLMSG_OK(nh, total_len); nh = NLMSG_NEXT(nh, total_len)) { 1214 int len = nh->nlmsg_len; 1215 1216 if (nh->nlmsg_type == NLMSG_DONE) 1217 break; 1218 if (nh->nlmsg_type == NLMSG_ERROR) 1219 nl_error(nh); 1220 if (nh->nlmsg_type != pm_family) 1221 continue; 1222 1223 len -= NLMSG_LENGTH(GENL_HDRLEN); 1224 attrs = (struct rtattr *) ((char *) NLMSG_DATA(nh) + 1225 GENL_HDRLEN); 1226 while (RTA_OK(attrs, len)) { 1227 int type = attrs->rta_type; 1228 1229 if (type != MPTCP_PM_ATTR_RCV_ADD_ADDRS && 1230 type != MPTCP_PM_ATTR_SUBFLOWS) 1231 goto next; 1232 1233 memcpy(&max, RTA_DATA(attrs), 4); 1234 printf("%s %u\n", type == MPTCP_PM_ATTR_SUBFLOWS ? 1235 "subflows" : "accept", max); 1236 1237 next: 1238 attrs = RTA_NEXT(attrs, len); 1239 } 1240 } 1241 } 1242 1243 int get_set_limits(int fd, int pm_family, int argc, char *argv[]) 1244 { 1245 char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 1246 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 1247 1024]; 1248 uint32_t rcv_addr = 0, subflows = 0; 1249 int cmd, len = sizeof(data); 1250 struct nlmsghdr *nh; 1251 int off = 0; 1252 1253 /* limit */ 1254 if (argc == 4) { 1255 rcv_addr = atoi(argv[2]); 1256 subflows = atoi(argv[3]); 1257 cmd = MPTCP_PM_CMD_SET_LIMITS; 1258 } else { 1259 cmd = MPTCP_PM_CMD_GET_LIMITS; 1260 } 1261 1262 memset(data, 0, sizeof(data)); 1263 nh = (void *)data; 1264 off = init_genl_req(data, pm_family, cmd, MPTCP_PM_VER); 1265 1266 /* limit */ 1267 if (cmd == MPTCP_PM_CMD_SET_LIMITS) { 1268 struct rtattr *rta = (void *)(data + off); 1269 1270 rta->rta_type = MPTCP_PM_ATTR_RCV_ADD_ADDRS; 1271 rta->rta_len = RTA_LENGTH(4); 1272 memcpy(RTA_DATA(rta), &rcv_addr, 4); 1273 off += NLMSG_ALIGN(rta->rta_len); 1274 1275 rta = (void *)(data + off); 1276 rta->rta_type = MPTCP_PM_ATTR_SUBFLOWS; 1277 rta->rta_len = RTA_LENGTH(4); 1278 memcpy(RTA_DATA(rta), &subflows, 4); 1279 off += NLMSG_ALIGN(rta->rta_len); 1280 1281 /* do not expect a reply */ 1282 len = 0; 1283 } 1284 1285 len = do_nl_req(fd, nh, off, len); 1286 if (cmd == MPTCP_PM_CMD_GET_LIMITS) 1287 print_limits(nh, pm_family, len); 1288 return 0; 1289 } 1290 1291 int add_listener(int argc, char *argv[]) 1292 { 1293 struct sockaddr_storage addr; 1294 struct sockaddr_in6 *a6; 1295 struct sockaddr_in *a4; 1296 u_int16_t family = AF_UNSPEC; 1297 int enable = 1; 1298 int sock; 1299 int err; 1300 1301 if (argc < 4) 1302 syntax(argv); 1303 1304 memset(&addr, 0, sizeof(struct sockaddr_storage)); 1305 a4 = (struct sockaddr_in *)&addr; 1306 a6 = (struct sockaddr_in6 *)&addr; 1307 1308 if (inet_pton(AF_INET, argv[2], &a4->sin_addr)) { 1309 family = AF_INET; 1310 a4->sin_family = family; 1311 a4->sin_port = htons(atoi(argv[3])); 1312 } else if (inet_pton(AF_INET6, argv[2], &a6->sin6_addr)) { 1313 family = AF_INET6; 1314 a6->sin6_family = family; 1315 a6->sin6_port = htons(atoi(argv[3])); 1316 } else 1317 error(1, errno, "can't parse ip %s", argv[2]); 1318 1319 sock = socket(family, SOCK_STREAM, IPPROTO_MPTCP); 1320 if (sock < 0) 1321 error(1, errno, "can't create listener sock\n"); 1322 1323 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))) { 1324 close(sock); 1325 error(1, errno, "can't set SO_REUSEADDR on listener sock\n"); 1326 } 1327 1328 err = bind(sock, (struct sockaddr *)&addr, 1329 ((family == AF_INET) ? sizeof(struct sockaddr_in) : 1330 sizeof(struct sockaddr_in6))); 1331 1332 if (err == 0 && listen(sock, 30) == 0) 1333 pause(); 1334 1335 close(sock); 1336 return 0; 1337 } 1338 1339 int set_flags(int fd, int pm_family, int argc, char *argv[]) 1340 { 1341 char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + 1342 NLMSG_ALIGN(sizeof(struct genlmsghdr)) + 1343 1024]; 1344 struct rtattr *rta, *nest; 1345 struct nlmsghdr *nh; 1346 u_int32_t flags = 0; 1347 u_int32_t token = 0; 1348 u_int16_t rport = 0; 1349 u_int16_t family; 1350 void *rip = NULL; 1351 int nest_start; 1352 int use_id = 0; 1353 u_int8_t id; 1354 int off = 0; 1355 int arg = 2; 1356 1357 memset(data, 0, sizeof(data)); 1358 nh = (void *)data; 1359 off = init_genl_req(data, pm_family, MPTCP_PM_CMD_SET_FLAGS, 1360 MPTCP_PM_VER); 1361 1362 if (argc < 3) 1363 syntax(argv); 1364 1365 nest_start = off; 1366 nest = (void *)(data + off); 1367 nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR; 1368 nest->rta_len = RTA_LENGTH(0); 1369 off += NLMSG_ALIGN(nest->rta_len); 1370 1371 if (!strcmp(argv[arg], "id")) { 1372 if (++arg >= argc) 1373 error(1, 0, " missing id value"); 1374 1375 use_id = 1; 1376 id = atoi(argv[arg]); 1377 rta = (void *)(data + off); 1378 rta->rta_type = MPTCP_PM_ADDR_ATTR_ID; 1379 rta->rta_len = RTA_LENGTH(1); 1380 memcpy(RTA_DATA(rta), &id, 1); 1381 off += NLMSG_ALIGN(rta->rta_len); 1382 } else { 1383 /* addr data */ 1384 rta = (void *)(data + off); 1385 if (inet_pton(AF_INET, argv[arg], RTA_DATA(rta))) { 1386 family = AF_INET; 1387 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4; 1388 rta->rta_len = RTA_LENGTH(4); 1389 } else if (inet_pton(AF_INET6, argv[arg], RTA_DATA(rta))) { 1390 family = AF_INET6; 1391 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6; 1392 rta->rta_len = RTA_LENGTH(16); 1393 } else { 1394 error(1, errno, "can't parse ip %s", argv[arg]); 1395 } 1396 off += NLMSG_ALIGN(rta->rta_len); 1397 1398 /* family */ 1399 rta = (void *)(data + off); 1400 rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY; 1401 rta->rta_len = RTA_LENGTH(2); 1402 memcpy(RTA_DATA(rta), &family, 2); 1403 off += NLMSG_ALIGN(rta->rta_len); 1404 } 1405 1406 if (++arg >= argc) 1407 error(1, 0, " missing flags keyword"); 1408 1409 for (; arg < argc; arg++) { 1410 if (!strcmp(argv[arg], "token")) { 1411 if (++arg >= argc) 1412 error(1, 0, " missing token value"); 1413 1414 /* token */ 1415 token = strtoul(argv[arg], NULL, 10); 1416 } else if (!strcmp(argv[arg], "flags")) { 1417 char *tok, *str; 1418 1419 /* flags */ 1420 if (++arg >= argc) 1421 error(1, 0, " missing flags value"); 1422 1423 for (str = argv[arg]; (tok = strtok(str, ",")); 1424 str = NULL) { 1425 if (!strcmp(tok, "backup")) 1426 flags |= MPTCP_PM_ADDR_FLAG_BACKUP; 1427 else if (!strcmp(tok, "fullmesh")) 1428 flags |= MPTCP_PM_ADDR_FLAG_FULLMESH; 1429 else if (strcmp(tok, "nobackup") && 1430 strcmp(tok, "nofullmesh")) 1431 error(1, errno, 1432 "unknown flag %s", argv[arg]); 1433 } 1434 1435 rta = (void *)(data + off); 1436 rta->rta_type = MPTCP_PM_ADDR_ATTR_FLAGS; 1437 rta->rta_len = RTA_LENGTH(4); 1438 memcpy(RTA_DATA(rta), &flags, 4); 1439 off += NLMSG_ALIGN(rta->rta_len); 1440 } else if (!strcmp(argv[arg], "port")) { 1441 u_int16_t port; 1442 1443 if (use_id) 1444 error(1, 0, " port can't be used with id"); 1445 1446 if (++arg >= argc) 1447 error(1, 0, " missing port value"); 1448 1449 port = atoi(argv[arg]); 1450 rta = (void *)(data + off); 1451 rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT; 1452 rta->rta_len = RTA_LENGTH(2); 1453 memcpy(RTA_DATA(rta), &port, 2); 1454 off += NLMSG_ALIGN(rta->rta_len); 1455 } else if (!strcmp(argv[arg], "rport")) { 1456 if (++arg >= argc) 1457 error(1, 0, " missing remote port"); 1458 1459 rport = atoi(argv[arg]); 1460 } else if (!strcmp(argv[arg], "rip")) { 1461 if (++arg >= argc) 1462 error(1, 0, " missing remote ip"); 1463 1464 rip = argv[arg]; 1465 } else { 1466 error(1, 0, "unknown keyword %s", argv[arg]); 1467 } 1468 } 1469 nest->rta_len = off - nest_start; 1470 1471 /* token */ 1472 if (token) { 1473 rta = (void *)(data + off); 1474 rta->rta_type = MPTCP_PM_ATTR_TOKEN; 1475 rta->rta_len = RTA_LENGTH(4); 1476 memcpy(RTA_DATA(rta), &token, 4); 1477 off += NLMSG_ALIGN(rta->rta_len); 1478 } 1479 1480 /* remote addr/port */ 1481 if (rip) { 1482 nest_start = off; 1483 nest = (void *)(data + off); 1484 nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR_REMOTE; 1485 nest->rta_len = RTA_LENGTH(0); 1486 off += NLMSG_ALIGN(nest->rta_len); 1487 1488 /* addr data */ 1489 rta = (void *)(data + off); 1490 if (inet_pton(AF_INET, rip, RTA_DATA(rta))) { 1491 family = AF_INET; 1492 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4; 1493 rta->rta_len = RTA_LENGTH(4); 1494 } else if (inet_pton(AF_INET6, rip, RTA_DATA(rta))) { 1495 family = AF_INET6; 1496 rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6; 1497 rta->rta_len = RTA_LENGTH(16); 1498 } else { 1499 error(1, errno, "can't parse ip %s", (char *)rip); 1500 } 1501 off += NLMSG_ALIGN(rta->rta_len); 1502 1503 /* family */ 1504 rta = (void *)(data + off); 1505 rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY; 1506 rta->rta_len = RTA_LENGTH(2); 1507 memcpy(RTA_DATA(rta), &family, 2); 1508 off += NLMSG_ALIGN(rta->rta_len); 1509 1510 if (rport) { 1511 rta = (void *)(data + off); 1512 rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT; 1513 rta->rta_len = RTA_LENGTH(2); 1514 memcpy(RTA_DATA(rta), &rport, 2); 1515 off += NLMSG_ALIGN(rta->rta_len); 1516 } 1517 1518 nest->rta_len = off - nest_start; 1519 } 1520 1521 do_nl_req(fd, nh, off, 0); 1522 return 0; 1523 } 1524 1525 int main(int argc, char *argv[]) 1526 { 1527 int events_mcast_grp; 1528 int pm_family; 1529 int fd; 1530 1531 if (argc < 2) 1532 syntax(argv); 1533 1534 fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); 1535 if (fd == -1) 1536 error(1, errno, "socket netlink"); 1537 1538 resolve_mptcp_pm_netlink(fd, &pm_family, &events_mcast_grp); 1539 1540 if (!strcmp(argv[1], "add")) 1541 return add_addr(fd, pm_family, argc, argv); 1542 else if (!strcmp(argv[1], "ann")) 1543 return announce_addr(fd, pm_family, argc, argv); 1544 else if (!strcmp(argv[1], "rem")) 1545 return remove_addr(fd, pm_family, argc, argv); 1546 else if (!strcmp(argv[1], "csf")) 1547 return csf(fd, pm_family, argc, argv); 1548 else if (!strcmp(argv[1], "dsf")) 1549 return dsf(fd, pm_family, argc, argv); 1550 else if (!strcmp(argv[1], "del")) 1551 return del_addr(fd, pm_family, argc, argv); 1552 else if (!strcmp(argv[1], "flush")) 1553 return flush_addrs(fd, pm_family, argc, argv); 1554 else if (!strcmp(argv[1], "get")) 1555 return get_addr(fd, pm_family, argc, argv); 1556 else if (!strcmp(argv[1], "dump")) 1557 return dump_addrs(fd, pm_family, argc, argv); 1558 else if (!strcmp(argv[1], "limits")) 1559 return get_set_limits(fd, pm_family, argc, argv); 1560 else if (!strcmp(argv[1], "set")) 1561 return set_flags(fd, pm_family, argc, argv); 1562 else if (!strcmp(argv[1], "events")) 1563 return capture_events(fd, events_mcast_grp); 1564 else if (!strcmp(argv[1], "listen")) 1565 return add_listener(argc, argv); 1566 1567 fprintf(stderr, "unknown sub-command: %s", argv[1]); 1568 syntax(argv); 1569 return 0; 1570 } 1571