]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* |
2 | * OSPF network related functions | |
3 | * Copyright (C) 1999 Toshiaki Takada | |
4 | * | |
5 | * This file is part of GNU Zebra. | |
6 | * | |
7 | * GNU Zebra is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2, or (at your option) any | |
10 | * later version. | |
11 | * | |
12 | * GNU Zebra is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with GNU Zebra; see the file COPYING. If not, write to the Free | |
19 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
20 | * 02111-1307, USA. | |
21 | */ | |
22 | ||
23 | #include <zebra.h> | |
24 | ||
25 | #include "thread.h" | |
26 | #include "linklist.h" | |
27 | #include "prefix.h" | |
28 | #include "if.h" | |
29 | #include "sockunion.h" | |
30 | #include "log.h" | |
31 | #include "sockopt.h" | |
edd7c245 | 32 | #include "privs.h" |
33 | ||
34 | extern struct zebra_privs_t ospfd_privs; | |
718e3744 | 35 | |
36 | #include "ospfd/ospfd.h" | |
37 | #include "ospfd/ospf_network.h" | |
38 | #include "ospfd/ospf_interface.h" | |
39 | #include "ospfd/ospf_asbr.h" | |
40 | #include "ospfd/ospf_lsa.h" | |
41 | #include "ospfd/ospf_lsdb.h" | |
42 | #include "ospfd/ospf_neighbor.h" | |
43 | #include "ospfd/ospf_packet.h" | |
44 | ||
edd7c245 | 45 | |
46 | ||
718e3744 | 47 | /* Join to the OSPF ALL SPF ROUTERS multicast group. */ |
48 | int | |
49 | ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p, | |
50 | unsigned int ifindex) | |
51 | { | |
52 | int ret; | |
53 | ||
54 | ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP, | |
55 | p->u.prefix4, htonl (OSPF_ALLSPFROUTERS), | |
56 | ifindex); | |
57 | if (ret < 0) | |
58 | zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (AllSPFRouters): %s", | |
59 | strerror (errno)); | |
60 | else | |
61 | zlog_info ("interface %s join AllSPFRouters Multicast group.", | |
62 | inet_ntoa (p->u.prefix4)); | |
63 | ||
64 | return ret; | |
65 | } | |
66 | ||
67 | int | |
68 | ospf_if_drop_allspfrouters (struct ospf *top, struct prefix *p, | |
69 | unsigned int ifindex) | |
70 | { | |
71 | int ret; | |
72 | ||
73 | ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP, | |
74 | p->u.prefix4, htonl (OSPF_ALLSPFROUTERS), | |
75 | ifindex); | |
76 | if (ret < 0) | |
77 | zlog_warn("can't setsockopt IP_DROP_MEMBERSHIP (AllSPFRouters): %s", | |
78 | strerror (errno)); | |
79 | else | |
80 | zlog_info ("interface %s leave AllSPFRouters Multicast group.", | |
81 | inet_ntoa (p->u.prefix4)); | |
82 | ||
83 | return ret; | |
84 | } | |
85 | ||
86 | /* Join to the OSPF ALL Designated ROUTERS multicast group. */ | |
87 | int | |
88 | ospf_if_add_alldrouters (struct ospf *top, struct prefix *p, unsigned int | |
89 | ifindex) | |
90 | { | |
91 | int ret; | |
92 | ||
93 | ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP, | |
94 | p->u.prefix4, htonl (OSPF_ALLDROUTERS), | |
95 | ifindex); | |
96 | if (ret < 0) | |
97 | zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (AllDRouters): %s", | |
98 | strerror (errno)); | |
99 | else | |
100 | zlog_info ("interface %s join AllDRouters Multicast group.", | |
101 | inet_ntoa (p->u.prefix4)); | |
102 | ||
103 | return ret; | |
104 | } | |
105 | ||
106 | int | |
107 | ospf_if_drop_alldrouters (struct ospf *top, struct prefix *p, unsigned int | |
108 | ifindex) | |
109 | { | |
110 | int ret; | |
111 | ||
112 | ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP, | |
113 | p->u.prefix4, htonl (OSPF_ALLDROUTERS), | |
114 | ifindex); | |
115 | if (ret < 0) | |
116 | zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (AllDRouters): %s", | |
117 | strerror (errno)); | |
118 | else | |
119 | zlog_info ("interface %s leave AllDRouters Multicast group.", | |
120 | inet_ntoa (p->u.prefix4)); | |
121 | ||
122 | return ret; | |
123 | } | |
124 | ||
125 | int | |
126 | ospf_if_ipmulticast (struct ospf *top, struct prefix *p, unsigned int ifindex) | |
127 | { | |
128 | u_char val; | |
129 | int ret, len; | |
130 | ||
131 | val = 0; | |
132 | len = sizeof (val); | |
133 | ||
134 | /* Prevent receiving self-origined multicast packets. */ | |
135 | ret = setsockopt (top->fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&val, len); | |
136 | if (ret < 0) | |
137 | zlog_warn ("can't setsockopt IP_MULTICAST_LOOP(0): %s", strerror (errno)); | |
138 | ||
139 | /* Explicitly set multicast ttl to 1 -- endo. */ | |
140 | val = 1; | |
141 | ret = setsockopt (top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val, len); | |
142 | if (ret < 0) | |
143 | zlog_warn ("can't setsockopt IP_MULTICAST_TTL(1): %s", strerror (errno)); | |
144 | ||
145 | ret = setsockopt_multicast_ipv4 (top->fd, IP_MULTICAST_IF, | |
146 | p->u.prefix4, 0, ifindex); | |
147 | if (ret < 0) | |
148 | zlog_warn ("can't setsockopt IP_MULTICAST_IF: %s", strerror (errno)); | |
149 | ||
150 | return ret; | |
151 | } | |
152 | ||
153 | int | |
154 | ospf_sock_init (void) | |
155 | { | |
156 | int ospf_sock; | |
157 | int ret, tos, hincl = 1; | |
158 | ||
edd7c245 | 159 | if ( ospfd_privs.change (ZPRIVS_RAISE) ) |
160 | zlog_err ("ospf_sock_init: could not raise privs, %s", | |
161 | strerror (errno) ); | |
162 | ||
718e3744 | 163 | ospf_sock = socket (AF_INET, SOCK_RAW, IPPROTO_OSPFIGP); |
164 | if (ospf_sock < 0) | |
165 | { | |
edd7c245 | 166 | if ( ospfd_privs.change (ZPRIVS_LOWER) ) |
167 | zlog_err ("ospf_sock_init: could not lower privs, %s", | |
168 | strerror (errno) ); | |
b1809bea | 169 | zlog_err ("ospf_read_sock_init: socket: %s", strerror (errno)); |
170 | exit(-1); | |
718e3744 | 171 | } |
edd7c245 | 172 | |
718e3744 | 173 | |
174 | /* Set precedence field. */ | |
175 | #ifdef IPTOS_PREC_INTERNETCONTROL | |
176 | tos = IPTOS_PREC_INTERNETCONTROL; | |
177 | ret = setsockopt (ospf_sock, IPPROTO_IP, IP_TOS, | |
178 | (char *) &tos, sizeof (int)); | |
179 | if (ret < 0) | |
180 | { | |
edd7c245 | 181 | if ( ospfd_privs.change (ZPRIVS_LOWER) ) |
182 | zlog_err ("ospf_sock_init: could not lower privs, %s", | |
183 | strerror (errno) ); | |
718e3744 | 184 | zlog_warn ("can't set sockopt IP_TOS %d to socket %d", tos, ospf_sock); |
185 | close (ospf_sock); /* Prevent sd leak. */ | |
186 | return ret; | |
187 | } | |
188 | #endif /* IPTOS_PREC_INTERNETCONTROL */ | |
189 | ||
190 | /* we will include IP header with packet */ | |
191 | ret = setsockopt (ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof (hincl)); | |
192 | if (ret < 0) | |
edd7c245 | 193 | { |
194 | if ( ospfd_privs.change (ZPRIVS_LOWER) ) | |
195 | zlog_err ("ospf_sock_init: could not lower privs, %s", | |
196 | strerror (errno) ); | |
197 | zlog_warn ("Can't set IP_HDRINCL option"); | |
198 | } | |
718e3744 | 199 | |
200 | #if defined (IP_PKTINFO) | |
201 | ret = setsockopt (ospf_sock, IPPROTO_IP, IP_PKTINFO, &hincl, sizeof (hincl)); | |
202 | if (ret < 0) | |
edd7c245 | 203 | { |
204 | if ( ospfd_privs.change (ZPRIVS_LOWER) ) | |
205 | zlog_err ("ospf_sock_init: could not lower privs, %s", | |
206 | strerror (errno) ); | |
207 | zlog_warn ("Can't set IP_PKTINFO option"); | |
208 | } | |
718e3744 | 209 | #elif defined (IP_RECVIF) |
210 | ret = setsockopt (ospf_sock, IPPROTO_IP, IP_RECVIF, &hincl, sizeof (hincl)); | |
211 | if (ret < 0) | |
edd7c245 | 212 | { |
213 | if ( ospfd_privs.change (ZPRIVS_LOWER) ) | |
214 | zlog_err ("ospf_sock_init: could not lower privs, %s", | |
215 | strerror (errno) ); | |
216 | zlog_warn ("Can't set IP_RECVIF option"); | |
217 | } | |
718e3744 | 218 | #else |
219 | #warning "cannot be able to receive link information on this OS" | |
220 | #endif | |
edd7c245 | 221 | |
222 | if (ospfd_privs.change (ZPRIVS_LOWER)) | |
223 | { | |
224 | zlog_err ("ospf_sock_init: could not lower privs, %s", | |
225 | strerror (errno) ); | |
226 | } | |
718e3744 | 227 | |
228 | return ospf_sock; | |
229 | } |