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