summaryrefslogtreecommitdiff
path: root/mcast/netcv2dvbip/igmp.h
blob: 9032e833302467aa22e6c1420a6310bfb7a587bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#ifndef __IGMP_H
#define __IGMP_H

#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif

#include "clist.h"
#include "thread.h"
#include "misc.h"
#include "iface.h"

#define IGMPV1_MEMBERSHIP_REPORT    0x12    /* Ver. 1 membership report */
#define IGMPV2_MEMBERSHIP_REPORT    0x16    /* Ver. 2 membership report */
#define IGMPV2_LEAVE_GROUP          0x17    /* Leave-group message      */

#define IGMPV3_MR_MODE_IS_INCLUDE   0x01
#define IGMPV3_MR_MODE_IS_EXCLUDE   0x02
#define IGMPV3_MR_CHANGE_TO_INCLUDE 0x03
#define IGMPV3_MR_CHANGE_TO_EXCLUDE 0x04
#define IGMPV3_MR_ALLOW_NEW_SOURCES 0x05
#define IGMPV3_MR_BLOCK_OLD_SOURCES 0x06

class cStream;
class cStreamer;

class cMulticastGroup : public cListObject
{
	public:
		cMulticastGroup(in_addr_t Group);
        in_addr_t group;
		in_addr_t reporter;
		struct timeval timeout;
		struct timeval v1timer;
		struct timeval retransmit;
		cStream* stream;
};

class cIgmpMain;

class cIgmpListener : public cThread
{
	public:
		cIgmpListener(cIgmpMain* igmpmain);

		bool Initialize(iface_t bindif, int table);
		void Destruct(void);
		bool Membership(in_addr_t mcaddr, bool Add);
		void IGMPSendQuery(in_addr_t Group, int Timeout);

	private:
		int m_socket;
		in_addr_t m_bindaddr;

		cIgmpMain* m_IgmpMain;

		void Parse(char*, int);
		
		virtual void Action();	

};

//-------------------------------------------------------------------------------------------------------------------

class cIgmpMain : public cThread
{
	public:
		cIgmpMain(cStreamer* streamer, iface_t bindif, int table);
		~cIgmpMain(void);
		bool StartListener(void);
		void Destruct(void);
		void ProcessIgmpQueryMessage(in_addr_t Group, in_addr_t Sender);
		void ProcessIgmpReportMessage(int type, in_addr_t Group, 
			in_addr_t Sender);
		
	private:
		// Parent streamer
		cStreamer* m_streamer;
		
		// Listener
		cIgmpListener* m_IgmpListener;
		in_addr_t m_bindaddr;
		iface_t m_bindif;
		int m_table;

		cList<cMulticastGroup> m_Groups;
		
		// General Query / Timer
		struct timeval m_GeneralQueryTimer;
		bool m_Querier;
		int m_StartupQueryCount;

		void IGMPStartGeneralQueryTimer();
		void IGMPStartOtherQuerierPresentTimer();
		void IGMPSendGeneralQuery();

		// Group Query / Timer
	        void IGMPStartTimer(cMulticastGroup* Group, in_addr_t Member);
        	void IGMPStartV1HostTimer(cMulticastGroup* Group);
	        void IGMPStartTimerAfterLeave(cMulticastGroup* Group, 
			unsigned int MaxResponseTime);
	        void IGMPStartRetransmitTimer(cMulticastGroup* Group);
	        void IGMPClearRetransmitTimer(cMulticastGroup* Group);
	        void IGMPSendGroupQuery(cMulticastGroup* Group);
	        void IGMPStartMulticast(cMulticastGroup* Group);
	        void IGMPStopMulticast(cMulticastGroup* Group);

		// Main thread 				
		virtual void Action();
		cCondWait m_CondWait;
		int m_stopping;

		// Helper				
		cMulticastGroup* FindGroup(in_addr_t Group) const;
		bool IsGroupinRange(in_addr_t groupaddr);
};

#endif