mirror of
https://gitlab.com/ogelpre/pingxelflut.git
synced 2025-02-22 23:24:09 +01:00
69 lines
2.3 KiB
C++
69 lines
2.3 KiB
C++
#include "net_socket.hpp"
|
|
#include <linux/in6.h>
|
|
#include <iostream>
|
|
#include <linux/ip.h>
|
|
#include <linux/in6.h>
|
|
|
|
namespace net {
|
|
net_socket::net_socket(const std::string& iface){
|
|
/* Open PF_PACKET socket, listening for EtherType ETHER_TYPE */
|
|
if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) {
|
|
perror("listener: socket");
|
|
throw;
|
|
}
|
|
|
|
/* Set interface to promiscuous mode - do we need to do this every time? */
|
|
// strncpy(ifopts.ifr_name, iface.c_str(), IFNAMSIZ - 1);
|
|
ioctl(sockfd, SIOCGIFFLAGS, &ifopts);
|
|
ifopts.ifr_flags |= IFF_PROMISC;
|
|
ioctl(sockfd, SIOCSIFFLAGS, &ifopts);
|
|
/* Allow the socket to be reused - incase connection is closed prematurely */
|
|
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) ==
|
|
-1) {
|
|
perror("setsockopt");
|
|
close(sockfd);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
/* Bind to device */
|
|
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, iface.c_str(), IFNAMSIZ - 1) ==
|
|
-1) {
|
|
perror("SO_BINDTODEVICE");
|
|
close(sockfd);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
#ifndef NET_PREFIX
|
|
my_prefix = {{0xfc00, 0x0000, 0x0000, 0x0000}};
|
|
#else
|
|
my_prefix = {NET_PREFIX};
|
|
#endif
|
|
|
|
}
|
|
|
|
types::pixel net_socket::recv(){
|
|
bool pixel_valid = false;
|
|
while(!pixel_valid){
|
|
numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL);
|
|
// std::array<uint8_t, 6> recv_mac;
|
|
// std::copy(std::begin(eh->ether_dhost), std::end(eh->ether_dhost), std::begin(recv_mac));
|
|
if (iph->version != 6) {
|
|
continue;
|
|
}
|
|
/* Get source IP */
|
|
// memcpy(&((struct sockaddr_in6 *)&their_addr)->sin6_addr.s6_addr,
|
|
// &((struct ipv6hdr *)iph)->saddr, sizeof(struct in6_addr));
|
|
/* Get dest IP */
|
|
memcpy(&((struct sockaddr_in6 *)&our_addr)->sin6_addr.s6_addr,
|
|
&((struct ipv6hdr *)iph)->daddr, sizeof(struct in6_addr));
|
|
std::array<uint16_t, 4> recv_prefix;
|
|
for (size_t i=0; i<4; ++i){
|
|
recv_prefix[i] = ntohs(((struct sockaddr_in6 *)&our_addr)->sin6_addr.s6_addr16[i]);
|
|
}
|
|
if (my_prefix != recv_prefix){
|
|
continue;
|
|
}
|
|
pixel_valid = true;
|
|
}
|
|
return types::pixel((uint8_t *)&(((struct sockaddr_in6 *)&our_addr)->sin6_addr.s6_addr) + 8);
|
|
}
|
|
/* Look up my device IP addr if possible */
|
|
}
|