Просмотр исходного кода

IGMP protocol now uses the generic background protocol mechanism.

tags/v0.9.3
Michael Brown 19 лет назад
Родитель
Сommit
be7897523d
4 измененных файлов: 37 добавлений и 178 удалений
  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 Просмотреть файл

@@ -21,13 +21,10 @@ Literature dealing with the network protocols:
21 21
 #include "resolv.h"
22 22
 #include "dev.h"
23 23
 #include "nic.h"
24
+#include "background.h"
24 25
 #include "elf.h" /* FOR EM_CURRENT */
25 26
 
26 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 28
 /* Put rom_info in .nocompress section so romprefix.S can write to it */
32 29
 struct rom_info	rom __attribute__ ((section (".text16.nocompress"))) = {0,0};
33 30
 static unsigned long	netmask;
@@ -827,140 +824,6 @@ uint16_t tcpudpchksum(struct iphdr *ip)
827 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 828
 #include "proto_eth_slow.c"
966 829
 
@@ -985,8 +848,8 @@ int await_reply(reply_t reply, int ival, void *ptr, long timeout)
985 848
 	 */
986 849
 	for (;;) {
987 850
 		now = currticks();
851
+		background_send(now);
988 852
 		send_eth_slow_reports(now);
989
-		send_igmp_reports(now);
990 853
 		result = eth_poll(1);
991 854
 		if (result == 0) {
992 855
 			/* We don't have anything */
@@ -1104,8 +967,8 @@ int await_reply(reply_t reply, int ival, void *ptr, long timeout)
1104 967
 #endif	/* MDEBUG */
1105 968
 			}
1106 969
 		}
970
+		background_process(now, ptype, ip);
1107 971
 		process_eth_slow(ptype, now);
1108
-		process_igmp(ip, now);
1109 972
 	}
1110 973
 	return(0);
1111 974
 }
@@ -1297,20 +1160,4 @@ long rfc2131_sleep_interval(long base, int exp)
1297 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 Просмотреть файл

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

+ 26
- 7
src/include/igmp.h Просмотреть файл

@@ -1,5 +1,8 @@
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 7
 #define IGMP_QUERY	0x11
5 8
 #define IGMPv1_REPORT	0x12
@@ -7,11 +10,19 @@
7 10
 #define IGMP_LEAVE	0x17
8 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 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 26
 } PACKED;
16 27
 
17 28
 struct igmp_ip_t { /* Format of an igmp ip packet */
@@ -20,4 +31,12 @@ struct igmp_ip_t { /* Format of an igmp ip packet */
20 31
 	struct igmp igmp;
21 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 Просмотреть файл

@@ -5,6 +5,7 @@
5 5
 
6 6
 #include "ip.h"
7 7
 #include "igmp.h"
8
+#include "background.h"
8 9
 #include "nic.h"
9 10
 #include "etherboot.h"
10 11
 
@@ -56,7 +57,8 @@ static void send_igmp_reports ( unsigned long now ) {
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 62
 	struct igmp *igmp;
61 63
 	int i;
62 64
 	unsigned iplen;
@@ -110,6 +112,11 @@ static void process_igmp ( struct iphdr *ip, unsigned long now ) {
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 120
 void leave_group ( int slot ) {
114 121
 	/* Be very stupid and always send a leave group message if 
115 122
 	 * I have subscribed.  Imperfect but it is standards
@@ -157,4 +164,3 @@ void join_group ( int slot, unsigned long group ) {
157 164
 		igmptable[slot].time = currticks();
158 165
 	}
159 166
 }
160
-

Загрузка…
Отмена
Сохранить