115 lines
3.7 KiB
C++
115 lines
3.7 KiB
C++
//
|
|
// Created by root on 13.10.17.
|
|
//
|
|
|
|
#include "FilteredUDPSocket.h"
|
|
|
|
#include <iostream>
|
|
#include <cstring>
|
|
#include <ifaddrs.h>
|
|
#include <netinet/udp.h> //Provides declarations for udp header
|
|
#include <netinet/ip.h> //Provides declarations for ip header
|
|
#include <arpa/inet.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
#include <arpa/inet.h>
|
|
#include <linux/if_ether.h>
|
|
#include <linux/filter.h>
|
|
#include <chrono>
|
|
#include <zconf.h>
|
|
|
|
using namespace std;
|
|
using namespace std::chrono;
|
|
using namespace ts::connection;
|
|
|
|
FilteredUdpSocket::FilteredUdpSocket() {}
|
|
FilteredUdpSocket::~FilteredUdpSocket() {}
|
|
|
|
|
|
bool FilteredUdpSocket::setup(sockaddr_in * remoteAddr) {
|
|
srand(system_clock::now().time_since_epoch().count()); // should only be called once
|
|
int r = (lrand48() % (50 * 1000)) + 1000; // returns a pseudo-random integer between 0 and RAND_MAX
|
|
|
|
|
|
this->remoteAdress = new sockaddr_in;
|
|
memcpy(this->remoteAdress, remoteAddr, sizeof(sockaddr_in));
|
|
|
|
this->socketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
if(this->socketDescriptor < 0){
|
|
cerr << "Invalid socket create: " << errno << " - " << this->socketDescriptor << " -> " << strerror(errno) << endl;
|
|
}
|
|
int allow = 1;
|
|
setsockopt(this->socketDescriptor, SOL_SOCKET, SO_REUSEADDR, &allow, sizeof(int));
|
|
|
|
this->localAdress = new sockaddr_in;
|
|
memset((char *) this->localAdress, 0, sizeof(sockaddr_in));
|
|
localAdress->sin_family = AF_INET;
|
|
localAdress->sin_addr.s_addr = htonl(INADDR_ANY);
|
|
localAdress->sin_port = htons(r);
|
|
|
|
|
|
/* sudo tcpdump -q udp port 256 -dd */
|
|
struct sock_filter code[ ] = {
|
|
{ 0x28, 0, 0, 0x0000000c },
|
|
{ 0x15, 0, 8, 0x000086dd },
|
|
{ 0x30, 0, 0, 0x00000014 },
|
|
{ 0x15, 2, 0, 0x00000084 },
|
|
{ 0x15, 1, 0, 0x00000006 },
|
|
{ 0x15, 0, 17, 0x00000011 },
|
|
{ 0x28, 0, 0, 0x00000036 },
|
|
{ 0x15, 14, 0, 0x00002fbd },
|
|
{ 0x28, 0, 0, 0x00000038 },
|
|
{ 0x15, 12, 13, 0x00002fbd },
|
|
{ 0x15, 0, 12, 0x00000800 },
|
|
{ 0x30, 0, 0, 0x00000017 },
|
|
{ 0x15, 2, 0, 0x00000084 },
|
|
{ 0x15, 1, 0, 0x00000006 },
|
|
{ 0x15, 0, 8, 0x00000011 },
|
|
{ 0x28, 0, 0, 0x00000014 },
|
|
{ 0x45, 6, 0, 0x00001fff },
|
|
{ 0xb1, 0, 0, 0x0000000e },
|
|
{ 0x48, 0, 0, 0x0000000e },
|
|
{ 0x15, 2, 0, 0x00002fbd },
|
|
{ 0x48, 0, 0, 0x00000010 },
|
|
{ 0x15, 0, 1, 0x00002fbd },
|
|
{ 0x6, 0, 0, 0x00040000 },
|
|
{ 0x6, 0, 0, 0x00000000 },
|
|
|
|
};
|
|
|
|
struct sock_fprog bpf = {
|
|
.len = sizeof(code) / sizeof(*code),
|
|
.filter = code,
|
|
};
|
|
|
|
//auto response = setsockopt(this->socketDescriptor, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
|
|
//if (response < 0) cerr << "Invalid attach!" << endl;
|
|
/* ... bail out ... */
|
|
|
|
|
|
/*
|
|
*
|
|
if(connect(this->socketDescriptor, (const sockaddr *) remoteAddr, sizeof(sockaddr_in)) < 0){
|
|
cerr << "Invalid connect" << endl;
|
|
}
|
|
*/
|
|
if(bind(this->socketDescriptor, (const sockaddr *) localAdress, sizeof(sockaddr_in)) < 0) cout << "XXX" << endl;
|
|
|
|
return true;
|
|
}
|
|
|
|
void FilteredUdpSocket::close() {
|
|
if(this->socketDescriptor > 0) {
|
|
shutdown(this->socketDescriptor, SHUT_RDWR);
|
|
::close(this->socketDescriptor);
|
|
this->socketDescriptor = 0;
|
|
}
|
|
}
|
|
|
|
ssize_t FilteredUdpSocket::write(const char *buffer, size_t size) {
|
|
return sendto(this->socketDescriptor, buffer, size, 0, (const sockaddr *) this->remoteAdress, sizeof(sockaddr_in));
|
|
}
|
|
|
|
ssize_t FilteredUdpSocket::read(char *buffer, size_t size) {
|
|
return recv(this->socketDescriptor, (void *) buffer, size, 0);
|
|
} |