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