Browse Source

Typo
get mac address from iface

David Marec 8 tháng trước cách đây
mục cha
commit
d0132e1f94
3 tập tin đã thay đổi với 66 bổ sung9 xóa
  1. 3 2
      sockraw/README.md
  2. 5 0
      sockraw/obj/.gitignore
  3. 58 7
      sockraw/sockbpf.c

+ 3 - 2
sockraw/README.md

@@ -3,14 +3,14 @@
 * [man 4 bpf](https://man.freebsd.org/cgi/man.cgi?query=bpf&manpath=FreeBSD+14.2-RELEASE+and+Ports)
 * [man 4 epair](https://man.freebsd.org/cgi/man.cgi?query=epair&manpath=FreeBSD+14.2-RELEASE+and+Ports)
 
-Adaption sur _FreeBSD_ sous _bpf_ de codes écrits pour _Linux_ qui utilisait les mécanismes _raw sockets_ pour tester des boucles _Ethernet_.
+Adaptation sur _FreeBSD_ sous _bpf_ de codes écrits pour _Linux_ qui utilisait les mécanismes _raw sockets_ pour tester des boucles _Ethernet_.
 
 ## sockbpf
 
 Créez une interface de type `epair`:
 
 ```sh
-ifconfig create epair
+ifconfig epair create
 ifconfig epair0a 192.168.2.1/24
 ifconfig epair0b 192.168.2.2/24
 ```
@@ -42,6 +42,7 @@ Packet #10 sent.
 * `-m`: adresse MAC de destination;
 * `-v`: mode verbeux;
 * `-p`: nombre de trames à envoyer;
+* `-t`: interface de destination, supersedes `-m`.
 
 Vous devriez voir les paquets entrer de l'autre coté:
 ```sh

+ 5 - 0
sockraw/obj/.gitignore

@@ -0,0 +1,5 @@
+# No not push object files
+*
+# Except this file
+!.gitignore
+

+ 58 - 7
sockraw/sockbpf.c

@@ -14,7 +14,8 @@
 
 #define	DEVICE_BPF	"/dev/bpf"
 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;
 
 #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)
 {
 	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("  --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("  --verbose: verbose\n", stderr);
 	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)
 {
 	size_t i = 0;
@@ -67,7 +74,14 @@ static int get_first_bpf(void)
 	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;
 	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);
 
 	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) {
 		memset(out_buffer.frame.payload, ++dummy, sizeof out_buffer.frame.payload);
@@ -92,26 +106,57 @@ static void sender(size_t nb)
 	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[])
 {
 	size_t packets = 10;
 	struct ifreq out_if = {0};
 	const char *mac_address = fake_dest;
+	struct ifreq dest_ifr = {0};
+	int rc;
 
 	/* options */
 	int ch;
 	static struct option longopts[] = {
 		{ "if"     , required_argument, NULL, 'i' },
+		{ "to"     , required_argument, NULL, 't' },
 		{ "verbose", no_argument      , NULL, 'v' },
 		{ "mac"    , required_argument, NULL, 'm' },
 		{ "packets", required_argument, NULL, 'p' },
 		{ 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) {
 			case 'v':
 				verbose = 1;
 				break;
+			case 't':
+				dest_net = optarg;
+				break;
 			case 'i':
 				out_net = optarg;
 				break;
@@ -149,6 +194,12 @@ int main(int argc, char *argv[])
 		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
 	 * static int dummy_true = 1;
@@ -160,7 +211,7 @@ int main(int argc, char *argv[])
 	 *                exit(1);
 	 *        }
 	 */
-	sender(packets);
+	sender(&dest_ifr, packets);
 
 last:
 	close(bpf);