Home | History | Annotate | Download | only in tests-m32
      1 /*
      2  * Copyright (c) 2015-2016 Dmitry V. Levin <ldv (at) altlinux.org>
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. The name of the author may not be used to endorse or promote products
     14  *    derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include "tests.h"
     29 #include <netinet/in.h>
     30 
     31 #if defined IP_ADD_MEMBERSHIP && defined IPV6_ADD_MEMBERSHIP \
     32  && defined IPV6_JOIN_ANYCAST && defined HAVE_IF_INDEXTONAME
     33 
     34 # include <stdio.h>
     35 # include <unistd.h>
     36 # include <sys/socket.h>
     37 # include <arpa/inet.h>
     38 # include <net/if.h>
     39 
     40 int
     41 main(void)
     42 {
     43 	static const char multi4addr[] = "224.0.0.3";
     44 	static const char multi6addr[] = "ff01::c";
     45 	static const char interface[] = "127.0.0.1";
     46 
     47 	struct ip_mreq *const m4 = tail_alloc(sizeof(*m4));
     48 	struct ipv6_mreq *const m6 = tail_alloc(sizeof(*m6));
     49 	unsigned int i;
     50 	int rc;
     51 
     52 	inet_pton(AF_INET, multi4addr, &m4->imr_multiaddr);
     53 	inet_pton(AF_INET, interface, &m4->imr_interface);
     54 	inet_pton(AF_INET6, multi6addr, &m6->ipv6mr_multiaddr);
     55 
     56 	m6->ipv6mr_interface = if_nametoindex("lo");
     57 	if (!m6->ipv6mr_interface)
     58 		perror_msg_and_skip("lo");
     59 
     60 	(void) close(0);
     61 	if (socket(AF_INET, SOCK_DGRAM, 0))
     62 		perror_msg_and_skip("socket");
     63 
     64 	struct {
     65 		int level;
     66 		const char *str_level;
     67 		int optname;
     68 		const char *str_optname;
     69 		void *optval;
     70 		unsigned int optsize;
     71 	} short_any[] = {
     72 		{
     73 			ARG_STR(SOL_IP), ARG_STR(IP_ADD_MEMBERSHIP),
     74 			m4, sizeof(*m4)
     75 		},
     76 		{
     77 			ARG_STR(SOL_IP), ARG_STR(IP_DROP_MEMBERSHIP),
     78 			m4, sizeof(*m4)
     79 		},
     80 		{
     81 			ARG_STR(SOL_IPV6), ARG_STR(IPV6_ADD_MEMBERSHIP),
     82 			m6, sizeof(*m6)
     83 		},
     84 		{
     85 			ARG_STR(SOL_IPV6), ARG_STR(IPV6_DROP_MEMBERSHIP),
     86 			m6, sizeof(*m6)
     87 		},
     88 		{
     89 			ARG_STR(SOL_IPV6), ARG_STR(IPV6_JOIN_ANYCAST),
     90 			m6, sizeof(*m6)
     91 		},
     92 		{
     93 			ARG_STR(SOL_IPV6), ARG_STR(IPV6_LEAVE_ANYCAST),
     94 			m6, sizeof(*m6)
     95 		}
     96 	};
     97 
     98 	for (i = 0; i < ARRAY_SIZE(short_any); ++i) {
     99 		rc = setsockopt(0, short_any[i].level, short_any[i].optname,
    100 				short_any[i].optval, 1);
    101 		printf("setsockopt(0, %s, %s, \"\\%hho\", 1) = %s\n",
    102 		       short_any[i].str_level, short_any[i].str_optname,
    103 		       * (unsigned char *) short_any[i].optval,
    104 		       sprintrc(rc));
    105 
    106 		rc = setsockopt(0, short_any[i].level, short_any[i].optname,
    107 				short_any[i].optval + 1, short_any[i].optsize);
    108 		printf("setsockopt(0, %s, %s, %p, %u) = %s\n",
    109 		       short_any[i].str_level, short_any[i].str_optname,
    110 		       short_any[i].optval + 1, short_any[i].optsize,
    111 		       sprintrc(rc));
    112 	}
    113 
    114 	struct {
    115 		int optname;
    116 		const char *str_optname;
    117 	} long_ip[] = {
    118 		{ ARG_STR(IP_ADD_MEMBERSHIP) },
    119 		{ ARG_STR(IP_DROP_MEMBERSHIP) }
    120 	}, long_ipv6[] = {
    121 		{ ARG_STR(IPV6_ADD_MEMBERSHIP) },
    122 		{ ARG_STR(IPV6_DROP_MEMBERSHIP) },
    123 		{ ARG_STR(IPV6_JOIN_ANYCAST) },
    124 		{ ARG_STR(IPV6_LEAVE_ANYCAST) }
    125 	};
    126 
    127 	for (i = 0; i < ARRAY_SIZE(long_ip); ++i) {
    128 		rc = setsockopt(0, SOL_IP, long_ip[i].optname,
    129 				m4, sizeof(*m4));
    130 		printf("setsockopt(0, SOL_IP, %s"
    131 		       ", {imr_multiaddr=inet_addr(\"%s\")"
    132 		       ", imr_interface=inet_addr(\"%s\")}, %u) = %s\n",
    133 		       long_ip[i].str_optname, multi4addr,
    134 		       interface, (unsigned) sizeof(*m4), sprintrc(rc));
    135 	}
    136 
    137 	for (i = 0; i < ARRAY_SIZE(long_ipv6); ++i) {
    138 		rc = setsockopt(0, SOL_IPV6, long_ipv6[i].optname,
    139 				m6, sizeof(*m6));
    140 		printf("setsockopt(0, SOL_IPV6, %s"
    141 		       ", {ipv6mr_multiaddr=inet_pton(\"%s\")"
    142 		       ", ipv6mr_interface=if_nametoindex(\"lo\")}"
    143 		       ", %u) = %s\n",
    144 		       long_ipv6[i].str_optname, multi6addr,
    145 		       (unsigned) sizeof(*m6), sprintrc(rc));
    146 	}
    147 
    148 	puts("+++ exited with 0 +++");
    149 	return 0;
    150 }
    151 
    152 #else
    153 
    154 SKIP_MAIN_UNDEFINED("IP_ADD_MEMBERSHIP && IPV6_ADD_MEMBERSHIP"
    155 		    " && IPV6_JOIN_ANYCAST && HAVE_IF_INDEXTONAME")
    156 
    157 #endif
    158