diff --git a/send_eth.c b/send_eth.c new file mode 100644 index 0000000..56b0172 --- /dev/null +++ b/send_eth.c @@ -0,0 +1,81 @@ +// commande : sudo ./send_eth + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int mac_from_str(const char *s, unsigned char *mac) { + int vals[6]; + if (sscanf(s, "%x:%x:%x:%x:%x:%x", + &vals[0], &vals[1], &vals[2], + &vals[3], &vals[4], &vals[5]) != 6) return -1; + for (int i = 0; i < 6; ++i) mac[i] = (unsigned char)vals[i]; + return 0; +} + +int main(int argc, char **argv) { + if (argc < 6) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + const char *ifname = argv[1]; + unsigned char dst_mac[6], src_mac[6]; + if (mac_from_str(argv[2], dst_mac) < 0) { fprintf(stderr, "Bad dst-mac\n"); return 1; } + if (mac_from_str(argv[3], src_mac) < 0) { fprintf(stderr, "Bad src-mac\n"); return 1; } + + unsigned int ethertype; + if (sscanf(argv[4], "%x", ðertype) != 1) { fprintf(stderr, "Bad ethertype\n"); return 1; } + + const char *payload = argv[5]; + size_t payload_len = strlen(payload); + + int sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + if (sock == -1) { perror("socket"); return 1; } + + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1); + if (ioctl(sock, SIOCGIFINDEX, &ifr) == -1) { perror("SIOCGIFINDEX"); close(sock); return 1; } + int ifindex = ifr.ifr_ifindex; + + unsigned char frame[ETH_FRAME_LEN]; + size_t frame_len = 0; + + memcpy(frame + frame_len, dst_mac, 6); frame_len += 6; + memcpy(frame + frame_len, src_mac, 6); frame_len += 6; + frame[frame_len++] = (ethertype >> 8) & 0xff; + frame[frame_len++] = ethertype & 0xff; + + if (payload_len + frame_len > ETH_DATA_LEN + ETH_HLEN) { + fprintf(stderr, "Payload too large\n"); close(sock); return 1; + } + memcpy(frame + frame_len, payload, payload_len); + frame_len += payload_len; + + if (frame_len < 60) { + memset(frame + frame_len, 0, 60 - frame_len); + frame_len = 60; + } + + struct sockaddr_ll sock_addr; + memset(&sock_addr, 0, sizeof(sock_addr)); + sock_addr.sll_ifindex = ifindex; + sock_addr.sll_halen = ETH_ALEN; + memcpy(sock_addr.sll_addr, dst_mac, 6); + + ssize_t sent = sendto(sock, frame, frame_len, 0, (struct sockaddr*)&sock_addr, sizeof(sock_addr)); + if (sent == -1) { perror("sendto"); close(sock); return 1; } + + printf("Sent %zd bytes on %s\n", sent, ifname); + close(sock); + return 0; +}