Browse Source

IGMP protocol now uses the generic background protocol mechanism.

tags/v0.9.3
Michael Brown 19 years ago
parent
commit
be7897523d
4 changed files with 37 additions and 178 deletions
  1. 3
    156
      src/core/nic.c
  2. 0
    13
      src/include/etherboot.h
  3. 26
    7
      src/include/igmp.h
  4. 8
    2
      src/proto/igmp.c

+ 3
- 156
src/core/nic.c View File

21
 #include "resolv.h"
21
 #include "resolv.h"
22
 #include "dev.h"
22
 #include "dev.h"
23
 #include "nic.h"
23
 #include "nic.h"
24
+#include "background.h"
24
 #include "elf.h" /* FOR EM_CURRENT */
25
 #include "elf.h" /* FOR EM_CURRENT */
25
 
26
 
26
 struct arptable_t	arptable[MAX_ARP];
27
 struct arptable_t	arptable[MAX_ARP];
27
-#if MULTICAST_LEVEL2
28
-unsigned long last_igmpv1 = 0;
29
-struct igmptable_t	igmptable[MAX_IGMP];
30
-#endif
31
 /* Put rom_info in .nocompress section so romprefix.S can write to it */
28
 /* Put rom_info in .nocompress section so romprefix.S can write to it */
32
 struct rom_info	rom __attribute__ ((section (".text16.nocompress"))) = {0,0};
29
 struct rom_info	rom __attribute__ ((section (".text16.nocompress"))) = {0,0};
33
 static unsigned long	netmask;
30
 static unsigned long	netmask;
827
 	return checksum;
824
 	return checksum;
828
 }
825
 }
829
 
826
 
