K2.6 patches and update.
[tomato.git] / release / src / router / zebra / lib / sockopt.c
blobe2beca9f9ca019a69ed1acbaaf8a263562d09c8f
1 /* setsockopt functions
2 * Copyright (C) 1999 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
22 #include <zebra.h>
23 #include "log.h"
25 #ifdef HAVE_IPV6
26 /* Set IPv6 packet info to the socket. */
27 int
28 setsockopt_ipv6_pktinfo (int sock, int val)
30 int ret;
32 #ifdef IPV6_RECVPKTINFO /*2292bis-01*/
33 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(val));
34 if (ret < 0)
35 zlog_warn ("can't setsockopt IPV6_RECVPKTINFO : %s", strerror (errno));
36 #else /*RFC2292*/
37 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, &val, sizeof(val));
38 if (ret < 0)
39 zlog_warn ("can't setsockopt IPV6_PKTINFO : %s", strerror (errno));
40 #endif /* INIA_IPV6 */
41 return ret;
44 /* Set multicast hops val to the socket. */
45 int
46 setsockopt_ipv6_checksum (int sock, int val)
48 int ret;
50 #ifdef GNU_LINUX
51 ret = setsockopt(sock, IPPROTO_RAW, IPV6_CHECKSUM, &val, sizeof(val));
52 #else
53 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_CHECKSUM, &val, sizeof(val));
54 #endif /* GNU_LINUX */
55 if (ret < 0)
56 zlog_warn ("can't setsockopt IPV6_CHECKSUM");
57 return ret;
60 /* Set multicast hops val to the socket. */
61 int
62 setsockopt_ipv6_multicast_hops (int sock, int val)
64 int ret;
66 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, sizeof(val));
67 if (ret < 0)
68 zlog_warn ("can't setsockopt IPV6_MULTICAST_HOPS");
69 return ret;
72 /* Set multicast hops val to the socket. */
73 int
74 setsockopt_ipv6_unicast_hops (int sock, int val)
76 int ret;
78 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &val, sizeof(val));
79 if (ret < 0)
80 zlog_warn ("can't setsockopt IPV6_UNICAST_HOPS");
81 return ret;
84 int
85 setsockopt_ipv6_hoplimit (int sock, int val)
87 int ret;
89 #ifdef IPV6_RECVHOPLIMIT /*2292bis-01*/
90 ret = setsockopt (sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &val, sizeof(val));
91 if (ret < 0)
92 zlog_warn ("can't setsockopt IPV6_RECVHOPLIMIT");
93 #else /*RFC2292*/
94 ret = setsockopt (sock, IPPROTO_IPV6, IPV6_HOPLIMIT, &val, sizeof(val));
95 if (ret < 0)
96 zlog_warn ("can't setsockopt IPV6_HOPLIMIT");
97 #endif
98 return ret;
101 /* Set multicast loop zero to the socket. */
103 setsockopt_ipv6_multicast_loop (int sock, int val)
105 int ret;
107 ret = setsockopt (sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val,
108 sizeof (val));
109 if (ret < 0)
110 zlog_warn ("can't setsockopt IPV6_MULTICAST_LOOP");
111 return ret;
114 #endif /* HAVE_IPV6 */
117 /* Set up a multicast socket options for IPv4
118 This is here so that people only have to do their OS multicast mess
119 in one place rather than all through zebra, ospfd, and ripd
120 NB: This is a hookpoint for specific OS functionality */
122 setsockopt_multicast_ipv4(int sock,
123 int optname,
124 struct in_addr if_addr,
125 unsigned int mcast_addr,
126 unsigned int ifindex)
129 /* Linux 2.2.0 and up */
130 #if defined(GNU_LINUX) && LINUX_VERSION_CODE > 131584
131 /* This is better because it uses ifindex directly */
132 struct ip_mreqn mreqn;
134 switch (optname)
136 case IP_MULTICAST_IF:
137 case IP_ADD_MEMBERSHIP:
138 case IP_DROP_MEMBERSHIP:
139 memset (&mreqn, 0, sizeof(mreqn));
141 if (mcast_addr)
142 mreqn.imr_multiaddr.s_addr = mcast_addr;
144 if (ifindex)
145 mreqn.imr_ifindex = ifindex;
146 else
147 mreqn.imr_address = if_addr;
149 return setsockopt(sock, IPPROTO_IP, optname, (void *)&mreqn, sizeof(mreqn));
150 break;
152 default:
153 /* Can out and give an understandable error */
154 errno = EINVAL;
155 return -1;
156 break;
159 /* Example defines for another OS, boilerplate off other code in this
160 function, AND handle optname as per other sections for consistency !! */
161 /* #elif defined(BOGON_NIX) && EXAMPLE_VERSION_CODE > -100000 */
162 /* Add your favourite OS here! */
164 #else /* #if OS_TYPE */
165 /* default OS support */
167 struct in_addr m;
168 struct ip_mreq mreq;
170 switch (optname)
172 case IP_MULTICAST_IF:
173 m = if_addr;
175 return setsockopt (sock, IPPROTO_IP, optname, (void *)&m, sizeof(m));
176 break;
178 case IP_ADD_MEMBERSHIP:
179 case IP_DROP_MEMBERSHIP:
180 memset (&mreq, 0, sizeof(mreq));
181 mreq.imr_multiaddr.s_addr = mcast_addr;
182 mreq.imr_interface = if_addr;
184 return setsockopt (sock,
185 IPPROTO_IP,
186 optname,
187 (void *)&mreq,
188 sizeof(mreq));
189 break;
191 default:
192 /* Can out and give an understandable error */
193 errno = EINVAL;
194 return -1;
195 break;
197 #endif /* #if OS_TYPE */