Josh Posted December 16, 2017 Share Posted December 16, 2017 I've done some reading and I think I understand the NAT punch-through problem now and I am preparing to solve it. I'm looking for the simplest way possible to send a bunch of UDP packets to a specific IP address. The packets don't need any format and will never even be read, I just need to spam an IP address with a bunch of nonsense data. What's the simplest cross-platform method to do this? Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted December 16, 2017 Author Share Posted December 16, 2017 Also note here is a method of doing it without any handshake server:https://samy.pl/pwnat/ 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted December 29, 2017 Author Share Posted December 29, 2017 Here's a rough first pass at a Socket class for doing exactly this: #include <sys/types.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <arpa/inet.h> #include <netdb.h> #include <memory.h> #include <ifaddrs.h> #include <net/if.h> #include <errno.h> #include <stdlib.h> #include <iostream> #ifdef LEADWERKS_5 class Socket : public SharedObject #else class Socket : public Object #endif { Socket(); virtual ~Socket(); std::string ip; int port; int sock; #ifndef LEADWERKS_5 static Socket* Create(const std::string ip, const int port); #endif static int resolvehelper(const char* hostname, int family, const char* service, sockaddr_storage* pAddr); }; #ifdef LEADWERKS_5 extern shared_ptr<Socket> CreateSocket(const std::string ip, const int port); #endif Socket::Socket() : sockaddr_storage addrDest ({}), port (0), sock(0) {} Socket::~Socket() { if (sock!=0) closesocket(sock); sock = 0; } int Socket::resolvehelper(const char* hostname, int family, const char* service, sockaddr_storage* pAddr) { int result; addrinfo* result_list = NULL; addrinfo hints = {}; hints.ai_family = family; hints.ai_socktype = SOCK_DGRAM; // without this flag, getaddrinfo will return 3x the number of addresses (one for each socket type). result = getaddrinfo(hostname, service, &hints, &result_list); if (result == 0) { //ASSERT(result_list->ai_addrlen <= sizeof(sockaddr_in)); memcpy(pAddr, result_list->ai_addr, result_list->ai_addrlen); freeaddrinfo(result_list); } return result; } #ifdef LEADWERKS_5 shared_ptr<Socket> CreateSocket(const std::string& ip, const int port) { auto socket = make_shared<Socket>(); #else Socket* Socket::Create(const std::string& ip, const int port) { auto socket = new Socket; #endif socket->sock = socket(AF_INET, SOCK_DGRAM, 0); sockaddr_in addrListen = {}; // zero-int, sin_port is 0, which picks a random port for bind. addrListen.sin_family = AF_INET; int result = bind(socket->sock, (sockaddr*)&addrListen, sizeof(addrListen)); if (result == -1) { int lasterror = errno; std::cout << "error: " << lasterror; exit(1); } result = resolvehelper( ip, AF_INET, std::string(port), &socket->addrDest); if (result != 0) { int lasterror = errno; Print("Error: " + std::string(lasterror)); return nullptr; } return socket; } #ifdef LEADWERKS_5 bool Socket::Send(shared_ptr<Bank> data) #else bool Socket::Send(const Bank* data) #endif { Send(bank->buf,bank->GetSize()); } bool Socket::Send(const void* data, const int size) { return size == sendto(sock, data, size, 0, (sockaddr*)&addrDest, sizeof(addrDest)); } Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted December 30, 2017 Author Share Posted December 30, 2017 Alright, my socket class works now and I can spam random packets at any webhost or IP address: #include "../Leadwerks.h" namespace Leadwerks { //http://www.binarytides.com/code-a-simple-socket-client-class-in-c/ const int SOCKET_UDP = SOCK_DGRAM; const int SOCKET_TCP = SOCK_STREAM; bool Socket::Initialized = false; Socket::Socket() : port(0), sock(0) {} Socket::~Socket() { #ifdef _WIN32 if (sock != 0) closesocket(sock); #else if (sock != 0) close(sock); #endif sock = 0; } #ifdef LEADWERKS_5 shared_ptr<Socket> CreateSocket(const std::string ip, const int port, const int protocol) #else Socket* Socket::Create(const std::string address, const int port, const int protocol) #endif { #ifdef _WIN32 if (!Initialized) { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err == 0) { Initialized = true; } else { return nullptr; } } #endif #ifdef LEADWERKS_5 auto socket = make_shared<Socket>(); #else auto socket_ = new Socket; #endif socket_->sock = socket(AF_INET, protocol, 0); socket_->address = address; socket_->port = port; if (inet_addr(address.c_str()) == -1) { struct hostent *he; struct in_addr **addr_list; //resolve the hostname, its not an ip address he = gethostbyname(address.c_str()); if (he == NULL) { //gethostbyname failed //herror("gethostbyname"); //cout << "Failed to resolve hostname\n"; #ifndef LEADWERKS_5 socket_->Release(); #endif return nullptr; } //Cast the h_addr_list to in_addr , since h_addr_list also has the ip address in long format only addr_list = (struct in_addr **) he->h_addr_list; for (int i = 0; addr_list[i] != NULL; i++) { //strcpy(ip , inet_ntoa(*addr_list[i]) ); socket_->server.sin_addr = *addr_list[i]; //cout << address << " resolved to " << inet_ntoa(*addr_list[i]) << endl; break; } } else { socket_->server.sin_addr.s_addr = inet_addr(address.c_str()); } socket_->server.sin_family = AF_INET; socket_->server.sin_port = htons(port); //Connect to remote server if (connect(socket_->sock, (struct sockaddr *)&socket_->server, sizeof(server)) < 0) { #ifndef LEADWERKS_5 socket_->Release(); #endif return nullptr; } return socket_; } #ifdef LEADWERKS_5 bool Socket::Send(shared_ptr<Bank> data) #else bool Socket::Send(Bank* data) #endif { return Send(data->buf, data->GetSize()); } #ifdef LEADWERKS_5 int Socket::Receive(shared_ptr<Bank> data) #else int Socket::Receive(Bank* data) #endif { return Receive(data->buf, data->GetSize()); } bool Socket::Send(const void* data, const int size) { return send(sock, (const char*)data, size, 0) == size; } int Socket::Receive(void* data, const int size) { return recv(sock, (char*)data, size, 0); } } Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.