830
-#ifdef MULTICAST_LEVEL2
831
-static void send_igmp_reports(unsigned long now)
832
-{
833
-	int i;
834
-	for(i = 0; i < MAX_IGMP; i++) {
835
-		if (igmptable[i].time && (now >= igmptable[i].time)) {
836
-			struct igmp_ip_t igmp;
837
-			igmp.router_alert[0] = 0x94;
838
-			igmp.router_alert[1] = 0x04;
839
-			igmp.router_alert[2] = 0;
840
-			igmp.router_alert[3] = 0;
841
-			build_ip_hdr(igmptable[i].group.s_addr, 
842
-				1, IP_IGMP, sizeof(igmp.router_alert), sizeof(igmp), &igmp);
843
-			igmp.igmp.type = IGMPv2_REPORT;
844
-			if (last_igmpv1 && 
845
-				(now < last_igmpv1 + IGMPv1_ROUTER_PRESENT_TIMEOUT)) {
846
-				igmp.igmp.type = IGMPv1_REPORT;
847
-			}
848
-			igmp.igmp.response_time = 0;
849
-			igmp.igmp.chksum = 0;
850
-			igmp.igmp.group.s_addr = igmptable[i].group.s_addr;
851
-			igmp.igmp.chksum = ipchksum(&igmp.igmp, sizeof(igmp.igmp));
852
-			ip_transmit(sizeof(igmp), &igmp);
853
-#ifdef	MDEBUG
854
-			printf("Sent IGMP report to: %@\n", igmp.igmp.group.s_addr);
855
-#endif
856
-			/* Don't send another igmp report until asked */
857
-			igmptable[i].time = 0;
858
-		}
859
-	}
860
-}
861
-
862
-static void process_igmp(struct iphdr *ip, unsigned long now)
863
-{
864
-	struct igmp *igmp;
865
-	int i;
866
-	unsigned iplen;
867
-	if (!ip || (ip->protocol == IP_IGMP) ||
868
-		(nic.packetlen < sizeof(struct iphdr) + sizeof(struct igmp))) {
869
-		return;
870
-	}
871
-	iplen = (ip->verhdrlen & 0xf)*4;
872
-	igmp = (struct igmp *)&nic.packet[sizeof(struct iphdr)];
873
-	if (ipchksum(igmp, ntohs(ip->len) - iplen) != 0)
874
-		return;
875
-	if ((igmp->type == IGMP_QUERY) && 
876
-		(ip->dest.s_addr == htonl(GROUP_ALL_HOSTS))) {
877
-		unsigned long interval = IGMP_INTERVAL;
878
-		if (igmp->response_time == 0) {
879
-			last_igmpv1 = now;
880
-		} else {
881
-			interval = (igmp->response_time * TICKS_PER_SEC)/10;
882
-		}
883
-		
884
-#ifdef	MDEBUG
885
-		printf("Received IGMP query for: %@\n", igmp->group.s_addr);
886
-#endif			       
887
-		for(i = 0; i < MAX_IGMP; i++) {
888
-			uint32_t group = igmptable[i].group.s_addr;
889
-			if ((group == 0) || (group == igmp->group.s_addr)) {
890
-				unsigned long time;
891
-				time = currticks() + rfc1112_sleep_interval(interval, 0);
892
-				if (time < igmptable[i].time) {
893
-					igmptable[i].time = time;
894
-				}
895
-			}
896
-		}
897
-	}
898
-	if (((igmp->type == IGMPv1_REPORT) || (igmp->type == IGMPv2_REPORT)) &&
899
-		(ip->dest.s_addr == igmp->group.s_addr)) {
900
-#ifdef	MDEBUG
901
-		printf("Received IGMP report for: %@\n", igmp->group.s_addr);
902
-#endif			       
903
-		for(i = 0; i < MAX_IGMP; i++) {
904
-			if ((igmptable[i].group.s_addr == igmp->group.s_addr) &&
905
-				igmptable[i].time != 0) {
906
-				igmptable[i].time = 0;
907
-			}
908
-		}
909
-	}
910
-}
911
-
912
-void leave_group(int slot)
913
-{
914
-	/* Be very stupid and always send a leave group message if 
915
-	 * I have subscribed.  Imperfect but it is standards
916
-	 * compliant, easy and reliable to implement.
917
-	 *
918
-	 * The optimal group leave method is to only send leave when,
919
-	 * we were the last host to respond to a query on this group,
920
-	 * and igmpv1 compatibility is not enabled.
921
-	 */
922
-	if (igmptable[slot].group.s_addr) {
923
-		struct igmp_ip_t igmp;
924
-		igmp.router_alert[0] = 0x94;
925
-		igmp.router_alert[1] = 0x04;
926
-		igmp.router_alert[2] = 0;
927
-		igmp.router_alert[3] = 0;
928
-		build_ip_hdr(htonl(GROUP_ALL_HOSTS),
929
-			1, IP_IGMP, sizeof(igmp.router_alert), sizeof(igmp), &igmp);
930
-		igmp.igmp.type = IGMP_LEAVE;
931
-		igmp.igmp.response_time = 0;
932
-		igmp.igmp.chksum = 0;
933
-		igmp.igmp.group.s_addr = igmptable[slot].group.s_addr;
934
-		igmp.igmp.chksum = ipchksum(&igmp.igmp, sizeof(igmp));
935
-		ip_transmit(sizeof(igmp), &igmp);
936
-#ifdef	MDEBUG
937
-		printf("Sent IGMP leave for: %@\n", igmp.igmp.group.s_addr);
938
-#endif	
939
-	}
940
-	memset(&igmptable[slot], 0, sizeof(igmptable[0]));
941
-}
942
-
943
-void join_group(int slot, unsigned long group)
944
-{
945
-	/* I have already joined */
946
-	if (igmptable[slot].group.s_addr == group)
947
-		return;
948
-	if (igmptable[slot].group.s_addr) {
949
-		leave_group(slot);
950
-	}
951
-	/* Only join a group if we are given a multicast ip, this way
952
-	 * code can be given a non-multicast (broadcast or unicast ip)
953
-	 * and still work... 
954
-	 */
955
-	if ((group & htonl(MULTICAST_MASK)) == htonl(MULTICAST_NETWORK)) {
956
-		igmptable[slot].group.s_addr = group;
957
-		igmptable[slot].time = currticks();
958
-	}
959
-}
960
-#else
961
-#define send_igmp_reports(now) do {} while(0)
962
-#define process_igmp(ip, now)  do {} while(0)
963
-#endif
964
 
827
 
965
 #include "proto_eth_slow.c"
828
 #include "proto_eth_slow.c"
966
 
829
 
985
 	 */
848
 	 */
