18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#include <stdlib.h>
38c2ecf20Sopenharmony_ci#include <stdio.h>
48c2ecf20Sopenharmony_ci#include <linux/unistd.h>
58c2ecf20Sopenharmony_ci#include <unistd.h>
68c2ecf20Sopenharmony_ci#include <string.h>
78c2ecf20Sopenharmony_ci#include <errno.h>
88c2ecf20Sopenharmony_ci#include <linux/if_ether.h>
98c2ecf20Sopenharmony_ci#include <net/if.h>
108c2ecf20Sopenharmony_ci#include <linux/if_packet.h>
118c2ecf20Sopenharmony_ci#include <arpa/inet.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_cistatic inline int open_raw_sock(const char *name)
148c2ecf20Sopenharmony_ci{
158c2ecf20Sopenharmony_ci	struct sockaddr_ll sll;
168c2ecf20Sopenharmony_ci	int sock;
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci	sock = socket(PF_PACKET, SOCK_RAW | SOCK_NONBLOCK | SOCK_CLOEXEC, htons(ETH_P_ALL));
198c2ecf20Sopenharmony_ci	if (sock < 0) {
208c2ecf20Sopenharmony_ci		printf("cannot create raw socket\n");
218c2ecf20Sopenharmony_ci		return -1;
228c2ecf20Sopenharmony_ci	}
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci	memset(&sll, 0, sizeof(sll));
258c2ecf20Sopenharmony_ci	sll.sll_family = AF_PACKET;
268c2ecf20Sopenharmony_ci	sll.sll_ifindex = if_nametoindex(name);
278c2ecf20Sopenharmony_ci	sll.sll_protocol = htons(ETH_P_ALL);
288c2ecf20Sopenharmony_ci	if (bind(sock, (struct sockaddr *)&sll, sizeof(sll)) < 0) {
298c2ecf20Sopenharmony_ci		printf("bind to %s: %s\n", name, strerror(errno));
308c2ecf20Sopenharmony_ci		close(sock);
318c2ecf20Sopenharmony_ci		return -1;
328c2ecf20Sopenharmony_ci	}
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci	return sock;
358c2ecf20Sopenharmony_ci}
36