|
@@ -14,7 +14,8 @@
|
|
|
|
|
|
|
|
#define DEVICE_BPF "/dev/bpf"
|
|
#define DEVICE_BPF "/dev/bpf"
|
|
|
static int verbose;
|
|
static int verbose;
|
|
|
-static const char *out_net = "tap0";
|
|
|
|
|
|
|
+static const char *out_net = "epair0a";
|
|
|
|
|
+static const char *dest_net = NULL;
|
|
|
struct ether_addr *daddr;
|
|
struct ether_addr *daddr;
|
|
|
|
|
|
|
|
#define PAYLOAD_LEN 64
|
|
#define PAYLOAD_LEN 64
|
|
@@ -39,15 +40,21 @@ static const char *fake_dest = "6:66:6:66:6:66";
|
|
|
static void __attribute__((__noreturn__)) usage(void)
|
|
static void __attribute__((__noreturn__)) usage(void)
|
|
|
{
|
|
{
|
|
|
fputs("\nUsage:\n", stderr);
|
|
fputs("\nUsage:\n", stderr);
|
|
|
- fputs("sockraw [--if net][--mac mac][--packets samples][--verbose]\n", stderr);
|
|
|
|
|
|
|
+ fputs("sockraw [--if iface][--mac maca[-to iface]][--packets samples][--verbose]\n", stderr);
|
|
|
fputs(" --if : interface\n", stderr);
|
|
fputs(" --if : interface\n", stderr);
|
|
|
fputs(" --mac : destination MAC address\n", stderr);
|
|
fputs(" --mac : destination MAC address\n", stderr);
|
|
|
|
|
+ fputs(" --to : destination MAC address from interface name\n", stderr);
|
|
|
fputs(" --packets: packets samples to sent\n", stderr);
|
|
fputs(" --packets: packets samples to sent\n", stderr);
|
|
|
fputs(" --verbose: verbose\n", stderr);
|
|
fputs(" --verbose: verbose\n", stderr);
|
|
|
exit(EXIT_SUCCESS);
|
|
exit(EXIT_SUCCESS);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* open BPF interface */
|
|
|
|
|
|
|
+/* open BPF interface
|
|
|
|
|
+ *
|
|
|
|
|
+ * Setup global variable bpf
|
|
|
|
|
+ *
|
|
|
|
|
+ * return pbf value on success, -1 on error
|
|
|
|
|
+ */
|
|
|
static int get_first_bpf(void)
|
|
static int get_first_bpf(void)
|
|
|
{
|
|
{
|
|
|
size_t i = 0;
|
|
size_t i = 0;
|
|
@@ -67,7 +74,14 @@ static int get_first_bpf(void)
|
|
|
return bpf;
|
|
return bpf;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void sender(size_t nb)
|
|
|
|
|
|
|
+/*
|
|
|
|
|
+ * send packets
|
|
|
|
|
+ *
|
|
|
|
|
+ * @ifr: destination interface
|
|
|
|
|
+ * @nb: packets number
|
|
|
|
|
+ *
|
|
|
|
|
+ */
|
|
|
|
|
+static void sender(struct ifreq *ifr, size_t nb)
|
|
|
{
|
|
{
|
|
|
static unsigned char dummy;
|
|
static unsigned char dummy;
|
|
|
size_t total = nb + 1;
|
|
size_t total = nb + 1;
|
|
@@ -75,7 +89,7 @@ static void sender(size_t nb)
|
|
|
printf("Prepare to send %zu packets to %s.\n", nb, out_net);
|
|
printf("Prepare to send %zu packets to %s.\n", nb, out_net);
|
|
|
|
|
|
|
|
out_buffer.frame.header.ether_type = htons(PAYLOAD_LEN);
|
|
out_buffer.frame.header.ether_type = htons(PAYLOAD_LEN);
|
|
|
- memcpy(out_buffer.frame.header.ether_dhost, daddr, ETHER_ADDR_LEN);
|
|
|
|
|
|
|
+ memcpy(out_buffer.frame.header.ether_dhost, ifr->ifr_addr.sa_data, ETHER_ADDR_LEN);
|
|
|
|
|
|
|
|
while (nb) {
|
|
while (nb) {
|
|
|
memset(out_buffer.frame.payload, ++dummy, sizeof out_buffer.frame.payload);
|
|
memset(out_buffer.frame.payload, ++dummy, sizeof out_buffer.frame.payload);
|
|
@@ -92,26 +106,57 @@ static void sender(size_t nb)
|
|
|
printf("Done.\n");
|
|
printf("Done.\n");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/*
|
|
|
|
|
+ * Return MAC address
|
|
|
|
|
+ *
|
|
|
|
|
+ * @iface: Interface name
|
|
|
|
|
+ *
|
|
|
|
|
+ * @return -1 on error, 0 on success
|
|
|
|
|
+ */
|
|
|
|
|
+static int get_hwaddr(const char *iface, struct ifreq *dest_ifr)
|
|
|
|
|
+{
|
|
|
|
|
+ int shw;
|
|
|
|
|
+
|
|
|
|
|
+ strncpy(dest_ifr->ifr_name, iface, sizeof dest_ifr->ifr_name);
|
|
|
|
|
+ dest_ifr->ifr_addr.sa_family = AF_LINK;
|
|
|
|
|
+
|
|
|
|
|
+ if ((shw = socket(AF_INET, SOCK_RAW, 0)) < 0) {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ioctl(shw, SIOCGHWADDR, dest_ifr);
|
|
|
|
|
+ close(shw);
|
|
|
|
|
+ VPRINTF("Destination %s, HW address: %s.\n", iface, ether_ntoa((const struct ether_addr *)dest_ifr->ifr_addr.sa_data));
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
int main(int argc, char *argv[])
|
|
int main(int argc, char *argv[])
|
|
|
{
|
|
{
|
|
|
size_t packets = 10;
|
|
size_t packets = 10;
|
|
|
struct ifreq out_if = {0};
|
|
struct ifreq out_if = {0};
|
|
|
const char *mac_address = fake_dest;
|
|
const char *mac_address = fake_dest;
|
|
|
|
|
+ struct ifreq dest_ifr = {0};
|
|
|
|
|
+ int rc;
|
|
|
|
|
|
|
|
/* options */
|
|
/* options */
|
|
|
int ch;
|
|
int ch;
|
|
|
static struct option longopts[] = {
|
|
static struct option longopts[] = {
|
|
|
{ "if" , required_argument, NULL, 'i' },
|
|
{ "if" , required_argument, NULL, 'i' },
|
|
|
|
|
+ { "to" , required_argument, NULL, 't' },
|
|
|
{ "verbose", no_argument , NULL, 'v' },
|
|
{ "verbose", no_argument , NULL, 'v' },
|
|
|
{ "mac" , required_argument, NULL, 'm' },
|
|
{ "mac" , required_argument, NULL, 'm' },
|
|
|
{ "packets", required_argument, NULL, 'p' },
|
|
{ "packets", required_argument, NULL, 'p' },
|
|
|
{ NULL, 0, NULL, 0 }
|
|
{ NULL, 0, NULL, 0 }
|
|
|
};
|
|
};
|
|
|
- while ((ch = getopt_long(argc, argv, "vi:o:p:m:", longopts, NULL)) != -1) {
|
|
|
|
|
|
|
+ while ((ch = getopt_long(argc, argv, "vi:t:p:m:", longopts, NULL)) != -1) {
|
|
|
switch (ch) {
|
|
switch (ch) {
|
|
|
case 'v':
|
|
case 'v':
|
|
|
verbose = 1;
|
|
verbose = 1;
|
|
|
break;
|
|
break;
|
|
|
|
|
+ case 't':
|
|
|
|
|
+ dest_net = optarg;
|
|
|
|
|
+ break;
|
|
|
case 'i':
|
|
case 'i':
|
|
|
out_net = optarg;
|
|
out_net = optarg;
|
|
|
break;
|
|
break;
|
|
@@ -149,6 +194,12 @@ int main(int argc, char *argv[])
|
|
|
goto last;
|
|
goto last;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ rc = dest_net == NULL;
|
|
|
|
|
+ if (!rc)
|
|
|
|
|
+ rc = get_hwaddr(dest_net, &dest_ifr);
|
|
|
|
|
+
|
|
|
|
|
+ if (rc)
|
|
|
|
|
+ memcpy(dest_ifr.ifr_addr.sa_data, daddr, ETHER_ADDR_LEN);
|
|
|
/*
|
|
/*
|
|
|
* pointless until we do not read _from_ interface
|
|
* pointless until we do not read _from_ interface
|
|
|
* static int dummy_true = 1;
|
|
* static int dummy_true = 1;
|
|
@@ -160,7 +211,7 @@ int main(int argc, char *argv[])
|
|
|
* exit(1);
|
|
* exit(1);
|
|
|
* }
|
|
* }
|
|
|
*/
|
|
*/
|
|
|
- sender(packets);
|
|
|
|
|
|
|
+ sender(&dest_ifr, packets);
|
|
|
|
|
|
|
|
last:
|
|
last:
|
|
|
close(bpf);
|
|
close(bpf);
|