|
@@ -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
|
|