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
17#include <sys/param.h>
18
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
25
26#ifndef Linux
27#include <net/if.h>
28#include <net/if_var.h>
29#include <net/if_dl.h>
30#include <net/route.h>
31#else
32#include <linux/if.h>
33#endif
34#include <netinet/in_systm.h>
35#ifdef Linux
36#include <linux/in.h>
37#include "ip.h"
38#else
39#include <netinet/in.h>
40#include <netinet/ip.h>
41#endif
42#include <assert.h>
43#ifdef Linux
44#include <linux/mroute.h>
45#else
46#include <netinet/ip_mroute.h>
47#endif
48#include <sys/syslog.h>
49
50
51
52#include "util.h"
53#include "igmp.h"
54
55
56extern vifi_t     numvifs;
57extern unsigned long upstream;
58extern int forward_upstream;
59
60
61#define UNKNOWN -1
62#define EMPTY 0
63#define IGMPVERSION 1
64#define IS_QUERIER  2
65#define UPSTREAM    4
66#define DOWNSTREAM  5
67
68#define	MAX_MSGBUFSIZE		2048
69#define MAXVIFS	                32
70#define	MAX_ADDRS	       	500
71#define TRUE	         	1
72#define FALSE	         	0
73
74#ifdef Linux
75#define FD_COPY(f, t)   memcpy(t, f, sizeof(*(f)))
76#endif
77/*
78#define MAXCTRLSIZE						\
79	(sizeof(struct cmsghdr) + sizeof(struct sockaddr_dl) +	\
80	sizeof(struct cmsghdr) + sizeof(int) + 32)
81
82#define CMSG_IFINDEX(cmsg) 				\
83	(((struct sockaddr_dl*)(cmsg + 1))->sdl_index)	\
84*/
85
86#define VALID_ADDR(x)\
87	    ((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" )))))
88
89//typedef u_short vifi_t;
90/* IGMP interface type */
91typedef struct _igmp_interface_t {
92    struct in_addr               igmpi_addr;
93    char		         igmpi_name[IFNAMSIZ];
94    vifi_t 		         igmpi_index;
95    int                          igmpi_type;  /*interface type:upstream/downstream*/
96    igmp_group_t*                igmpi_groups;
97    sch_query_t*	         sch_group_query;
98    int				 igmpi_version;
99    int				 igmpi_isquerier;
100    int				 igmpi_qi;		/* query interval */
101    int				 igmpi_qri;		/* query response interval */
102    int				 igmpi_gmi;		/* group membership interval */
103    int				 igmpi_oqp;		/* other querier present timer */
104    int			     igmpi_rv;		/* robustness variable */
105    int				 igmpi_ti_qi;	/* timer: query interval */
106    int              igmpi_socket;	/* igmp socket */
107	int				 ifp_udp_socket;/* udp socket */
108    struct _igmp_interface_t*    igmpi_next;
109    int				 igmpi_save_flags;
110    char*			 igmpi_buf;
111    int				 igmpi_bufsize;
112} igmp_interface_t;
113
114/* proxy membership database */
115typedef struct membership_db {
116  struct {
117    struct in_addr group;
118    int fmode;
119    int numsources;
120    struct in_addr sources[500];
121  } membership;
122  struct membership_db *next;
123} membership_db;
124
125
126/* IGMP router type */
127typedef struct _igmp_router_t {
128  igmp_interface_t*       igmprt_interfaces;
129  membership_db*          igmprt_membership_db;
130  int 		          igmprt_flag_timer;
131  int 		          igmprt_flag_input;
132  int 		          igmprt_running;
133  pthread_t               igmprt_thr_timer;
134  pthread_t               igmprt_thr_input;
135  int                     igmprt_up_socket;
136  int                     igmprt_socket;
137    } igmp_router_t;
138
139#if (!defined LINUX26)
140 struct ip_msfilter {
141 	__u32	imsf_multiaddr;	/* IP multicast address of group */
142 	__u32	imsf_interface;	/* local IP address of interface */
143 	__u32	imsf_fmode; 	/* filter mode */
144 	__u32	imsf_numsrc;	/* number of sources in src list */
145 	__u32  imsf_slist[1];	/* source list */
146 };
147#endif
148
149/***
150 *
151 * routines
152 *
153 ***/
154/* sources routines */
155igmp_src_t *
156igmp_group_src_add(igmp_group_t *gp,struct in_addr srcaddr);
157
158igmp_src_t *
159igmp_group_src_lookup(igmp_group_t *gp,struct in_addr srcaddr);
160
161void igmp_src_cleanup(igmp_group_t *gp,igmp_src_t *src);
162
163
164
165/* group routines */
166
167igmp_group_t*
168igmp_group_create(struct in_addr groupaddr);
169
170void
171igmp_group_cleanup(igmp_group_t* gp);
172
173void
174igmp_group_handle_isex(igmp_router_t* router, igmp_interface_t* ifp, igmp_group_t* gp,
175    int numsrc, struct in_addr *sources);
176
177void
178igmp_group_print(igmp_group_t* gp);
179
180/* interface routines */
181
182igmp_interface_t*
183igmp_interface_create(struct in_addr ifaddr, char *ifname,vifi_t index);
184
185void
186igmp_interface_cleanup(igmp_interface_t* ifp);
187
188igmp_group_t*
189igmp_interface_group_add(igmp_router_t* router, igmp_interface_t *ifp, struct in_addr groupaddr);
190
191igmp_group_t*
192igmp_interface_group_lookup(igmp_interface_t *ifp, struct in_addr groupaddr);
193
194void
195igmp_interface_membership_report_v12(igmp_router_t* router, igmp_interface_t* ifp,struct in_addr src,
196	igmpr_t* report, int len, int version);
197
198void
199igmp_interface_print(igmp_interface_t* ifp);
200
201/* router routines */
202
203int
204igmprt_init(igmp_router_t* igmprt);
205
206void
207igmprt_cleanup(igmp_router_t* igmprt);
208
209igmp_interface_t*
210igmprt_interface_lookup(igmp_router_t* igmprt, struct in_addr ifaddr);
211
212igmp_group_t*
213igmprt_group_lookup(igmp_router_t* igmprt, struct in_addr ifaddr,
214	struct in_addr groupaddr);
215
216igmp_interface_t*
217igmprt_interface_add(igmp_router_t* igmprt, struct in_addr ifaddr,
218	char *ifname,vifi_t index);
219
220igmp_group_t*
221igmprt_group_add(igmp_router_t* igmprt, struct in_addr ifaddr,
222    struct in_addr groupaddr);
223
224void
225igmprt_timer();
226
227void*
228igmprt_timer_thread(void* arg);
229
230void
231igmprt_input(igmp_router_t* igmprt, igmp_interface_t* ifp);
232
233void*
234igmprt_input_thread(void *arg);
235
236void
237igmprt_start(igmp_router_t* igmprt);
238
239void
240igmprt_stop(igmp_router_t* igmprt);
241
242void
243igmprt_print(igmp_router_t* igmprt);
244
245void
246igmprt_membership_query(igmp_router_t* igmprt, igmp_interface_t* ifp,
247    struct in_addr *group, struct in_addr *sources, int numsrc, int SRSP);
248
249void
250receive_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);
251
252void
253send_sh_query(igmp_router_t *router,igmp_interface_t *ifp);
254void
255send_group_specific_query(igmp_router_t *router,igmp_interface_t *ifp,igmp_group_t *gp);
256void
257send_group_src_specific_q(igmp_router_t *router,igmp_interface_t *ifp,igmp_group_t *gp,struct in_addr *sources,int numsrc);
258
259/* proxy routines */
260
261void set_source_filter(igmp_router_t* router,igmp_group_t* gp,unsigned long interface_adress,int fmode,int nsources,struct in_addr *sources);
262void k_init_proxy(int socket);
263void k_stop_proxy(int socket);
264int k_proxy_add_vif (int socket,unsigned long vifaddr,vifi_t vifi);
265int k_proxy_del_mfc (int socket, u_long source, u_long group);
266int k_proxy_chg_mfc(int socket,u_long source,u_long group,vifi_t outvif,int fstate);
267membership_db* create_membership(struct in_addr group,int fmode,int numsources,struct in_addr *sources);
268membership_db* find_membership(membership_db *membership,struct in_addr group);
269membership_db* deleate_membership(igmp_router_t* igmprt,struct in_addr group);
270membership_db* update_multi(igmp_router_t *igmprt,struct in_addr group,int fmode,int nsources,struct in_addr *sources);
271int find_source(struct in_addr sr,int nsources,struct in_addr *sources);
272