101 lines
2.6 KiB
C++
101 lines
2.6 KiB
C++
|
|
#include <stdio.h>
|
|
#include <arpa/inet.h>
|
|
#include <netinet/ether.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <sys/ioctl.h>
|
|
#include <net/if.h>
|
|
#include <sys/socket.h>
|
|
#include <linux/if_packet.h>
|
|
#include <net/ethernet.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <pcap/pcap.h>
|
|
|
|
#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;
|
|
} |