986
 	for (;;) {
849
 	for (;;) {
987
 		now = currticks();
850
 		now = currticks();
851
+		background_send(now);
988
 		send_eth_slow_reports(now);
852
 		send_eth_slow_reports(now);
989
-		send_igmp_reports(now);
990
 		result = eth_poll(1);
853
 		result = eth_poll(1);
991
 		if (result == 0) {
854
 		if (result == 0) {
992
 			/* We don't have anything */
855
 			/* We don't have anything */
1104
 #endif	/* MDEBUG */
967
 #endif	/* MDEBUG */
1105
 			}
968
 			}
1106
 		}
969
 		}
970
+		background_process(now, ptype, ip);
1107
 		process_eth_slow(ptype, now);
971
 		process_eth_slow(ptype, now);
1108
-		process_igmp(ip, now);
1109
 	}
972
 	}
1110
 	return(0);
973
 	return(0);
1111
 }
974
 }
1297
 	return tmo;
1160
 	return tmo;
1298
 }
1161
 }
1299
 
1162
 
1300
-#ifdef MULTICAST_LEVEL2
1301
-/**************************************************************************
1302
-RFC1112_SLEEP_INTERVAL - sleep for expotentially longer times, up to (base << exp)
1303
-**************************************************************************/
1304
-long rfc1112_sleep_interval(long base, int exp)
1305
-{
1306
-	unsigned long divisor, tmo;
1307
-#ifdef BACKOFF_LIMIT
1308
-	if (exp > BACKOFF_LIMIT)
1309
-		exp = BACKOFF_LIMIT;
1310
-#endif
1311
-	divisor = RAND_MAX/(base << exp);
1312
-	tmo = random()/divisor;
1313
-	return tmo;
1314
-}
1315
-#endif /* MULTICAST_LEVEL_2 */
1316
 
1163
 

+ 0
- 13
src/include/etherboot.h View File

130
 	MAX_ARP
130
 	MAX_ARP
131
 };
131
 };
132
 
132
 
133
-#define IGMP_SERVER	0
134
-#define MAX_IGMP	IGMP_SERVER+1
135
-
136
 #define	RARP_REQUEST	3
133
 #define	RARP_REQUEST	3
137
 #define	RARP_REPLY	4
134
 #define	RARP_REPLY	4
138
 
135
 
139
 #include	"in.h"
136
 #include	"in.h"
140
 
137
 
141
-#define MULTICAST_MASK    0xF0000000
142
-#define MULTICAST_NETWORK 0xE0000000
143
 
138
 
144
 /* Helper macros used to identify when DHCP options are valid/invalid in/outside of encapsulation */
139
 /* Helper macros used to identify when DHCP options are valid/invalid in/outside of encapsulation */
145
 #define NON_ENCAP_OPT in_encapsulated_options == 0 &&
140
 #define NON_ENCAP_OPT in_encapsulated_options == 0 &&
164
 	uint8_t node[6];
159
 	uint8_t node[6];
165
 } PACKED;
160
 } PACKED;
166
 
161
 
167
-struct igmptable_t {
168
-	in_addr group;
169
-	unsigned long time;
170
-} PACKED;
171
-
172
 #define	KERNEL_BUF	(BOOTP_DATA_ADDR->bootp_reply.bp_file)
162
 #define	KERNEL_BUF	(BOOTP_DATA_ADDR->bootp_reply.bp_file)
173
 
163
 
174
 #define	FLOPPY_BOOT_LOCATION	0x7c00
164
 #define	FLOPPY_BOOT_LOCATION	0x7c00
214
 typedef int (*reply_t)(int ival, void *ptr, unsigned short ptype, struct iphdr *ip, struct udphdr *udp, struct tcphdr *tcp);
204
 typedef int (*reply_t)(int ival, void *ptr, unsigned short ptype, struct iphdr *ip, struct udphdr *udp, struct tcphdr *tcp);
215
 extern int await_reply P((reply_t reply,	int ival, void *ptr, long timeout));
205
 extern int await_reply P((reply_t reply,	int ival, void *ptr, long timeout));
216
 extern int decode_rfc1533 P((unsigned char *, unsigned int, unsigned int, int));
206
 extern int decode_rfc1533 P((unsigned char *, unsigned int, unsigned int, int));
217
-extern void join_group(int slot, unsigned long group);
218
-extern void leave_group(int slot);
219
 #define RAND_MAX 2147483647L
207
 #define RAND_MAX 2147483647L
220
 extern uint16_t ipchksum P((const void *ip, unsigned long len));
208
 extern uint16_t ipchksum P((const void *ip, unsigned long len));
