1 /* Common include file
2 *
3 * Copyright (C) 2001-2005 Carsten Schill <carsten@cschill.de>
4 * Copyright (C) 2006-2009 Julien BLACHE <jb@jblache.org>
5 * Copyright (C) 2009 Todd Hayton <todd.hayton@gmail.com>
6 * Copyright (C) 2009-2011 Micha Lenk <micha@debian.org>
7 * Copyright (C) 2011-2013 Joachim Nilsson <troglobit@gmail.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdarg.h>
28 #include <syslog.h>
29 #include <errno.h>
30 #include <unistd.h>
31
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35
36 #include <sys/ioctl.h>
37 #include <sys/socket.h>
38 #include <sys/un.h>
39 #include <sys/queue.h>
40
find_valid_iface(const char * ifname,int cmd)41 #include <net/if.h>
42
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
45
46 #include "config.h"
47
48 #ifdef HAVE_LINUX_MROUTE_H
49 #define _LINUX_IN_H /* For Linux <= 2.6.25 */
50 #include <linux/types.h>
51 #include <linux/mroute.h>
52 #endif
53
54 #ifdef HAVE_LINUX_MROUTE6_H
55 #include <linux/mroute6.h>
56 #endif
57
58 #ifdef HAVE_LINUX_FILTER_H
59 #include <linux/filter.h>
60 #endif
61
62 #ifdef HAVE_NET_ROUTE_H
63 #include <net/route.h>
64 #endif
65
66 #ifdef HAVE_NETINET_IP_MROUTE_H
67 #include <netinet/ip_mroute.h>
68 #endif
69 #ifdef __DragonFly__
70 #include <net/ip_mroute/ip_mroute.h>
71 #endif
72
73 #ifdef HAVE_NETINET6_IP6_MROUTE_H
74 #ifdef HAVE_SYS_PARAM_H
75 #include <sys/param.h>
76 #endif
77 #include <netinet6/ip6_mroute.h>
78 #endif
79
80 typedef u_int8_t uint8;
81 typedef u_int16_t uint16;
mcgroup_join_leave_ipv4(int sd,int cmd,const char * ifname,struct in_addr group)82 typedef u_int32_t uint32;
83
84 #define SA(x) ((struct sockaddr *)x)
85 #define SIN4(x) ((struct sockaddr_in *)x)
86 #define SIN6(x) ((struct sockaddr_in6 *)x)
87
88 #ifndef IN6_IS_ADDR_MULTICAST
89 #define IN6_IS_ADDR_MULTICAST(a) (((__const uint8_t *) (a))[0] == 0xff)
90 #endif
91
92 #ifndef MIN
93 #define MIN(a, b) ((a) < (b) ? (a) : (b))
94 #endif
95 #ifndef MAX
96 #define MAX(a, b) ((a) < (b) ? (b) : (a))
97 #endif
98
99 /* http://stackoverflow.com/questions/1598773/is-there-a-standard-function-in-c-that-would-return-the-length-of-an-array/1598827#1598827
100 * Evidently Google uses it in Chromium. It is actually intended to look like 0[arr], read the link, or search the web.
101 */
102 #define ARRAY_ELEMENTS(arr) ((sizeof(arr)/sizeof(0[arr])) / ((size_t)(!(sizeof(arr) % sizeof(0[arr])))))
103
104 struct iface {
105 char name[IFNAMSIZ + 1];
106 struct in_addr inaddr; /* == 0 for non IP interfaces */
107 u_short ifindex; /* Physical interface index */
108 short flags;
109 short vif;
mcgroup4_join(const char * ifname,struct in_addr group)110 short mif;
111 uint8_t threshold; /* TTL threshold: 1-255, default: 1 */
112 };
113
114 extern int do_vifs;
115 extern int do_syslog;
116
117 /* ifvc.c */
118 #define MAX_IF 40 // max. number of interfaces recognized
119
120 void iface_init (void);
121 struct iface *iface_find_by_name (const char *ifname);
122 struct iface *iface_find_by_index (unsigned int ifindex);
mcgroup4_leave(const char * ifname,struct in_addr group)123 struct iface *iface_find_by_vif (int vif);
124 int iface_get_vif (struct iface *iface);
125 int iface_get_mif (struct iface *iface);
126 int iface_get_vif_by_name (const char *ifname);
127 int iface_get_mif_by_name (const char *ifname);
128
129 /* mroute-api.c */
130
131 /*
132 * IPv4 multicast route
mcgroup4_disable(void)133 */
134 #define MAX_MC_VIFS MAXVIFS /* from linux/mroute.h */
135
136 struct mroute4 {
137 LIST_ENTRY(mroute4) link;
138
139 struct in_addr sender;
140 struct in_addr group; /* multicast group */
141 short inbound; /* incoming VIF */
142 uint8 ttl[MAX_MC_VIFS]; /* outgoing VIFs */
143 };
mcgroup6_init(void)144 typedef struct mroute4 mroute4_t;
145
146 /*
147 * IPv6 multicast route
148 */
149 #ifdef HAVE_IPV6_MULTICAST_ROUTING
150 #define MAX_MC_MIFS MAXMIFS /* from linux/mroute6.h */
151 #else
152 #define MAX_MC_MIFS 1 /* Dummy value for builds w/o IPv6 routing */
153 #endif
154
155 struct mroute6 {
156 struct sockaddr_in6 sender;
157 struct sockaddr_in6 group; /* multicast group */
158 short inbound; /* incoming VIF */
159 uint8 ttl[MAX_MC_MIFS]; /* outgoing VIFs */
160 };
161 typedef struct mroute6 mroute6_t;
162
163 /*
164 * Generic multicast route (wrapper for IPv4/IPv6 mroute)
165 */
166 struct mroute {
167 int version; /* 4 or 6 */
168 union {
169 mroute4_t mroute4;
170 mroute6_t mroute6;
171 } u;
mcgroup_join_leave_ipv6(int sd,int cmd,const char * ifname,struct in6_addr group)172 };
173 typedef struct mroute mroute_t;
174
175 /*
176 * Raw IGMP socket used as interface for the IPv4 mrouted API.
177 * Receives IGMP packets and upcall messages from the kernel.
178 */
179 extern int mroute4_socket;
180
181 /*
182 * Raw ICMPv6 socket used as interface for the IPv6 mrouted API.
183 * Receives MLD packets and upcall messages from the kenrel.
184 */
185 #define DEFAULT_THRESHOLD 1 /* Packet TTL must be at least 1 to pass */
186
187 extern int mroute6_socket;
188
189 int mroute4_enable (void);
190 void mroute4_disable (void);
191 int mroute4_dyn_add (mroute4_t *mroute);
192 int mroute4_add (mroute4_t *mroute);
193 int mroute4_del (mroute4_t *mroute);
194
195 int mroute6_enable (void);
196 void mroute6_disable (void);
197 int mroute6_add (mroute6_t *mroute);
198 int mroute6_del (mroute6_t *mroute);
199
mcgroup6_join(const char * ifname,struct in6_addr group)200 int mroute_add_vif (char *ifname, uint8_t threshold);
201 int mroute_del_vif (char *ifname);
202
203 /* ipc.c */
204 int ipc_server_init (void);
205 struct cmd *ipc_server_read (uint8 buf[], int len);
206 int ipc_client_init (void);
207 int ipc_send (const void *buf, int len);
208 int ipc_receive (uint8 buf[], int len);
209 void ipc_exit (void);
210
211 /* cmdpkt.c
212 *
mcgroup6_leave(const char * ifname,struct in6_addr group)213 * XXX: Add example packet layouts
214 */
215 struct cmd {
216 size_t len; /* total size of packet including cmd header */
217 uint16 cmd; /* 'a'=Add,'r'=Remove,'j'=Join,'l'=Leave,'k'=Kill */
218 uint16 count; /* command argument count */
219 char *argv[0]; /* 'count' * '\0' terminated strings + '\0' */
220 };
221
222 #define MX_CMDPKT_SZ 1024 /* command size including appended strings */
223
mcgroup6_disable(void)224 void *cmd_build (char cmd, const char *argv[], int count);
225 const char *cmd_convert_to_mroute (mroute_t *mroute, const struct cmd *packet);
226 const char *cmd_convert_to_mroute4 (mroute4_t *mroute, const struct cmd *packet);
227 const char *cmd_convert_to_mroute6 (mroute6_t *mroute, const struct cmd *packet);
228
229 /* mcgroup.c */
230 int mcgroup4_join (const char *ifname, struct in_addr group);
231 int mcgroup4_leave (const char *ifname, struct in_addr group);
232 void mcgroup4_disable (void);
233 int mcgroup6_join (const char *ifname, struct in6_addr group);
234 int mcgroup6_leave (const char *ifname, struct in6_addr group);
235 void mcgroup6_disable (void);
236
237 /* log.c */
238 #define LOG_INIT 10
239
240 extern int log_level;
241 extern char log_message[128];
242
243 int loglvl(const char *level);
244 void smclog(int severity, const char *fmt, ...);
245
246 /* parse-conf.c */
247 int run_script(mroute_t *mroute);
248 int parse_conf_file(const char *file);
249
250 /* pidfile.c */
251 int pidfile(const char *basename);
252
253 /**
254 * Local Variables:
255 * version-control: t
256 * indent-tabs-mode: t
257 * c-file-style: "linux"
258 * End:
259 */
260