diff options
Diffstat (limited to 'tools/testing/selftests/net/mptcp/pm_nl_ctl.c')
-rw-r--r-- | tools/testing/selftests/net/mptcp/pm_nl_ctl.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c index f881d8548153..6a2f4b981e1d 100644 --- a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c +++ b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c @@ -25,6 +25,9 @@ #ifndef MPTCP_PM_EVENTS #define MPTCP_PM_EVENTS "mptcp_pm_events" #endif +#ifndef IPPROTO_MPTCP +#define IPPROTO_MPTCP 262 +#endif static void syntax(char *argv[]) { @@ -41,6 +44,7 @@ static void syntax(char *argv[]) fprintf(stderr, "\tdump\n"); fprintf(stderr, "\tlimits [<rcv addr max> <subflow max>]\n"); fprintf(stderr, "\tevents\n"); + fprintf(stderr, "\tlisten <local-ip> <local-port>\n"); exit(0); } @@ -1219,6 +1223,54 @@ int get_set_limits(int fd, int pm_family, int argc, char *argv[]) return 0; } +int add_listener(int argc, char *argv[]) +{ + struct sockaddr_storage addr; + struct sockaddr_in6 *a6; + struct sockaddr_in *a4; + u_int16_t family; + int enable = 1; + int sock; + int err; + + if (argc < 4) + syntax(argv); + + memset(&addr, 0, sizeof(struct sockaddr_storage)); + a4 = (struct sockaddr_in *)&addr; + a6 = (struct sockaddr_in6 *)&addr; + + if (inet_pton(AF_INET, argv[2], &a4->sin_addr)) { + family = AF_INET; + a4->sin_family = family; + a4->sin_port = htons(atoi(argv[3])); + } else if (inet_pton(AF_INET6, argv[2], &a6->sin6_addr)) { + family = AF_INET6; + a6->sin6_family = family; + a6->sin6_port = htons(atoi(argv[3])); + } else + error(1, errno, "can't parse ip %s", argv[2]); + + sock = socket(family, SOCK_STREAM, IPPROTO_MPTCP); + if (sock < 0) + error(1, errno, "can't create listener sock\n"); + + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))) { + close(sock); + error(1, errno, "can't set SO_REUSEADDR on listener sock\n"); + } + + err = bind(sock, (struct sockaddr *)&addr, + ((family == AF_INET) ? sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6))); + + if (err == 0 && listen(sock, 30) == 0) + pause(); + + close(sock); + return 0; +} + int set_flags(int fd, int pm_family, int argc, char *argv[]) { char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + @@ -1375,6 +1427,8 @@ int main(int argc, char *argv[]) return set_flags(fd, pm_family, argc, argv); else if (!strcmp(argv[1], "events")) return capture_events(fd, events_mcast_grp); + else if (!strcmp(argv[1], "listen")) + return add_listener(argc, argv); fprintf(stderr, "unknown sub-command: %s", argv[1]); syntax(argv); |