1/* 2 * $Id: socket.c,v 1.7 2005/10/18 19:17:29 lutchann Exp $ 3 * 4 * Authors: 5 * Pedro Roque <roque@di.fc.ul.pt> 6 * Lars Fenneberg <lf@elemental.net> 7 * 8 * This software is Copyright 1996,1997 by the above mentioned author(s), 9 * All Rights Reserved. 10 * 11 * The license which is distributed with this software in the file COPYRIGHT 12 * applies to this software. If your distribution is missing this file, you 13 * may request it from <pekkas@netcore.fi>. 14 * 15 */ 16 17#include <config.h> 18#include <includes.h> 19#include <radvd.h> 20 21/* Note: these are applicable to receiving sockopts only */ 22#if defined IPV6_HOPLIMIT && !defined IPV6_RECVHOPLIMIT 23# define IPV6_RECVHOPLIMIT IPV6_HOPLIMIT 24#endif 25 26#if defined IPV6_PKTINFO && !defined IPV6_RECVPKTINFO 27# define IPV6_RECVPKTINFO IPV6_PKTINFO 28#endif 29 30int 31open_icmpv6_socket(void) 32{ 33 int sock; 34 struct icmp6_filter filter; 35 int err, val; 36 37 sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); 38 if (sock < 0) 39 { 40 flog(LOG_ERR, "can't create socket(AF_INET6): %s", strerror(errno)); 41 return (-1); 42 } 43 44 val = 1; 45 err = setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(val)); 46 if (err < 0) 47 { 48 flog(LOG_ERR, "setsockopt(IPV6_RECVPKTINFO): %s", strerror(errno)); 49 return (-1); 50 } 51 52 val = 2; 53#ifdef __linux__ 54 err = setsockopt(sock, IPPROTO_RAW, IPV6_CHECKSUM, &val, sizeof(val)); 55#else 56 err = setsockopt(sock, IPPROTO_IPV6, IPV6_CHECKSUM, &val, sizeof(val)); 57#endif 58 if (err < 0) 59 { 60 flog(LOG_ERR, "setsockopt(IPV6_CHECKSUM): %s", strerror(errno)); 61 return (-1); 62 } 63 64 val = 255; 65 err = setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val, sizeof(val)); 66 if (err < 0) 67 { 68 flog(LOG_ERR, "setsockopt(IPV6_UNICAST_HOPS): %s", strerror(errno)); 69 return (-1); 70 } 71 72 val = 255; 73 err = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, sizeof(val)); 74 if (err < 0) 75 { 76 flog(LOG_ERR, "setsockopt(IPV6_MULTICAST_HOPS): %s", strerror(errno)); 77 return (-1); 78 } 79 80#ifdef IPV6_RECVHOPLIMIT 81 val = 1; 82 83 err = setsockopt(sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &val, sizeof(val)); 84 if (err < 0) 85 { 86 flog(LOG_ERR, "setsockopt(IPV6_RECVHOPLIMIT): %s", strerror(errno)); 87 return (-1); 88 } 89 90#endif 91 92 /* 93 * setup ICMP filter 94 */ 95 96 ICMP6_FILTER_SETBLOCKALL(&filter); 97 ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter); 98 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter); 99 100 err = setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, 101 sizeof(filter)); 102 if (err < 0) 103 { 104 flog(LOG_ERR, "setsockopt(ICMPV6_FILTER): %s", strerror(errno)); 105 return (-1); 106 } 107 108 return sock; 109} 110