mfontanini / libtins

High-level, multiplatform C++ network packet sniffing and crafting library.
http://libtins.github.io/
BSD 2-Clause "Simplified" License
1.89k stars 373 forks source link

Hello World send / receive #492

Open fghoussen opened 1 year ago

fghoussen commented 1 year ago

Hello World send / receive doesn't work?!... Or, more probably, I can't get it to work! :(

I am new to network related stuffs (I had a hard time to learn basics about OSI model and various protocols - not sure to get all right... so reading the doc is not always easy) and barely know about pcap. I am trying to send / recv a payload in a TCP / IP packet. Even after reading the doc, I can't get that to work... So hoping to get some help here.

Code of the sender:

>> cat packet_sender.cpp 
/*
 * Using libtins to send / receive custom data / protocol.
 *
 * Need sudo rights:
 * >> sudo ./packet_receiver
 * >> sudo ./packet_sender
 */

#include <iostream>
#include <cstdlib>
#include <string>

#include <tins/tins.h>

using namespace std;

bool send(Tins::PacketSender &sender,
          const string &ip, const int &port,
          const string &iface) {
  // Send packets.
  while (1) {
    string payload;
    cout << "Enter payload: "; // Let user define a message as payload.
    cin >> payload;
    Tins::IP pkt = Tins::IP(ip) / Tins::TCP(port) / Tins::RawPDU(payload);
    // FIXME: send seems not to work? Why?
    sender.send(pkt, iface);
  }
}

int main(int argc, char ** argv) {
  // Handle command line arguments.
  string ip = "127.0.0.1"; // Default IP.
  int port = 123; // Default port.
  string iface = "eth0"; // Default interface.
  for (int i = 0; i < argc; i++) {
    string option = argv[i];
    if (option == "--ip") {i++; ip = argv[i];}
    if (option == "--port") {i++; port = atoi(argv[i]);}
    if (option == "--iface") {i++; iface = argv[i];}
  }
  cout << "ip " << ip << endl;
  cout << "port " << port << endl;
  cout << "iface " << iface << endl;

  // Send packets.
  Tins::PacketSender sender;
  send(sender, ip, port, iface);

  return 0;
}

Code of the receiver:

>> cat packet_receiver.cpp 
/*
 * Using libtins to send / receive custom data / protocol.
 *
 * Need sudo rights:
 * >> sudo ./packet_receiver
 * >> sudo ./packet_sender
 */

#include <iostream>
#include <cstdlib>
#include <string>
#include <sstream>

#include <tins/tins.h>

using namespace std;

bool receive(const Tins::PDU &pdu) {
  // Find the IP layer.
  const Tins::IP &ip = pdu.rfind_pdu<Tins::IP>();
  // Find the TCP layer.
  const Tins::TCP &tcp = pdu.rfind_pdu<Tins::TCP>();
  // Find the payload.
  const Tins::RawPDU &raw = pdu.rfind_pdu<Tins::RawPDU>();

  // Print received packet and associated payload.
  string payload = ""; // FIXME: how to get payload from raw?
  cout << ip.src_addr() << ':' << tcp.sport() << " -> ";
  cout << "payload: " << payload;
  cout << " -> " << ip.dst_addr() << ':' << tcp.dport() << endl;
  return true;
}

int main(int argc, char ** argv) {
  // Handle command line arguments.
  string ip = "127.0.0.1"; // Default IP.
  int port = 123; // Default port.
  string iface = "eth0"; // Default interface.
  for (int i = 0; i < argc; i++) {
    string option = argv[i];
    if (option == "--ip") {i++; ip = argv[i];}
    if (option == "--port") {i++; port = atoi(argv[i]);}
    if (option == "--iface") {i++; iface = argv[i];}
  }
  cout << "ip " << ip << endl;
  cout << "port " << port << endl;
  cout << "iface " << iface << endl;

  // Receive packets.
  Tins::SnifferConfiguration config;
  config.set_promisc_mode(true); // Show all data going over the network.
  config.set_immediate_mode(true); // Receive packets as soon as possible (no buffering).
  config.set_filter("ip src " + ip);
  stringstream ssport; ssport << port;
  config.set_filter("port " + ssport.str());
  Tins::Sniffer sniffer(iface, config);
  sniffer.sniff_loop(receive);

  return 0;
}

Running with sudo sender and receiver:

>> sudo ./packet_sender 
ip 127.0.0.1
port 123
iface eth0
Enter payload: hello
Enter payload: world
Enter payload: 

>> sudo ./packet_receiver 
ip 127.0.0.1
port 123
iface eth0

The expected result is that "hello" and "world" appears at the receiver side... But Nothing shows up?! Using wlan0 doesn't help.

I have 2 questions about why this doesn't work:

>> grep FIXME *.cpp
packet_receiver.cpp:27:  string payload = ""; // FIXME: how to get payload from raw?
packet_sender.cpp:26:    // FIXME: send seems not to work? Why?

Any help is appreciated! Question may look like a rooky one... But it's actually a difficult one for me as I do not know much/enough about networking... What's wrong/missing in this code?

Note: running debian.