#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "raw_socket.h" #include "packet_construct.h" void raw_socket_destory(struct raw_socket *raw) { if (raw) { if (raw->sockfd) { close(raw->sockfd); } free(raw); raw = NULL; } } struct raw_socket *raw_socket_create(const char *interface, int fd_so_mask) { struct ifreq ifr = {0}; struct raw_socket *raw = (struct raw_socket *)calloc(1, sizeof(struct raw_socket)); memcpy(raw->interface, interface, strlen(interface)); raw->sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (raw->sockfd < 0) { printf("socket() failed, (%d: %s)", errno, strerror(errno)); goto error; } snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", raw->interface); if (ioctl(raw->sockfd, SIOCGIFHWADDR, &ifr) < 0) { printf("ioctl(SIOCGIFHWADDR) failed, (%d: %s)", errno, strerror(errno)); goto error; } memcpy(&(raw->mac_addr), ifr.ifr_hwaddr.sa_data, 6); raw->sockaddr.sll_ifindex = if_nametoindex(interface); if (raw->sockaddr.sll_ifindex == 0) { printf("if_nametoindex() failed, (%d: %s)", errno, strerror(errno)); goto error; } raw->sockaddr.sll_family = AF_PACKET; memcpy((void *)&(raw->sockaddr.sll_addr), (void *)&(raw->mac_addr), 6); raw->sockaddr.sll_halen = 6; if (setsockopt(raw->sockfd, SOL_SOCKET, SO_MARK, (char *)&fd_so_mask, sizeof(fd_so_mask)) < 0) { printf("setsockopt(SO_MARK) failed, (%d: %s)", errno, strerror(errno)); goto error; } return raw; error: raw_socket_destory(raw); return NULL; } int raw_socket_send(struct raw_socket *raw, const char *data, int data_len) { int ret = sendto(raw->sockfd, data, data_len, 0, (struct sockaddr *)&raw->sockaddr, sizeof(raw->sockaddr)); if (ret < 0) { printf("sendto() failed, (%d: %s)", errno, strerror(errno)); } return ret; } int raw_socket_recv(struct raw_socket *raw, char *buff, int buff_size) { socklen_t addr_len = sizeof(raw->sockaddr); int ret = recvfrom(raw->sockfd, buff, buff_size, 0, (struct sockaddr *)&raw->sockaddr, &addr_len); if (ret < 0) { printf("sendto() failed, (%d: %s)", errno, strerror(errno)); } return ret; }