akaros/tools/packetizer/packetizer.cpp
<<
>>
Prefs
   1#include <net/if.h>
   2#include <net/ethernet.h>
   3#include <netinet/in.h>
   4#include <unistd.h>
   5#include <stdint.h>
   6#include <netdb.h>
   7#include <sys/ioctl.h>
   8#include <sys/time.h>
   9#include <stdio.h>
  10#include <assert.h>
  11#include <packetizer.h>
  12#include <stdexcept>
  13#include <fstream>
  14
  15#ifdef DEBUG_MODE
  16# define debug(...) (__VA_ARGS__)
  17#else
  18# define debug(...) do { } while(0)
  19#endif
  20
  21static __inline uint64_t
  22read_tsc(void)
  23{
  24    uint64_t tsc;
  25    __asm __volatile("rdtsc" : "=A" (tsc));
  26    return tsc;
  27}
  28
  29packetizer::packetizer(const char *target_mac, const char *eth_device, 
  30                             const char *filename)
  31{
  32        seqno = 0;
  33        memcpy(this->target_mac, target_mac, 6);
  34        strcpy(this->eth_device, eth_device);
  35        strcpy(this->filename, filename);
  36        memset(&myaddr, 0, sizeof(myaddr));
  37
  38        // setuid root to open a raw socket.  if we fail, too bad
  39        seteuid(0);
  40        sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
  41        seteuid(getuid());
  42        if(sock < 0)
  43          throw std::runtime_error("socket() failed! Maybe try running as root...");
  44
  45        myaddr.sll_ifindex = if_nametoindex(eth_device);
  46        myaddr.sll_family = AF_PACKET;
  47
  48        int ret = bind(sock, (struct sockaddr *)&myaddr, sizeof(myaddr));
  49        if (ret < 0)
  50          throw std::runtime_error("bind() failed!");
  51
  52        struct timeval tv;
  53        tv.tv_sec = 1;
  54        tv.tv_usec = 0;
  55        if(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(struct timeval)) < 0)
  56          throw std::runtime_error("setsockopt() failed!");
  57
  58        // get MAC address of local ethernet device
  59        struct ifreq ifr;
  60        strcpy(ifr.ifr_name, eth_device);
  61        ret = ioctl(sock, SIOCGIFHWADDR, (char *)&ifr);
  62        if (ret < 0)
  63          throw std::runtime_error("ioctl() failed!");
  64        memcpy(&host_mac, &ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);
  65}
  66
  67int packetizer::start()
  68{
  69        std::ifstream file(filename, std::ios::in | std::ios::binary);
  70        packet p(target_mac, host_mac, seqno, MAX_PAYLOAD_SIZE, NULL);
  71
  72        int ret;
  73        printf("Starting to packetize the file: %s\n", filename);
  74        file.read(p.payload, MAX_PAYLOAD_SIZE);
  75        while(file) {
  76                //printf("Sending chunk %d\n", seqno);
  77                ret = ::sendto(sock, (char*)&p, p.size(), 0,
  78                               (sockaddr*)&myaddr,sizeof(myaddr));
  79                
  80                volatile uint64_t tsc = read_tsc();
  81                while((read_tsc() - tsc) < 34800);
  82                if (ret < 0)
  83                  throw std::runtime_error("sending packet failed!");
  84                p.header.seqno = htons(next_seqno());
  85                file.read(p.payload, MAX_PAYLOAD_SIZE);
  86        }
  87        if(file.gcount()) {
  88                p.header.payload_size = ntohl(file.gcount());
  89                p.packet_size = sizeof(p.header)+file.gcount();
  90                
  91                ret = ::sendto(sock, (char*)&p, p.size(), 0,
  92                               (sockaddr*)&myaddr,sizeof(myaddr));
  93                if (ret < 0)
  94                  throw std::runtime_error("sending packet failed!");
  95                //printf("Sending chunk %d\n", seqno);
  96        }
  97        printf("Last chunk had %u bytes...\n", file.gcount());
  98}
  99
 100int main(int argc, char** argv)
 101{
 102        char target_mac[6];
 103        char eth_device[256];
 104        char filename[256];
 105        if(argc == 1) {
 106                target_mac[0] = 0x00;
 107                target_mac[1] = 0x24;
 108                target_mac[2] = 0x1d;
 109                target_mac[3] = 0x10;
 110                target_mac[4] = 0xa2;
 111                target_mac[5] = 0xb5;
 112                strcpy(eth_device, "eth0");
 113                strcpy(filename, "../../fs/i686/tests/e.y4m");
 114        }
 115        if(argc > 1) {
 116                assert(argc == 4);
 117                assert(strlen(argv[1]) == 17);
 118                sscanf(argv[1], "%2x:%2x:%2x:%2x:%2x:%2x", (unsigned int *)&target_mac[0],
 119                                                           (unsigned int *)&target_mac[1],
 120                                                           (unsigned int *)&target_mac[2],
 121                                                           (unsigned int *)&target_mac[3],
 122                                                           (unsigned int *)&target_mac[4],
 123                                                           (unsigned int *)&target_mac[5]);
 124                strcpy(eth_device, argv[2]);
 125                strcpy(filename, argv[3]);
 126                
 127        }
 128        packetizer p(target_mac, eth_device, filename);
 129        p.start();
 130        return 0;
 131}
 132
 133