221
 extern uint16_t add_ipchksums P((unsigned long offset, uint16_t sum, uint16_t new));
209
 extern uint16_t add_ipchksums P((unsigned long offset, uint16_t sum, uint16_t new));
222
 extern int32_t random P((void));
210
 extern int32_t random P((void));
223
 extern long rfc2131_sleep_interval P((long base, int exp));
211
 extern long rfc2131_sleep_interval P((long base, int exp));
224
-extern long rfc1112_sleep_interval P((long base, int exp));
225
 extern void cleanup P((void));
212
 extern void cleanup P((void));
226
 
213
 
227
 /* osloader.c */
214
 /* osloader.c */

+ 26
- 7
src/include/igmp.h View File

1
-#ifndef	_IGMP_H
2
-#define	_IGMP_H
1
+#ifndef	IGMP_H
2
+#define	IGMP_H
3
+
4
+#include "stdint.h"
5
+#include "in.h"
3
 
6
 
4
 #define IGMP_QUERY	0x11
7
 #define IGMP_QUERY	0x11
5
 #define IGMPv1_REPORT	0x12
8
 #define IGMPv1_REPORT	0x12
7
 #define IGMP_LEAVE	0x17
10
 #define IGMP_LEAVE	0x17
8
 #define GROUP_ALL_HOSTS 0xe0000001 /* 224.0.0.1 Host byte order */
11
 #define GROUP_ALL_HOSTS 0xe0000001 /* 224.0.0.1 Host byte order */
9
 
12
 
13
+#define MULTICAST_MASK    0xf0000000
14
+#define MULTICAST_NETWORK 0xe0000000
15
+
16
+enum {
17
+	IGMP_SERVER,
18
+	MAX_IGMP
19
+};
20
+
10
 struct igmp {
21
 struct igmp {
11
-	uint8_t  type;
12
-	uint8_t  response_time;
13
-	uint16_t chksum;
14
-	in_addr group;
22
+	uint8_t		type;
23
+	uint8_t		response_time;
24
+	uint16_t	chksum;
25
+	struct in_addr	group;
15
 } PACKED;
26
 } PACKED;
16
 
27
 
17
 struct igmp_ip_t { /* Format of an igmp ip packet */
28
 struct igmp_ip_t { /* Format of an igmp ip packet */
20
 	struct igmp igmp;
31
 	struct igmp igmp;
21
 } PACKED;
32
 } PACKED;
22
 
33
 
23
-#endif	/* _IGMP_H */
34
+struct igmptable_t {
35
+	struct in_addr group;
36
+	unsigned long time;
37
+} PACKED;
38
+
39
+extern void join_group ( int slot, unsigned long group );
40
+extern void leave_group ( int slot );
41
+
42
+#endif	/* IGMP_H */

+ 8
- 2
src/proto/igmp.c View File

5
 
5
 
6
 #include "ip.h"
6
 #include "ip.h"
7
 #include "igmp.h"
7
 #include "igmp.h"
8
+#include "background.h"
8
 #include "nic.h"
9
 #include "nic.h"
9
 #include "etherboot.h"
10
 #include "etherboot.h"
10
 
11
 
56
 	}
57
 	}
57
 }
58
 }
58
 
59
 
59
-static void process_igmp ( struct iphdr *ip, unsigned long now ) {
60
+static void process_igmp ( unsigned long now, unsigned short ptype __unused,
61
+			   struct iphdr *ip ) {
60
 	struct igmp *igmp;
62
 	struct igmp *igmp;
61
 	int i;
63
 	int i;
62
 	unsigned iplen;
64
 	unsigned iplen;
110
 	}
112
 	}
111
 }
113
 }
112
 
114
 
115
+static struct background igmp_background __background = {
116
+	.send = send_igmp_reports,
117
+	.process = process_igmp,
118
+};
119
+
113
 void leave_group ( int slot ) {
120
 void leave_group ( int slot ) {
114
 	/* Be very stupid and always send a leave group message if 
121
 	/* Be very stupid and always send a leave group message if 
115
 	 * I have subscribed.  Imperfect but it is standards
122
 	 * I have subscribed.  Imperfect but it is standards
157
 		igmptable[slot].time = currticks();
164
 		igmptable[slot].time = currticks();
158
 	}
165
 	}
159
 }
166
 }
160
-

Loading…
Cancel
Save