1/*****************************************************************************
2 * Fichier Include : IGMP.h
3 *****************************************************************************
4 * Contient la declaration de differentes structures du demon IGMPPD
5 * Auteurs: Lahmadi.Abdelkader@loria.fr
6 *          Anis.Ben-Hellel@loria.fr
7 * MAJ: 7 Aout 2001
8 ****************************************************************************/
9//#define Linux
10#include <stdio.h>
11#include <unistd.h>
12#include <pthread.h>
13#include <signal.h>
14#include <stdlib.h>
15#include <string.h>
16#include <ctype.h>
17
18#include <sys/param.h>
19#include <sys/errno.h>
20#include <sys/types.h>
21#include <sys/socket.h>
22#include <sys/ioctl.h>
23#include <sys/uio.h>
24#include <sys/syslog.h>
25
26#include <net/if.h>
27#include <arpa/inet.h>
28#include <netinet/in_systm.h>
29#include <netinet/in.h>
30#include <netinet/ip.h>
31#include <assert.h>
32#include <linux/if_packet.h>
33#include <net/ethernet.h>
34#include "util.h"
35#include "igmp.h"
36#include "mroute.h"
37#include "acosNvramConfig.h"
38#if (defined RALINK_SDK)
39#include "defs.h"
40#endif
41
42#if 0 /* not used */
43extern vifi_t     numvifs;
44#endif
45extern unsigned long upstream;
46extern int forward_upstream;
47
48#define UNKNOWN -1
49#define EMPTY 0
50#define IGMPVERSION 1
51#define IS_QUERIER  2
52#define UPSTREAM    4
53#define DOWNSTREAM  5
54
55#define	MAX_MSGBUFSIZE		2048
56#define MAXVIFS	                32
57#define	MAX_ADDRS	       	500
58#define TRUE	         	1
59#define FALSE	         	0
60
61#ifndef isblank
62#define isblank(c) ((c) == ' ' || (c) == '\t')
63#endif
64
65#ifndef FD_COPY
66#define FD_COPY(f, t)   memcpy(t, f, sizeof(*(f)))
67#endif
68/*
69#define MAXCTRLSIZE						\
70	(sizeof(struct cmsghdr) + sizeof(struct sockaddr_dl) +	\
71	sizeof(struct cmsghdr) + sizeof(int) + 32)
72
73#define CMSG_IFINDEX(cmsg) 				\
74	(((struct sockaddr_dl*)(cmsg + 1))->sdl_index)	\
75*/
76
77#define VALID_ADDR(x)\
78	    ((ntohl((x).s_addr) != INADDR_ALLRTRS_GROUP) && (ntohl((x).s_addr) != INADDR_ALLRTRS_IGMPV3_GROUP) && (ntohl((x).s_addr) != INADDR_ALLHOSTS_GROUP) && (ntohl((x).s_addr) != (ntohl(inet_addr("224.0.0.4")))) && (ntohl((x).s_addr) != (ntohl(inet_addr("224.0.0.9" )))))
79
80//typedef u_short vifi_t;
81/* IGMP interface type */
82typedef struct _igmp_interface_t {
83    struct in_addr               igmpi_addr;
84    char		         igmpi_name[IFNAMSIZ];
85    vifi_t 		         igmpi_index;
86    int                          igmpi_type;  /*interface type:upstream/downstream*/
87    igmp_group_t*                igmpi_groups;
88    sch_query_t*	         sch_group_query;
89    int				 igmpi_version;
90    int				 igmpi_isquerier;
91    int				 igmpi_qi;		/* query interval */
92    int				 igmpi_qri;		/* query response interval */
93    int				 igmpi_gmi;		/* group membership interval */
94    int				 igmpi_oqp;		/* other querier present timer */
95    int			     igmpi_rv;		/* robustness variable */
96    int				 igmpi_ti_qi;	/* timer: query interval */
97    int              igmpi_socket;	/* igmp socket */
98    int				 ifp_udp_socket;/* udp socket */
99    struct _igmp_interface_t*    igmpi_next;
100    int				 igmpi_save_flags;
101    char*			 igmpi_buf;
102    int				 igmpi_bufsize;
103} igmp_interface_t;
104
105/* proxy membership database */
106typedef struct membership_db {
107  struct {
108    struct in_addr group;
109    int fmode;
110    int numsources;
111    struct in_addr sources[500];
112  } membership;
113  struct membership_db *next;
114} membership_db;
115
116
117/* IGMP router type */
118typedef struct _igmp_router_t {
119  igmp_interface_t*       igmprt_interfaces;
120  membership_db*          igmprt_membership_db;
121  int 		          igmprt_flag_timer;
122  int 		          igmprt_flag_input;
123  int 		          igmprt_running;
124  pthread_t               igmprt_thr_timer;
125  pthread_t               igmprt_thr_input;
126  int                     igmprt_up_socket;
127  int                     igmprt_socket;
128#ifdef BT_IGMP_SUPPORT
129  int                     igmprt_bt_igmp;
130#endif
131} igmp_router_t;
132
133#if 0 /* not used */
134struct ip_msfilter {
135  __be32	imsf_multiaddr;	/* IP multicast address of group */
136  __be32	imsf_interface;	/* local IP address of interface */
137  __u32	imsf_fmode; 	/* filter mode */
138  __u32	imsf_numsrc;	/* number of sources in src list */
139  __be32  imsf_slist[1];	/* source list */
140};
141
142#define IP_MSFILTER_SIZE(numsrc)  (sizeof(struct ip_msfilter) \
143    - sizeof(struct in_addr) + (numsrc) * sizeof(struct in_addr))
144#endif
145
146/***
147 *
148 * routines
149 *
150 ***/
151/* sources routines */
152igmp_src_t *
153igmp_group_src_add(igmp_group_t *gp,struct in_addr srcaddr);
154
155igmp_src_t *
156igmp_group_src_lookup(igmp_group_t *gp,struct in_addr srcaddr);
157
158void igmp_src_cleanup(igmp_group_t *gp,igmp_src_t *src);
159
160
161
162/* group routines */
163
164igmp_group_t*
165igmp_group_create(struct in_addr groupaddr);
166
167void
168igmp_group_cleanup(igmp_group_t* gp);
169
170igmp_rep_t*
171igmp_group_rep_lookup(igmp_group_t *gp, struct in_addr srcaddr);
172
173igmp_rep_t*
174igmp_group_rep_del(igmp_group_t *gp, struct in_addr srcaddr);
175
176void igmp_group_handle_isex(igmp_router_t* router, igmp_interface_t* ifp,
177    igmp_group_t* gp, int numsrc, struct in_addr *sources);
178void igmp_group_handle_isin(igmp_router_t* router, igmp_interface_t* ifp,
179    igmp_group_t* gp, int numsrc, struct in_addr *sources);
180void igmp_group_handle_toin(igmp_router_t *router, igmp_interface_t *ifp,
181    igmp_group_t *gp, int numsrc, igmp_rep_t *srcrep, struct in_addr *sources);
182void igmp_group_handle_toex(igmp_router_t *router, igmp_interface_t *ifp,
183    igmp_group_t *gp, int numsrc, struct in_addr *sources);
184void igmp_group_handle_allow(igmp_router_t *router, igmp_interface_t *ifp,
185    igmp_group_t *gp, int numsrc, struct in_addr *sources);
186void igmp_group_handle_block(igmp_router_t *router, igmp_interface_t *ifp,
187    igmp_group_t *gp, int numsrc, struct in_addr *sources);
188
189void
190igmp_group_print(igmp_group_t* gp);
191
192/* interface routines */
193
194igmp_interface_t*
195igmp_interface_create(struct in_addr ifaddr, char *ifname,vifi_t index);
196
197void
198igmp_interface_cleanup(igmp_interface_t* ifp);
199
200igmp_group_t*
201igmp_interface_group_add(igmp_router_t* router, igmp_interface_t *ifp, struct in_addr groupaddr);
202
203igmp_group_t*
204igmp_interface_group_lookup(igmp_interface_t *ifp, struct in_addr groupaddr);
205
206void
207igmp_interface_membership_report_v12(igmp_router_t* router, igmp_interface_t* ifp,struct in_addr src,
208	igmpr_t* report, int len, int version);
209
210void
211igmp_interface_membership_report_v3(igmp_router_t* router, igmp_interface_t* ifp, struct in_addr src,
212	 igmp_report_t* report, int len);
213
214void
215igmp_interface_leave_group_v2(igmp_router_t* router, igmp_interface_t* ifp, struct in_addr src,
216	igmpr_t* report, int len);
217
218void
219igmp_interface_print(igmp_interface_t* ifp);
220
221/* router routines */
222
223int
224igmprt_init(igmp_router_t* igmprt);
225
226void
227igmprt_cleanup(igmp_router_t* igmprt);
228
229igmp_interface_t*
230igmprt_interface_lookup(igmp_router_t* igmprt, struct in_addr ifaddr);
231
232igmp_group_t*
233igmprt_group_lookup(igmp_router_t* igmprt, struct in_addr ifaddr,
234	struct in_addr groupaddr);
235
236igmp_interface_t*
237igmprt_interface_add(igmp_router_t* igmprt, struct in_addr ifaddr,
238	char *ifname,vifi_t index);
239
240igmp_group_t*
241igmprt_group_add(igmp_router_t* igmprt, struct in_addr ifaddr,
242    struct in_addr groupaddr);
243
244void
245igmprt_timer(igmp_router_t* igmprt);
246
247void*
248igmprt_timer_thread(void* arg);
249
250void igmprt_timer_querier(igmp_interface_t *ifp);
251void igmprt_timer_group(igmp_router_t* router, igmp_interface_t *ifp);
252void igmprt_clear_timer_group(igmp_interface_t *ifp);
253void igmprt_timer_source (igmp_router_t* router, igmp_interface_t *ifp);
254#if (defined RALINK_SDK)
255void igmprt_timer_membership_report(igmp_interface_t *ifp);
256#endif
257
258void
259igmprt_input(igmp_router_t* igmprt, igmp_interface_t* ifp);
260
261void*
262igmprt_input_thread(void *arg);
263
264void
265igmprt_start(igmp_router_t* igmprt);
266
267void
268igmprt_stop(igmp_router_t* igmprt);
269
270void
271igmprt_print(igmp_router_t* igmprt);
272
273void
274igmp_info_print(igmp_router_t *router, char *function);
275
276void
277igmprt_membership_query(igmp_router_t* igmprt, igmp_interface_t* ifp,
278    struct in_addr *group, struct in_addr *sources, int numsrc, int SRSP);
279
280int send_membership_report_v12(igmp_router_t* igmprt,
281    struct in_addr group, int version);
282int send_membership_report_v3(int is_be_queried);
283int send_membership_report_v12_to_v3(struct in_addr group, int type);
284int send_membership_report_v3_to_v12(void);
285int send_leave_group_v2(struct in_addr group);
286
287void
288receive_membership_query(igmp_router_t* igmprt,igmp_interface_t *ifp,struct in_addr gp,struct in_addr *sources, u_long src_query,int numsrc, int srsp,int version);
289
290void
291send_sh_query(igmp_router_t *router,igmp_interface_t *ifp);
292void
293send_group_specific_query(igmp_router_t *router,igmp_interface_t *ifp,igmp_group_t *gp);
294void
295send_group_src_specific_q(igmp_router_t *router,igmp_interface_t *ifp,igmp_group_t *gp,struct in_addr *sources,int numsrc);
296
297/* proxy routines */
298
299void set_source_filter(igmp_router_t* router,igmp_group_t* gp,unsigned long interface_adress,int fmode,int nsources,struct in_addr *sources);
300void k_init_proxy(int socket);
301void k_stop_proxy(int socket);
302int k_proxy_add_vif (int socket,unsigned long vifaddr,vifi_t vifi);
303int k_proxy_del_mfc (int socket, u_long source, u_long group);
304int k_proxy_chg_mfc(igmp_router_t* router,int socket,u_long source,u_long group,vifi_t outvif,int fstate);
305membership_db* create_membership(struct in_addr group,int fmode,int numsources,struct in_addr *sources);
306membership_db* find_membership(membership_db *membership,struct in_addr group);
307void deleate_membership(igmp_router_t* igmprt,struct in_addr group);
308membership_db* update_multi(igmp_router_t *igmprt,struct in_addr group,int fmode,int nsources,struct in_addr *sources);
309int find_source(struct in_addr sr,int nsources,struct in_addr *sources);
310
311/* utils */
312int wordToOption(char *word);
313
314