pm_nl_ctl.c 40 KB

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