pm_nl_ctl.c 41 KB

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