]> git.sesse.net Git - multicastwardrive/commitdiff
Initial checkin. master
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 10 Apr 2013 21:25:21 +0000 (23:25 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 10 Apr 2013 21:25:21 +0000 (23:25 +0200)
dump-mcast.cpp [new file with mode: 0644]
multicastwardrive.c [new file with mode: 0644]

diff --git a/dump-mcast.cpp b/dump-mcast.cpp
new file mode 100644 (file)
index 0000000..9dc0c02
--- /dev/null
@@ -0,0 +1,78 @@
+#include <pcap/pcap.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+
+#include <map>
+#include <string>
+
+using namespace std;
+
+struct groupstats {
+       groupstats() : count(0) {}
+
+       int count;
+       struct timeval last_seen;
+};
+map<uint32_t, groupstats> stats;
+
+struct timeval now;
+
+void callback(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
+{
+       now = h->ts;
+
+       const iphdr *ip = (const iphdr *)(bytes + 16);
+       if ((ntohl(ip->daddr) & 0xe0000000) != (224u << 24) ||
+           (ntohl(ip->daddr) & 0xffffff00) == (224u << 24) ||
+            ip->daddr == 0xffffffffu ||
+           ip->protocol != 17) {
+               return;
+       }
+
+       ++stats[ip->daddr].count;
+       stats[ip->daddr].last_seen = h->ts;
+}
+
+double tdiff(const timeval &a, const timeval &b)
+{
+       return (b.tv_sec - a.tv_sec) +
+               1e-6 * (b.tv_usec - a.tv_usec);
+}
+
+void cleanup()
+{
+       for (auto it = stats.begin(); it != stats.end(); ) {
+               if (tdiff(it->second.last_seen, now) < 1.0) {
+                       ++it;
+                       continue;
+               }
+
+               in_addr ip;
+               ip.s_addr = it->first;
+               printf("%s %d\n", inet_ntoa(ip), it->second.count);
+               fflush(stdout);
+               it = stats.erase(it);
+       }
+}
+
+int main(void)
+{
+       char errbuf[PCAP_ERRBUF_SIZE];
+       pcap_t *pcap = pcap_create("any", NULL);
+       if (pcap == NULL) {
+               fprintf(stderr, "pcap_create(): %s\n", errbuf);
+               exit(1);
+       }
+
+       pcap_activate(pcap);
+
+       for ( ;; ) {
+               pcap_dispatch(pcap, 10000, callback, NULL);
+               cleanup();
+               usleep(10000);
+       }
+}
diff --git a/multicastwardrive.c b/multicastwardrive.c
new file mode 100644 (file)
index 0000000..f8208d7
--- /dev/null
@@ -0,0 +1,59 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+
+// #define NETWORK "233.121.29.%d"  // workzone
+// #define NETWORK "233.83.45.%d"   // nrk [tomt]
+// #define NETWORK "233.60.200.%d"   // comvie [tomt]
+// #define NETWORK "239.193.0.%d"   // uninett??
+// #define NETWORK "233.155.107.%d"   // tv2
+#define NETWORK "224.67.163.%d"     // blokk med stortinget i
+
+void join_group(int sock, int i)
+{
+       struct ip_mreqn mreq;
+       // char buf[256];
+       // snprintf(buf, 256, NETWORK, i);
+       // printf("%s\n", buf);
+       //mreq.imr_multiaddr.s_addr = inet_addr(buf);
+
+       mreq.imr_multiaddr.s_addr = i;
+       printf("%s\n", inet_ntoa(mreq.imr_multiaddr));
+       mreq.imr_address.s_addr = INADDR_ANY;
+       mreq.imr_ifindex = 0;
+       setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+}
+
+void leave_group(int sock, int i)
+{
+       struct ip_mreqn mreq;
+       // char buf[256];
+       // snprintf(buf, 256, NETWORK, i);
+       // mreq.imr_multiaddr.s_addr = inet_addr(buf);
+       mreq.imr_multiaddr.s_addr = i;
+       mreq.imr_address.s_addr = INADDR_ANY;
+       mreq.imr_ifindex = 0;
+       setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
+}
+
+int main(int argc, char **argv)
+{
+       int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+       in_addr_t from = inet_addr(argv[1]);
+       in_addr_t to = inet_addr(argv[2]);
+       uint32_t skip = atoi(argv[3]);
+
+       for (in_addr_t i = ntohl(from); i <= ntohl(to); i += skip) {
+               join_group(sock, htonl(i));
+               if (i - ntohl(from) >= 10 * skip) {
+                       leave_group(sock, htonl(i - 10 * skip));
+               }
+               usleep(200000);
+       }
+
+       sleep(2);
+}