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