ctdb-tests: Add tests for ARP and IPv6 NA marshalling
authorMartin Schwenke <martin@meltin.net>
Thu, 16 Aug 2018 05:15:55 +0000 (15:15 +1000)
committerAmitay Isaacs <amitay@samba.org>
Thu, 30 Aug 2018 02:48:57 +0000 (04:48 +0200)
Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/tests/cunit/system_socket_test_001.sh
ctdb/tests/src/system_socket_test.c

index 389cec6ac8cb54d5e53f4da7c27a7f9fbe025c40..e2badea257a7513f6f1a70e3259436d17e04c17c 100755 (executable)
@@ -2,5 +2,65 @@
 
 . "${TEST_SCRIPTS_DIR}/unit.sh"
 
+out_file="${TEST_VAR_DIR}/cunit/packet.out"
+
+remove_file ()
+{
+       rm -f "$out_file"
+}
+
+test_cleanup remove_file
+
+d=$(dirname "$out_file")
+mkdir -p "$d"
+
+########################################
+
 ok_null
 unit_test system_socket_test types
+
+arp_run ()
+{
+       $VALGRIND system_socket_test arp "$@" >"$out_file" || exit $?
+       od -A x -t x1 "$out_file"
+}
+
+arp_test ()
+{
+       os=$(uname)
+       if [ "$os" = "Linux" ] ; then
+               unit_test_notrace arp_run "$@"
+       else
+               ok "PACKETSOCKET not supported"
+               unit_test system_socket_test arp "$@"
+       fi
+}
+
+ok <<EOF
+000000 ff ff ff ff ff ff 12 34 56 78 9a bc 08 06 00 01
+000010 08 00 06 04 00 01 12 34 56 78 9a bc c0 a8 01 19
+000020 00 00 00 00 00 00 c0 a8 01 19 00 00 00 00 00 00
+000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+000040
+EOF
+arp_test "192.168.1.25" "12:34:56:78:9a:bc"
+
+ok <<EOF
+000000 ff ff ff ff ff ff 12 34 56 78 9a bc 08 06 00 01
+000010 08 00 06 04 00 02 12 34 56 78 9a bc c0 a8 01 19
+000020 12 34 56 78 9a bc c0 a8 01 19 00 00 00 00 00 00
+000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+000040
+EOF
+arp_test "192.168.1.25" "12:34:56:78:9a:bc" reply
+
+ok <<EOF
+000000 33 33 00 00 00 01 12 34 56 78 9a bc 86 dd 60 00
+000010 00 00 00 20 3a ff fe 80 00 00 00 00 00 00 6a f7
+000020 28 ff fe fa d1 36 ff 02 00 00 00 00 00 00 00 00
+000030 00 00 00 00 00 01 88 00 8d e4 20 00 00 00 fe 80
+000040 00 00 00 00 00 00 6a f7 28 ff fe fa d1 36 02 01
+000050 12 34 56 78 9a bc
+000056
+EOF
+arp_test "fe80::6af7:28ff:fefa:d136" "12:34:56:78:9a:bc"
index 61dfa3970c17f6f3f841c979f43e668ad73c1e28..23a1a3b26c585bab41b7c1ec9c0c090a4d796d8d 100644 (file)
    along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
+#include "replace.h"
+
 #include <assert.h>
 
+/* For ether_aton() */
+#ifdef _AIX
+#include <arpa/inet.h>
+#endif
+#ifdef __FreeBSD__
+#include <net/ethernet.h>
+#endif
+#ifdef linux
+#include <netinet/ether.h>
+#endif
+
 #include "common/system_socket.c"
 
 #include "protocol/protocol_util.h"
@@ -37,11 +50,54 @@ static void test_types(void)
        assert(sizeof(ip4pkt) == sizeof(struct ip) + sizeof(struct tcphdr));
 }
 
+#ifdef HAVE_PACKETSOCKET
+
+static void test_arp(const char *addr_str, const char *hwaddr_str, bool reply)
+{
+       ctdb_sock_addr addr;
+       struct ether_addr *hw, *dhw;
+       uint8_t buf[512];
+       size_t buflen = sizeof(buf);
+       size_t len;
+       int ret;
+
+       ret = ctdb_sock_addr_from_string(addr_str, &addr, false);
+       assert(ret == 0);
+
+       hw = ether_aton(hwaddr_str);
+       assert(hw != NULL);
+
+       switch (addr.ip.sin_family) {
+       case AF_INET:
+               ret = arp_build(buf, buflen, &addr.ip, hw, reply, &dhw, &len);
+               break;
+       case AF_INET6:
+               ret = ip6_na_build(buf, buflen, &addr.ip6, hw, &dhw, &len);
+               break;
+       default:
+               abort();
+       }
+
+       assert(ret == 0);
+
+       write(STDOUT_FILENO, buf, len);
+}
+
+#else /* HAVE_PACKETSOCKET  */
+
+static void test_arp(const char *addr_str, const char *hwaddr_str, bool reply)
+{
+       fprintf(stderr, "PACKETSOCKET not supported\n");
+}
+
+#endif /* HAVE_PACKETSOCKET */
+
 static void usage(const char *prog)
 {
        fprintf(stderr, "usage: %s <cmd> [<arg> ...]\n", prog);
        fprintf(stderr, "  commands:\n");
        fprintf(stderr, "    types\n");
+       fprintf(stderr, "    arp <ipaddr> <hwaddr> [reply]\n");
 
        exit(1);
 }
@@ -55,6 +111,15 @@ int main(int argc, char **argv)
 
        if (strcmp(argv[1], "types") == 0) {
                test_types();
+       } else if (strcmp(argv[1], "arp") == 0) {
+               /*
+                * Extra arg indicates that a reply should be
+                * constructed for IPv4 - value is ignored
+                */
+               if (argc != 4 && argc != 5) {
+                       usage(argv[0]);
+               }
+               test_arp(argv[2], argv[3], (argc == 5));
        } else {
                usage(argv[0]);
        }