// 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; }