diff --git a/configure.ac b/configure.ac index 05d95a307a..42a9f97c88 100644 --- a/configure.ac +++ b/configure.ac @@ -254,7 +254,7 @@ AC_CHECK_HEADERS( \ sys/uio.h \ ) -AC_CHECK_HEADERS(netinet/ip.h netinet/ip6.h net/route.h,,,[[ +AC_CHECK_HEADERS(netinet/ip.h netinet/ip6.h netinet/ip_icmp.h net/route.h,,,[[ #include #if HAVE_SYS_SOCKET_H #include @@ -265,7 +265,17 @@ AC_CHECK_HEADERS(netinet/ip.h netinet/ip6.h net/route.h,,,[[ #endif ]]) -AC_CHECK_HEADERS(netinet/ip_icmp.h, [], [], [#include ]) +AC_CHECK_HEADERS(netinet/ip_icmp.h,,,[[ +#include +#if HAVE_SYS_SOCKET_H +#include +#endif +#include +#if HAVE_NETINET_IN_SYSTM_H +#include +#endif +#include +]]) ########################################## #### Checks for typedefs, structures, #### diff --git a/lib/core/include/core.h.in b/lib/core/include/core.h.in index a871827a50..755a840475 100644 --- a/lib/core/include/core.h.in +++ b/lib/core/include/core.h.in @@ -140,6 +140,10 @@ #include #endif +#if HAVE_NETINET_IP_ICMP_H +#include +#endif + #if HAVE_NETINET_UDP_H #include #endif diff --git a/test/attach_test.c b/test/attach_test.c index dfa3b88eff..da43626400 100644 --- a/test/attach_test.c +++ b/test/attach_test.c @@ -302,7 +302,10 @@ static void attach_test1(abts_case *tc, void *data) core_sleep(time_from_msec(300)); /* Send GTP-U ICMP Packet */ - rv = testgtpu_enb_send("45.45.0.2", "45.45.0.1"); + rv = testgtpu_build_ping(&sendbuf, "45.45.0.2", "45.45.0.1"); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = testgtpu_enb_send(sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); /* Receive GTP-U ICMP Packet */ recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); @@ -311,7 +314,9 @@ static void attach_test1(abts_case *tc, void *data) pkbuf_free(recvbuf); #if LINUX == 1 - rv = testgtpu_enb_send("cafe::2", "cafe::1"); + rv = testgtpu_build_ping(&sendbuf, "cafe::2", "cafe::1"); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = testgtpu_enb_send(sendbuf); ABTS_INT_EQUAL(tc, CORE_OK, rv); /* Receive GTP-U ICMP Packet */ diff --git a/test/testpacket.c b/test/testpacket.c index b7daaede18..504eaf51e4 100644 --- a/test/testpacket.c +++ b/test/testpacket.c @@ -154,67 +154,20 @@ static uint16_t in_cksum(uint16_t *addr, int len) return answer; } -status_t testgtpu_enb_send(const char *src_ip, const char *dst_ip) +status_t testgtpu_enb_send(pkbuf_t *sendbuf) { + status_t rv; sock_id sock = 0; hash_index_t *hi = NULL; mme_ue_t *mme_ue = NULL; mme_sess_t *sess = NULL; mme_bearer_t *bearer = NULL; - status_t rv; - pkbuf_t *pkbuf = NULL; - gtp_header_t *gtp_h = NULL; - ssize_t sent; - ipsubnet_t src_ipsub, dst_ipsub; c_sockaddr_t sgw; - struct ip *ip_h = NULL; - struct icmp_header_t { - c_int8_t type; - c_int8_t code; - c_int16_t checksum; - union - { - struct - { - c_int16_t id; - c_int16_t sequence; - } echo; /* echo datagram */ - u_int32_t gateway; /* gateway address */ - struct - { - c_int16_t __glibc_reserved; - c_int16_t mtu; - } frag; /* path mtu discovery */ - } un; - } *icmp_h = NULL; - - struct ip6_hdr *ip6_h = NULL; - struct icmp6_hdr - { - uint8_t icmp6_type; /* type field */ - uint8_t icmp6_code; /* code field */ - uint16_t icmp6_cksum; /* checksum field */ - union - { - uint32_t icmp6_un_data32[1]; /* type-specific field */ -#define icmp6_data16 icmp6_dataun.icmp6_un_data16 -#define icmp6_id icmp6_data16[0] /* echo request/reply */ -#define icmp6_seq icmp6_data16[1] /* echo request/reply */ - uint16_t icmp6_un_data16[2]; /* type-specific field */ - uint8_t icmp6_un_data8[4]; /* type-specific field */ - } icmp6_dataun; - } *icmp6_h = NULL; + ssize_t sent; if (test_only_control_plane) return 0; - d_assert(src_ip, return -1,); - d_assert(dst_ip, return -1,); - rv = core_ipsubnet(&src_ipsub, src_ip, NULL); - d_assert(rv == CORE_OK, return -1,); - rv = core_ipsubnet(&dst_ipsub, dst_ip, NULL); - d_assert(rv == CORE_OK, return -1,); - hi = mme_ue_first(); d_assert(hi, return -1,); mme_ue = mme_ue_this(hi); @@ -224,111 +177,6 @@ status_t testgtpu_enb_send(const char *src_ip, const char *dst_ip) bearer = mme_bearer_first(sess); d_assert(bearer, return -1,); - pkbuf = pkbuf_alloc(0, 200 /* enough for ICMP; use smaller buffer */); - d_assert(pkbuf, return CORE_ERROR,); - memset(pkbuf->payload, 0, pkbuf->len); - - gtp_h = (gtp_header_t *)pkbuf->payload; - gtp_h->flags = 0x30; - gtp_h->type = GTPU_MSGTYPE_GPDU; - gtp_h->teid = htonl(1); - - if (dst_ipsub.family == AF_INET) - { - gtp_h->length = htons(sizeof(struct ip) + sizeof(struct icmp_header_t)); - - ip_h = (struct ip *)(pkbuf->payload + GTPV1U_HEADER_LEN); - ip_h->ip_v = 4; - ip_h->ip_hl = 5; - ip_h->ip_tos = 0; - ip_h->ip_id = rand(); - ip_h->ip_off = 0; - ip_h->ip_ttl = 255; - ip_h->ip_p = IPPROTO_ICMP; - ip_h->ip_len = gtp_h->length; - ip_h->ip_src.s_addr = src_ipsub.sub[0]; - ip_h->ip_dst.s_addr = dst_ipsub.sub[0]; - ip_h->ip_sum = in_cksum( - (unsigned short *)ip_h, sizeof(struct ip)); - - icmp_h = (struct icmp_header_t *) - (pkbuf->payload + GTPV1U_HEADER_LEN + sizeof(struct ip)); - icmp_h->type = 8; - icmp_h->un.echo.sequence = rand(); - icmp_h->un.echo.id = rand(); - icmp_h->checksum = in_cksum( - (unsigned short *)icmp_h, sizeof(struct icmp_header_t)); - } - else if (dst_ipsub.family == AF_INET6) - { - char cksumbuf[200]; - char *ptr = NULL; - - int icmp6_datalen = 0; -#if 0 - int icmp6_datalen = 56; - char *icmp6_data = NULL; - char hexbuf[200]; - char *hexraw = - "9805325a 00000000 ea950900 00000000" - "10111213 14151617 18191a1b 1c1d1e1f" - "20212223 24252627 28292a2b 2c2d2e2f" - "30313233 34353637"; -#endif - - gtp_h->length = htons(sizeof(struct ip6_hdr) + - sizeof(struct icmp6_hdr) + icmp6_datalen); - - ip6_h = (struct ip6_hdr *)(pkbuf->payload + GTPV1U_HEADER_LEN); - ip6_h->ip6_flow = htonl(0x600d5a92); - ip6_h->ip6_plen = htons(sizeof(struct icmp6_hdr) + icmp6_datalen); - ip6_h->ip6_nxt = 58; /* ICMPv6 */ - ip6_h->ip6_hlim = 64; - memcpy(ip6_h->ip6_src.s6_addr, src_ipsub.sub, sizeof src_ipsub.sub); - memcpy(ip6_h->ip6_dst.s6_addr, dst_ipsub.sub, sizeof dst_ipsub.sub); - - icmp6_h = - (struct icmp6_hdr *)((c_uint8_t*)ip6_h + sizeof(struct ip6_hdr)); - icmp6_h->icmp6_type = 128; - icmp6_h->icmp6_code = 0; - icmp6_h->icmp6_seq = rand(); - icmp6_h->icmp6_id = rand(); - -#if 0 - icmp6_data = (char *)((c_uint8_t*)icmp6_h + sizeof(struct icmp6_hdr)); - memcpy(icmp6_data, - CORE_HEX(hexraw, strlen(hexraw), hexbuf), icmp6_datalen); -#endif - - /* create pseudo-header */ - memset(cksumbuf, 0, sizeof cksumbuf); - ptr = cksumbuf; - memcpy(ptr, src_ipsub.sub, sizeof src_ipsub.sub); - ptr += sizeof src_ipsub.sub; - memcpy(ptr, dst_ipsub.sub, sizeof dst_ipsub.sub); - ptr += sizeof dst_ipsub.sub; - - ptr += 2; - memcpy(ptr, &ip6_h->ip6_plen, 2); - ptr += 2; - - ptr += 3; - *ptr = ip6_h->ip6_nxt; - ptr += 1; - - memcpy(ptr, icmp6_h, sizeof(struct icmp6_hdr)); -#if 0 - ptr += sizeof(struct icmp6_hdr); - memcpy(ptr, icmp6_data, icmp6_datalen); -#endif - -#define IPV6_PSEUDO_HDR 48 - icmp6_h->icmp6_cksum = in_cksum((unsigned short *)cksumbuf, - IPV6_PSEUDO_HDR + sizeof(struct icmp6_hdr) + icmp6_datalen); - } - else - d_assert(0, return -1,); - memset(&sgw, 0, sizeof(c_sockaddr_t)); sgw.c_sa_port = htons(GTPV1_U_UDP_PORT); if (bearer->sgw_s1u_ip.ipv6) @@ -352,9 +200,9 @@ status_t testgtpu_enb_send(const char *src_ip, const char *dst_ip) rv = udp_client(&sock, &sgw); d_assert(rv == CORE_OK, return CORE_ERROR,); - sent = core_send(sock, pkbuf->payload, pkbuf->len, 0); - pkbuf_free(pkbuf); - if (sent < 0 || sent != pkbuf->len) + sent = core_send(sock, sendbuf->payload, sendbuf->len, 0); + pkbuf_free(sendbuf); + if (sent < 0 || sent != sendbuf->len) return CORE_ERROR; sock_delete(sock); @@ -362,6 +210,137 @@ status_t testgtpu_enb_send(const char *src_ip, const char *dst_ip) return CORE_OK; } +status_t testgtpu_build_ping( + pkbuf_t **sendbuf, const char *src_ip, const char *dst_ip) +{ + status_t rv; + pkbuf_t *pkbuf = NULL; + gtp_header_t *gtp_h = NULL; + ipsubnet_t src_ipsub, dst_ipsub; + struct ip *ip_h = NULL; + struct icmphdr *icmp_h = NULL; + + struct ip6_hdr *ip6_h = NULL; + struct icmphdr *icmp6_h = NULL; + + if (test_only_control_plane) return CORE_OK; + + d_assert(src_ip, return CORE_ERROR,); + d_assert(dst_ip, return CORE_ERROR,); + rv = core_ipsubnet(&src_ipsub, src_ip, NULL); + d_assert(rv == CORE_OK, return CORE_ERROR,); + rv = core_ipsubnet(&dst_ipsub, dst_ip, NULL); + d_assert(rv == CORE_OK, return CORE_ERROR,); + + pkbuf = pkbuf_alloc(0, 200 /* enough for ICMP; use smaller buffer */); + d_assert(pkbuf, return CORE_ERROR,); + memset(pkbuf->payload, 0, pkbuf->len); + + gtp_h = (gtp_header_t *)pkbuf->payload; + gtp_h->flags = 0x30; + gtp_h->type = GTPU_MSGTYPE_GPDU; + gtp_h->teid = htonl(1); + + if (dst_ipsub.family == AF_INET) + { + gtp_h->length = htons(sizeof(struct ip) + sizeof(struct icmphdr)); + + ip_h = (struct ip *)(pkbuf->payload + GTPV1U_HEADER_LEN); + ip_h->ip_v = 4; + ip_h->ip_hl = 5; + ip_h->ip_tos = 0; + ip_h->ip_id = rand(); + ip_h->ip_off = 0; + ip_h->ip_ttl = 255; + ip_h->ip_p = IPPROTO_ICMP; + ip_h->ip_len = gtp_h->length; + ip_h->ip_src.s_addr = src_ipsub.sub[0]; + ip_h->ip_dst.s_addr = dst_ipsub.sub[0]; + ip_h->ip_sum = in_cksum( + (unsigned short *)ip_h, sizeof(struct ip)); + + icmp_h = (struct icmphdr *) + (pkbuf->payload + GTPV1U_HEADER_LEN + sizeof(struct ip)); + icmp_h->type = 8; + icmp_h->un.echo.sequence = rand(); + icmp_h->un.echo.id = rand(); + icmp_h->checksum = in_cksum( + (unsigned short *)icmp_h, sizeof(struct icmphdr)); + } + else if (dst_ipsub.family == AF_INET6) + { + char cksumbuf[200]; + char *ptr = NULL; + + int icmp6_datalen = 0; +#if 0 + int icmp6_datalen = 56; + char *icmp6_data = NULL; + char hexbuf[200]; + char *hexraw = + "9805325a 00000000 ea950900 00000000" + "10111213 14151617 18191a1b 1c1d1e1f" + "20212223 24252627 28292a2b 2c2d2e2f" + "30313233 34353637"; +#endif + + gtp_h->length = htons(sizeof(struct ip6_hdr) + + sizeof(struct icmphdr) + icmp6_datalen); + + ip6_h = (struct ip6_hdr *)(pkbuf->payload + GTPV1U_HEADER_LEN); + ip6_h->ip6_flow = htonl(0x600d5a92); + ip6_h->ip6_plen = htons(sizeof(struct icmphdr) + icmp6_datalen); + ip6_h->ip6_nxt = 58; /* ICMPv6 */ + ip6_h->ip6_hlim = 64; + memcpy(ip6_h->ip6_src.s6_addr, src_ipsub.sub, sizeof src_ipsub.sub); + memcpy(ip6_h->ip6_dst.s6_addr, dst_ipsub.sub, sizeof dst_ipsub.sub); + + icmp6_h = + (struct icmphdr *)((c_uint8_t*)ip6_h + sizeof(struct ip6_hdr)); + icmp6_h->type = 128; + icmp6_h->un.echo.sequence = rand(); + icmp6_h->un.echo.id = rand(); + +#if 0 + icmp6_data = (char *)((c_uint8_t*)icmp6_h + sizeof(struct icmphdr)); + memcpy(icmp6_data, + CORE_HEX(hexraw, strlen(hexraw), hexbuf), icmp6_datalen); +#endif + + /* create pseudo-header */ + memset(cksumbuf, 0, sizeof cksumbuf); + ptr = cksumbuf; + memcpy(ptr, src_ipsub.sub, sizeof src_ipsub.sub); + ptr += sizeof src_ipsub.sub; + memcpy(ptr, dst_ipsub.sub, sizeof dst_ipsub.sub); + ptr += sizeof dst_ipsub.sub; + + ptr += 2; + memcpy(ptr, &ip6_h->ip6_plen, 2); + ptr += 2; + + ptr += 3; + *ptr = ip6_h->ip6_nxt; + ptr += 1; + + memcpy(ptr, icmp6_h, sizeof(struct icmphdr)); +#if 0 + ptr += sizeof(struct icmphdr); + memcpy(ptr, icmp6_data, icmp6_datalen); +#endif + +#define IPV6_PSEUDO_HDR 48 + icmp6_h->checksum = in_cksum((unsigned short *)cksumbuf, + IPV6_PSEUDO_HDR + sizeof(struct icmphdr) + icmp6_datalen); + } + else + d_assert(0, return CORE_ERROR,); + + *sendbuf = pkbuf; + + return CORE_OK; +} + status_t testgtpu_enb_read(sock_id sock, pkbuf_t *recvbuf) { int rc = 0; diff --git a/test/testpacket.h b/test/testpacket.h index 2695027eda..669ed5b794 100644 --- a/test/testpacket.h +++ b/test/testpacket.h @@ -21,7 +21,8 @@ CORE_DECLARE(status_t) tests1ap_enb_read(sock_id id, pkbuf_t *recvbuf); CORE_DECLARE(status_t) testgtpu_enb_connect(sock_id *new); CORE_DECLARE(status_t) testgtpu_enb_close(sock_id sock); CORE_DECLARE(status_t) testgtpu_enb_read(sock_id sock, pkbuf_t *recvbuf); -CORE_DECLARE(status_t) testgtpu_enb_send( +CORE_DECLARE(status_t) testgtpu_enb_send(pkbuf_t *sendbuf); +CORE_DECLARE(status_t) testgtpu_build_ping(pkbuf_t **sendbuf, const char *src_ip, const char *dst_ip); CORE_DECLARE(status_t) tests1ap_build_setup_req( diff --git a/test/volte_test.c b/test/volte_test.c index c23c66e8e2..f1778500c7 100644 --- a/test/volte_test.c +++ b/test/volte_test.c @@ -552,10 +552,11 @@ static void volte_test2(abts_case *tc, void *data) /* Send GTP-U ICMP Packet */ #if 1 - rv = testgtpu_enb_send("45.45.0.2", "45.45.0.1"); + rv = testgtpu_build_ping(&sendbuf, "45.45.0.2", "45.45.0.1"); #else - rv = testgtpu_enb_send("cafe::2", "cafe::1"); + rv = testgtpu_build_ping(&sendbuf, "cafe::2", "cafe::1"); #endif + rv = testgtpu_enb_send(sendbuf); core_sleep(time_from_msec(300)); #endif @@ -580,9 +581,7 @@ abts_suite *test_volte(abts_suite *suite) { suite = ADD_SUITE(suite) -#if 0 abts_run_test(suite, volte_test1, NULL); -#endif abts_run_test(suite, volte_test2, NULL); return suite;