From 22efa8c36a787a507766d3167359678227de13d6 Mon Sep 17 00:00:00 2001 From: hoelscher <jens.hoelscher@fh-muenster.de> Date: Thu, 26 Nov 2015 16:14:54 +0100 Subject: [PATCH] add support for sctp_freeladdrs and sctp_getladdrs --- gtests/net/packetdrill/run_system_call.c | 109 ++++++++++++++++-- .../tests/bsd/sctp/sctp_active_x.pkt | 6 + 2 files changed, 104 insertions(+), 11 deletions(-) diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index f87dd2c1..b25215d9 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -5020,7 +5020,7 @@ static int syscall_sctp_peeloff(struct state *state, struct syscall_spec *syscal static int syscall_sctp_getpaddrs(struct state *state, struct syscall_spec *syscall, struct expression_list *args, - char **error) + char **error) { #if defined(__FreeBSD__) || defined(linux) int live_fd, script_fd, result; @@ -5103,6 +5103,91 @@ static int syscall_sctp_freepaddrs(struct state *state, struct syscall_spec *sys #endif } +static int syscall_sctp_getladdrs(struct state *state, struct syscall_spec *syscall, + struct expression_list *args, + char **error) +{ +#if defined(__FreeBSD__) || defined(linux) + int live_fd, script_fd, result; + sctp_assoc_t assoc_id; + struct expression *assoc_expr, *addrs_list_expr; + struct sockaddr *live_addrs; + + if (check_arg_count(args, 3, error)) + return STATUS_ERR; + if (s32_arg(args, 0, &script_fd, error)) + return STATUS_ERR; + if (to_live_fd(state, script_fd, &live_fd, error)) + return STATUS_ERR; + assoc_expr = get_arg(args, 1, error); + if (get_u32(assoc_expr, (u32 *)&assoc_id, error)) + return STATUS_ERR; + + begin_syscall(state, syscall); + + result = sctp_getladdrs(live_fd, assoc_id, &live_addrs); + + if (end_syscall(state, syscall, CHECK_EXACT, result, error)) + goto error_out; + addrs_list_expr = get_arg(args, 2, error); + if (addrs_list_expr->type != EXPR_ELLIPSIS) { + int list_length = 0, i = 0; + struct sockaddr *live_addr = live_addrs; + if (check_type(addrs_list_expr, EXPR_LIST, error)) { + goto error_out; + } + list_length = get_arg_count(addrs_list_expr->value.list); + if (list_length != result) { + asprintf(error, "Bad length of struct sockaddr array. expected: %d, actual %d", list_length, result); + goto error_out; + } + for (i = 0; i < result; i++) { + struct expression *script_addr_expr; + script_addr_expr = get_arg(addrs_list_expr->value.list, i, error); + if (check_sockaddr(script_addr_expr, live_addr, error)) { + goto error_out; + } + if (live_addr->sa_family == AF_INET) { + live_addr = (struct sockaddr *)((caddr_t*)live_addr) + sizeof(struct sockaddr_in); + } else if (live_addr->sa_family == AF_INET6) { + live_addr = (struct sockaddr *)((caddr_t*)live_addr) + sizeof(struct sockaddr_in6); + } else { + asprintf(error, "Bad Type of addrs[%d]", i); + goto error_out; + } + } + } + return STATUS_OK; +error_out: + sctp_freeladdrs(live_addrs); + return STATUS_ERR; +#else + asprintf(error, "sctp_getladdrs is not supported"); + return STATUS_ERR; +#endif +} + +static int syscall_sctp_freeladdrs(struct state *state, struct syscall_spec *syscall, + struct expression_list *args, + char **error) +{ +#if defined(__FreeBSD__) || defined(linux) + struct expression *addrs_expr; + if (check_arg_count(args, 1, error)) + return STATUS_ERR; + addrs_expr = get_arg(args, 0, error); + if (check_type(addrs_expr, EXPR_LIST, error)) + return STATUS_ERR; + if (ellipsis_arg(addrs_expr->value.list, 0, error)) + return STATUS_ERR; + + return STATUS_OK; +#else + asprintf(error, "sctp_freeladdrs is not supported"); + return STATUS_ERR; +#endif +} + /* A dispatch table with all the system calls that we support... */ @@ -5137,17 +5222,19 @@ struct system_call_entry system_call_table[] = { {"getsockopt", syscall_getsockopt}, {"setsockopt", syscall_setsockopt}, {"poll", syscall_poll}, - {"sctp_send", syscall_sctp_send}, - {"sctp_sendx", syscall_sctp_sendx}, - {"sctp_sendmsg", syscall_sctp_sendmsg}, - {"sctp_recvmsg", syscall_sctp_recvmsg}, - {"sctp_sendv", syscall_sctp_sendv}, - {"sctp_recvv", syscall_sctp_recvv}, - {"sctp_bindx", syscall_sctp_bindx}, - {"sctp_connectx", syscall_sctp_connectx}, - {"sctp_peeloff", syscall_sctp_peeloff}, + {"sctp_bindx", syscall_sctp_bindx}, + {"sctp_peeloff", syscall_sctp_peeloff}, + {"sctp_getpaddrs", syscall_sctp_getpaddrs}, {"sctp_freepaddrs",syscall_sctp_freepaddrs}, - {"sctp_getpaddrs",syscall_sctp_getpaddrs} + {"sctp_getladdrs", syscall_sctp_getladdrs}, + {"sctp_freeladdrs",syscall_sctp_freeladdrs}, + {"sctp_sendmsg", syscall_sctp_sendmsg}, + {"sctp_recvmsg", syscall_sctp_recvmsg}, + {"sctp_connectx", syscall_sctp_connectx}, + {"sctp_send", syscall_sctp_send}, + {"sctp_sendx", syscall_sctp_sendx}, + {"sctp_sendv", syscall_sctp_sendv}, + {"sctp_recvv", syscall_sctp_recvv} }; /* Evaluate the system call arguments and invoke the system call. */ diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_active_x.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_active_x.pkt index 93595426..9424a9b6 100644 --- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_active_x.pkt +++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_active_x.pkt @@ -18,6 +18,12 @@ +0.0 sctp_getpaddrs(3, 3, [{sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")}]) = 1 +0.0 sctp_freepaddrs([...]) = 0 ++0.0 sctp_getladdrs(3, 3, [...]) = 1 ++0.0 sctp_freeladdrs([...]) = 0 + ++0.0 sctp_getladdrs(3, 3, [{sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.168.0.1")}]) = 1 ++0.0 sctp_freeladdrs([...]) = 0 + +0.0 sctp_sendmsg(3, ..., 1000, ..., ..., htonl(1234), SCTP_UNORDERED, 1, 0, 0) = 1000 * > sctp: DATA[flgs=UBE, len=1016, tsn=1, sid=1, ssn=0, ppid=1234] +0.0 < sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=1500, gaps=[], dups=[]] -- GitLab