aboutsummaryrefslogtreecommitdiff
path: root/capture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'capture.cpp')
-rw-r--r--capture.cpp108
1 files changed, 108 insertions, 0 deletions
diff --git a/capture.cpp b/capture.cpp
new file mode 100644
index 0000000..7e51fcd
--- /dev/null
+++ b/capture.cpp
@@ -0,0 +1,108 @@
+#include <iostream>
+#include "wifi-triangulator/core.h"
+#include "wifi-triangulator.pb.h"
+
+#include <sstream>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <exception>
+#include <cstring>
+
+using namespace std;
+using namespace wifi_triangulator;
+
+class output {
+public:
+ virtual void handle(const data &) = 0;
+};
+
+class human_output : public output {
+public:
+ void handle(const data &data) {
+ printf("timestamp=%lu, rssi=%d, src=%s, dst=%s, type=%s\n", ((data.sec * 1000 * 1000) + data.usec) * 1000,
+ data.rssi, data.src.to_string().c_str(), data.dst.to_string().c_str(), to_string(data.type).c_str());
+ fflush(stdout);
+ };
+};
+
+class protobuf_output : public output {
+ int s;
+ struct sockaddr_in addr_si;
+ struct sockaddr *addr;
+ socklen_t addr_len;
+
+public:
+ protobuf_output(string host, uint16_t port) {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+ throw std::runtime_error("socket");
+
+
+ memset((char *) &addr_si, 0, sizeof(addr_si));
+ addr_si.sin_family = AF_INET;
+ addr_si.sin_port = htons(port);
+ if (inet_aton(host.c_str(), &addr_si.sin_addr) == 0) {
+ throw std::runtime_error("inet_aton() failed");
+ }
+
+ addr = reinterpret_cast<struct sockaddr *>(&addr_si);
+ addr_len = sizeof(addr_si);
+ }
+
+ ~protobuf_output() {
+ google::protobuf::ShutdownProtobufLibrary();
+ }
+
+ void handle(const data &data) override {
+ pb::envelope envelope;
+ envelope.set_type(data.type);
+
+ if (data.type == pb::packet_type::probe_request) {
+ pb::probe *probe = envelope.mutable_probe();
+ probe->set_src(data.src);
+ probe->set_dst(static_cast<uint64_t>(data.dst));
+ probe->set_rssi(data.rssi);
+ }
+
+ std::string str;
+ envelope.SerializeToString(&str);
+
+ if (sendto(s, str.c_str(), str.length(), 0, addr, addr_len) == -1) {
+ throw std::runtime_error("sendto failed");
+ }
+ cout << flush;
+
+ static int count = 0;
+ cerr << "count=" << count << ", len=" << str.length() << "!\r" << flush;
+ count++;
+ }
+};
+
+bool human = false;
+
+int main(int argc, char *argv[]) {
+ if (argc != 3) {
+ fprintf(stderr, "usage: %s [interface] [host]\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ string dev = argv[1];
+ string host = argv[2];
+
+ output *output;
+ if (human) {
+ output = new human_output;
+ } else {
+ cerr << "Sending to stdout" << flush << endl;
+ output = new protobuf_output(host, 3333);
+ }
+
+ return launch_capture(dev, [&](const data &data) {
+ output->handle(data);
+ });
+}