|
@@ -1,167 +0,0 @@
|
1
|
|
-/*
|
2
|
|
- * Eric Biederman wrote this code originally.
|
3
|
|
- *
|
4
|
|
- */
|
5
|
|
-
|
6
|
|
-#if 0
|
7
|
|
-
|
8
|
|
-#include <ip.h>
|
9
|
|
-#include <igmp.h>
|
10
|
|
-
|
11
|
|
-static unsigned long last_igmpv1 = 0;
|
12
|
|
-static struct igmptable_t igmptable[MAX_IGMP];
|
13
|
|
-
|
14
|
|
-static long rfc1112_sleep_interval ( long base, int exp ) {
|
15
|
|
- unsigned long divisor, tmo;
|
16
|
|
-
|
17
|
|
- if ( exp > BACKOFF_LIMIT )
|
18
|
|
- exp = BACKOFF_LIMIT;
|
19
|
|
- divisor = RAND_MAX / ( base << exp );
|
20
|
|
- tmo = random() / divisor;
|
21
|
|
- return tmo;
|
22
|
|
-}
|
23
|
|
-
|
24
|
|
-static void send_igmp_reports ( unsigned long now ) {
|
25
|
|
- struct igmp_ip_t igmp;
|
26
|
|
- int i;
|
27
|
|
-
|
28
|
|
- for ( i = 0 ; i < MAX_IGMP ; i++ ) {
|
29
|
|
- if ( ! igmptable[i].time )
|
30
|
|
- continue;
|
31
|
|
- if ( now < igmptable[i].time )
|
32
|
|
- continue;
|
33
|
|
-
|
34
|
|
- igmp.router_alert[0] = 0x94;
|
35
|
|
- igmp.router_alert[1] = 0x04;
|
36
|
|
- igmp.router_alert[2] = 0;
|
37
|
|
- igmp.router_alert[3] = 0;
|
38
|
|
- build_ip_hdr ( igmptable[i].group.s_addr, 1, IP_IGMP,
|
39
|
|
- sizeof ( igmp.router_alert ),
|
40
|
|
- sizeof ( igmp ), &igmp );
|
41
|
|
- igmp.igmp.type = IGMPv2_REPORT;
|
42
|
|
- if ( last_igmpv1 &&
|
43
|
|
- ( now < last_igmpv1 + IGMPv1_ROUTER_PRESENT_TIMEOUT ) ) {
|
44
|
|
- igmp.igmp.type = IGMPv1_REPORT;
|
45
|
|
- }
|
46
|
|
- igmp.igmp.response_time = 0;
|
47
|
|
- igmp.igmp.chksum = 0;
|
48
|
|
- igmp.igmp.group.s_addr = igmptable[i].group.s_addr;
|
49
|
|
- igmp.igmp.chksum = ipchksum ( &igmp.igmp,
|
50
|
|
- sizeof ( igmp.igmp ) );
|
51
|
|
- ip_transmit ( sizeof ( igmp ), &igmp );
|
52
|
|
- DBG ( "IGMP sent report to %s\n", inet_ntoa ( igmp.igmp.group ) );
|
53
|
|
- /* Don't send another igmp report until asked */
|
54
|
|
- igmptable[i].time = 0;
|
55
|
|
- }
|
56
|
|
-}
|
57
|
|
-
|
58
|
|
-static void process_igmp ( unsigned long now, unsigned short ptype __unused,
|
59
|
|
- struct iphdr *ip ) {
|
60
|
|
- struct igmp *igmp;
|
61
|
|
- int i;
|
62
|
|
- unsigned iplen;
|
63
|
|
-
|
64
|
|
- if ( ( ! ip ) || ( ip->protocol != IP_IGMP ) ||
|
65
|
|
- ( nic.packetlen < ( sizeof ( struct iphdr ) +
|
66
|
|
- sizeof ( struct igmp ) ) ) ) {
|
67
|
|
- return;
|
68
|
|
- }
|
69
|
|
-
|
70
|
|
- iplen = ( ip->verhdrlen & 0xf ) * 4;
|
71
|
|
- igmp = ( struct igmp * ) &nic.packet[ sizeof( struct iphdr ) ];
|
72
|
|
- if ( ipchksum ( igmp, ntohs ( ip->len ) - iplen ) != 0 )
|
73
|
|
- return;
|
74
|
|
-
|
75
|
|
- if ( ( igmp->type == IGMP_QUERY ) &&
|
76
|
|
- ( ip->dest.s_addr == htonl ( GROUP_ALL_HOSTS ) ) ) {
|
77
|
|
- unsigned long interval = IGMP_INTERVAL;
|
78
|
|
-
|
79
|
|
- if ( igmp->response_time == 0 ) {
|
80
|
|
- last_igmpv1 = now;
|
81
|
|
- } else {
|
82
|
|
- interval = ( igmp->response_time * TICKS_PER_SEC ) /10;
|
83
|
|
- }
|
84
|
|
-
|
85
|
|
- DBG ( "IGMP received query for %s\n", inet_ntoa ( igmp->group ) );
|
86
|
|
- for ( i = 0 ; i < MAX_IGMP ; i++ ) {
|
87
|
|
- uint32_t group = igmptable[i].group.s_addr;
|
88
|
|
- if ( ( group == 0 ) ||
|
89
|
|
- ( group == igmp->group.s_addr ) ) {
|
90
|
|
- unsigned long time;
|
91
|
|
- time = currticks() +
|
92
|
|
- rfc1112_sleep_interval ( interval, 0 );
|
93
|
|
- if ( time < igmptable[i].time ) {
|
94
|
|
- igmptable[i].time = time;
|
95
|
|
- }
|
96
|
|
- }
|
97
|
|
- }
|
98
|
|
- }
|
99
|
|
- if ( ( ( igmp->type == IGMPv1_REPORT ) ||
|
100
|
|
- ( igmp->type == IGMPv2_REPORT ) ) &&
|
101
|
|
- ( ip->dest.s_addr == igmp->group.s_addr ) ) {
|
102
|
|
- DBG ( "IGMP received report for %s\n",
|
103
|
|
- inet_ntoa ( igmp->group ) );
|
104
|
|
- for ( i = 0 ; i < MAX_IGMP ; i++ ) {
|
105
|
|
- if ( ( igmptable[i].group.s_addr ==
|
106
|
|
- igmp->group.s_addr ) &&
|
107
|
|
- ( igmptable[i].time != 0 ) ) {
|
108
|
|
- igmptable[i].time = 0;
|
109
|
|
- }
|
110
|
|
- }
|
111
|
|
- }
|
112
|
|
-}
|
113
|
|
-
|
114
|
|
-struct background igmp_background __background = {
|
115
|
|
- .send = send_igmp_reports,
|
116
|
|
- .process = process_igmp,
|
117
|
|
-};
|
118
|
|
-
|
119
|
|
-void leave_group ( int slot ) {
|
120
|
|
- /* Be very stupid and always send a leave group message if
|
121
|
|
- * I have subscribed. Imperfect but it is standards
|
122
|
|
- * compliant, easy and reliable to implement.
|
123
|
|
- *
|
124
|
|
- * The optimal group leave method is to only send leave when,
|
125
|
|
- * we were the last host to respond to a query on this group,
|
126
|
|
- * and igmpv1 compatibility is not enabled.
|
127
|
|
- */
|
128
|
|
- if ( igmptable[slot].group.s_addr ) {
|
129
|
|
- struct igmp_ip_t igmp;
|
130
|
|
-
|
131
|
|
- igmp.router_alert[0] = 0x94;
|
132
|
|
- igmp.router_alert[1] = 0x04;
|
133
|
|
- igmp.router_alert[2] = 0;
|
134
|
|
- igmp.router_alert[3] = 0;
|
135
|
|
- build_ip_hdr ( htonl ( GROUP_ALL_HOSTS ), 1, IP_IGMP,
|
136
|
|
- sizeof ( igmp.router_alert ), sizeof ( igmp ),
|
137
|
|
- &igmp);
|
138
|
|
- igmp.igmp.type = IGMP_LEAVE;
|
139
|
|
- igmp.igmp.response_time = 0;
|
140
|
|
- igmp.igmp.chksum = 0;
|
141
|
|
- igmp.igmp.group.s_addr = igmptable[slot].group.s_addr;
|
142
|
|
- igmp.igmp.chksum = ipchksum ( &igmp.igmp, sizeof ( igmp ) );
|
143
|
|
- ip_transmit ( sizeof ( igmp ), &igmp );
|
144
|
|
- DBG ( "IGMP left group %s\n", inet_ntoa ( igmp.igmp.group ) );
|
145
|
|
- }
|
146
|
|
- memset ( &igmptable[slot], 0, sizeof ( igmptable[0] ) );
|
147
|
|
-}
|
148
|
|
-
|
149
|
|
-void join_group ( int slot, unsigned long group ) {
|
150
|
|
- /* I have already joined */
|
151
|
|
- if ( igmptable[slot].group.s_addr == group )
|
152
|
|
- return;
|
153
|
|
- if ( igmptable[slot].group.s_addr ) {
|
154
|
|
- leave_group ( slot );
|
155
|
|
- }
|
156
|
|
- /* Only join a group if we are given a multicast ip, this way
|
157
|
|
- * code can be given a non-multicast (broadcast or unicast ip)
|
158
|
|
- * and still work...
|
159
|
|
- */
|
160
|
|
- if ( ( group & htonl ( MULTICAST_MASK ) ) ==
|
161
|
|
- htonl ( MULTICAST_NETWORK ) ) {
|
162
|
|
- igmptable[slot].group.s_addr = group;
|
163
|
|
- igmptable[slot].time = currticks();
|
164
|
|
- }
|
165
|
|
-}
|
166
|
|
-
|
167
|
|
-#endif
|