diff options
Diffstat (limited to 'mcast/common/mld.h')
-rw-r--r-- | mcast/common/mld.h | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/mcast/common/mld.h b/mcast/common/mld.h new file mode 100644 index 0000000..93d2bd6 --- /dev/null +++ b/mcast/common/mld.h @@ -0,0 +1,339 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#ifndef __MLD_H__ +#define __MLD_H__ + +/* Wrappers so we don't have to change the copied stuff ;) */ +#define __u8 uint8_t +#define __u16 uint16_t +/* Booleans */ +#define false 0 +#define true (!false) + + +/* Determine Endianness */ +#if ! defined __LITTLE_ENDIAN_BITFIELD && ! defined __BIG_ENDIAN_BITFIELD + #if BYTE_ORDER == LITTLE_ENDIAN + /* 1234 machines */ + #define __LITTLE_ENDIAN_BITFIELD 1 + #elif BYTE_ORDER == BIG_ENDIAN + /* 4321 machines */ + #define __BIG_ENDIAN_BITFIELD 1 + # define WORDS_BIGENDIAN 1 + #elif BYTE_ORDER == PDP_ENDIAN + /* 3412 machines */ + #error PDP endianness not supported yet! + #else + #error unknown endianness! + #endif +#endif + +/* Per RFC */ +struct mld1 +{ + __u8 type; + __u8 code; + __u16 csum; + __u16 mrc; + __u16 resv1; + struct in6_addr mca; +}; + +/* The timeout for queries */ +/* as per RFC3810 MLDv2 "9.2. Query Interval" */ +#define ECMH_SUBSCRIPTION_TIMEOUT 15 + +/* Robustness Factor, per RFC3810 MLDv2 "9.1. Robustness Variable" */ +#define ECMH_ROBUSTNESS_FACTOR 2 + + +/* MLDv2 Report */ +#ifndef ICMP6_V2_MEMBERSHIP_REPORT +#define ICMP6_V2_MEMBERSHIP_REPORT 143 +#endif +/* MLDv2 Report - Experimental Code */ +#ifndef ICMP6_V2_MEMBERSHIP_REPORT_EXP +#define ICMP6_V2_MEMBERSHIP_REPORT_EXP 206 +#endif + +/* MLDv2 Exclude/Include */ + +#ifndef MLD2_MODE_IS_INCLUDE +#define MLD2_MODE_IS_INCLUDE 1 +#endif +#ifndef MLD2_MODE_IS_EXCLUDE +#define MLD2_MODE_IS_EXCLUDE 2 +#endif +#ifndef MLD2_CHANGE_TO_INCLUDE +#define MLD2_CHANGE_TO_INCLUDE 3 +#endif +#ifndef MLD2_CHANGE_TO_EXCLUDE +#define MLD2_CHANGE_TO_EXCLUDE 4 +#endif +#ifndef MLD2_ALLOW_NEW_SOURCES +#define MLD2_ALLOW_NEW_SOURCES 5 +#endif +#ifndef MLD2_BLOCK_OLD_SOURCES +#define MLD2_BLOCK_OLD_SOURCES 6 +#endif + +#ifndef MLD2_ALL_MCR_INIT +#define MLD2_ALL_MCR_INIT { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x16 } } } +#endif + +#ifndef ICMP6_ROUTER_RENUMBERING +#define ICMP6_ROUTER_RENUMBERING 138 /* router renumbering */ +#endif +#ifndef ICMP6_NI_QUERY +#define ICMP6_NI_QUERY 139 /* node information request */ +#endif +#ifndef ICMP6_NI_REPLY +#define ICMP6_NI_REPLY 140 /* node information reply */ +#endif +#ifndef MLD_MTRACE_RESP +#define MLD_MTRACE_RESP 200 /* Mtrace response (to sender) */ +#endif +#ifndef MLD_MTRACE +#define MLD_MTRACE 201 /* Mtrace messages */ +#endif + +#ifndef ICMP6_DST_UNREACH_BEYONDSCOPE +#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* Beyond scope of source address */ +#endif + +#ifndef ICMP6_NI_SUCCESS +#define ICMP6_NI_SUCCESS 0 /* node information successful reply */ +#endif +#ifndef ICMP6_NI_REFUSED +#define ICMP6_NI_REFUSED 1 /* node information request is refused */ +#endif +#ifndef ICMP6_NI_UNKNOWN +#define ICMP6_NI_UNKNOWN 2 /* unknown Qtype */ +#endif + +#ifndef ICMP6_ROUTER_RENUMBERING_COMMAND +#define ICMP6_ROUTER_RENUMBERING_COMMAND 0 /* rr command */ +#endif +#ifndef ICMP6_ROUTER_RENUMBERING_RESULT +#define ICMP6_ROUTER_RENUMBERING_RESULT 1 /* rr result */ +#endif +#ifndef ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET +#define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255 /* rr seq num reset */ +#endif + +#ifndef ICMP6_MEMBERSHIP_QUERY +#define ICMP6_MEMBERSHIP_QUERY 130 +#endif + +#ifndef ICMP6_MEMBERSHIP_REPORT +#define ICMP6_MEMBERSHIP_REPORT 131 +#endif + +#ifndef ICMP6_MEMBERSHIP_REDUCTION +#define ICMP6_MEMBERSHIP_REDUCTION 132 +#endif + +#ifndef ICMP6_DST_UNREACH_NOTNEIGHBOR +#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor */ +#endif + +#ifdef __UCLIBC__ + +#ifndef IP6OPT_PADN +#define IP6OPT_PADN 1 +#endif + +#ifndef ip6_ext +struct ip6_ext +{ + uint8_t ip6e_nxt; + uint8_t ip6e_len; +}; +#endif +#endif + +#ifdef WIN32 +struct ip6_hdr + { + union + { + struct ip6_hdrctl + { + uint32_t ip6_un1_flow; /* 4 bits version, 8 bits TC, + 20 bits flow-ID */ + uint16_t ip6_un1_plen; /* payload length */ + uint8_t ip6_un1_nxt; /* next header */ + uint8_t ip6_un1_hlim; /* hop limit */ + } ip6_un1; + uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits tclass */ + } ip6_ctlun; + struct in6_addr ip6_src; /* source address */ + struct in6_addr ip6_dst; /* destination address */ + }; +#define ICMP6_DST_UNREACH 1 +#define ICMP6_TIME_EXCEEDED 3 +#define ICMP6_PARAM_PROB 4 + +#define ip6_vfc ip6_ctlun.ip6_un2_vfc +#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen +#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt +#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim + +#define IP6OPT_PADN 1 + +/* Hop-by-Hop options header. */ +struct ip6_hbh + { + uint8_t ip6h_nxt; /* next header. */ + uint8_t ip6h_len; /* length in units of 8 octets. */ + /* followed by options */ + }; + +#endif + + +/* From linux/net/ipv6/mcast.c */ + +/* + * These header formats should be in a separate include file, but icmpv6.h + * doesn't have in6_addr defined in all cases, there is no __u128, and no + * other files reference these. + * + * +-DLS 4/14/03 + * + * Multicast Listener Discovery version 2 headers + * Modified as they are where not ANSI C compliant + */ +struct mld2_grec +{ + __u8 grec_type; + __u8 grec_auxwords; + __u16 grec_nsrcs; + struct in6_addr grec_mca; +/* struct in6_addr grec_src[0]; */ +}; + +struct mld2_report +{ + __u8 type; + __u8 resv1; + __u16 csum; + __u16 resv2; + __u16 ngrec; +/* struct mld2_grec grec[0]; */ +}; + +struct mld2_query +{ + __u8 type; + __u8 code; + __u16 csum; + __u16 mrc; + __u16 resv1; + struct in6_addr mca; +#if defined(__LITTLE_ENDIAN_BITFIELD) + uint32_t qrv:3, suppress:1, resv2:4; +#elif defined(__BIG_ENDIAN_BITFIELD) + uint32_t resv2:4, suppress:1, qrv:3; +#else +#error "Please fix <asm/byteorder.h>" +#endif + __u8 qqic; + __u16 nsrcs; +/* struct in6_addr srcs[0]; */ +}; + +#define IGMP6_UNSOLICITED_IVAL (10*HZ) +#define MLD_QRV_DEFAULT 2 + +#define MLD_V1_SEEN(idev) ((idev)->mc_v1_seen && \ + time_before(jiffies, (idev)->mc_v1_seen)) + +#define MLDV2_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value)) +#define MLDV2_EXP(thresh, nbmant, nbexp, value) \ + ((value) < (thresh) ? (value) : \ + ((MLDV2_MASK(value, nbmant) | (1<<(nbmant+nbexp))) << \ + (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp)))) + +#define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value) +#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) + +#define bool int + +#define RAW_RX_BUF_SIZE 1024*1024 + +struct lookup +{ + unsigned int num; + const char *desc; +}; + +/* Our configuration structure */ +struct conf +{ + unsigned int maxinterfaces; /* The max number of interfaces the array can hold */ + struct intnode *ints; /* The interfaces we are watching */ + + struct mc_group *groups; + + bool quit; /* Global Quit signal */ + + bool promisc; /* Make interfaces promisc? (To be sure to receive all MLD's) */ + bool mode; /* Streamer 0 /Client mode 1 */ + + uint8_t *buffer; /* Our buffer */ + unsigned int bufferlen; /* Length of the buffer */ + + int rawsocket; /* Single RAW socket for sending and receiving everything */ + + unsigned int stat_packets_received; /* Number of packets received */ + unsigned int stat_packets_sent; /* Number of packets forwarded */ + unsigned int stat_bytes_received; /* Number of bytes received */ + unsigned int stat_bytes_sent; /* Number of bytes forwarded */ + unsigned int stat_icmp_received; /* Number of ICMP's received */ + unsigned int stat_icmp_sent; /* Number of ICMP's sent */ + + unsigned int mca_groups; + unsigned int subscribers; + cmdline_t *cmd; +#ifdef SERVER + tuner_t *tuner_parms; + int tuner_number; + + satellite_list_t *sat_list; + int sat_list_num; + int readconfig; + pthread_t mld_timer_thread; + pthread_t collect_stats_thread; + pthread_t stream_tca_thread; + pthread_t stream_tra_thread; + + int tca_id; +#endif + + pthread_mutex_t lock; +}; + +/* Global Stuff */ +extern struct conf *g_conf; +extern struct lookup mld2_grec_types[]; + + +const char *lookup (struct lookup *l, unsigned int num); +const char *icmpv6_type (unsigned int type); +const char *icmpv6_code (unsigned int type, unsigned int code); + +uint16_t ipv6_checksum (const struct ip6_hdr *ip6, uint8_t protocol, const void *data, const uint16_t length); +void sendpacket6 (struct intnode *intn, const struct ip6_hdr *iph, const uint16_t len); +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + +int send_mldv2_report (struct intnode *intn, int grec_number, struct in6_addr *mcas, int srcn, struct in6_addr *sources, int mode); +int start_mld_daemon (void); + +#endif |