Commit 08230421 authored by nanamicat's avatar nanamicat

float ip

parent 617a243f
......@@ -10,18 +10,49 @@
#include <unistd.h>
#include <arpa/inet.h>
#include <boost/program_options.hpp>
#include <netdb.h>
//#include <net/checksum.h>
struct Meta {
unsigned char src_id;
unsigned char dst_id;
unsigned short reversed;
};
#define decrypt_package encrypt_package
namespace po = boost::program_options;
unsigned char local_id;
unsigned char remote_id;
sockaddr_in remote_addr{.sin_family = AF_INET};
/* Checksum a block of data */
uint16_t csum(uint16_t *packet, int packlen) {
unsigned long sum = 0;
while (packlen > 1) {
sum += *(packet++);
packlen -= 2;
}
if (packlen > 0)
sum += *(unsigned char *) packet;
/* TODO: this depends on byte order */
while (sum >> 16)
sum = (sum & 0xffff) + (sum >> 16);
in_addr_t remote;
auto cipher = (unsigned char *) "Mathematics is the art of giving the same name to different things.";
auto cipher_length = strlen((char *) cipher);
return (uint16_t) ~sum;
}
char *secret;
size_t secret_length = strlen(secret);
void encrypt_package(unsigned char *buffer, size_t length) {
for (auto i = 0; i < length; i++) {
buffer[i] ^= cipher[i % cipher_length];
buffer[i] ^= secret[i % secret_length];
}
}
......@@ -35,14 +66,20 @@ void inbound(int raw, int tun) {
auto *packet = (iphdr *) buffer;
auto overhead = packet->ihl * 4;
auto payload = buffer + overhead;
// auto inner = (iphdr *) payload;
auto meta = (Meta *) payload;
if (!(meta->src_id == remote_id && meta->dst_id == local_id && meta->reversed == 0)) continue;
auto inner = (iphdr *) (payload + sizeof(Meta));
auto payload_length = packet_length - overhead - sizeof(Meta);
decrypt_package((unsigned char *) inner, payload_length);
// if (ip_fast_csum(inner, inner->ihl)) continue;
if (csum((uint16_t *) inner, inner->ihl * 4)) continue;
// std::cout << "packet_length " << packet_length
// << " tot_len " << ntohs(packet->tot_len)
// << " inner->tot_len " << ntohs(inner->tot_len)
// << " from " << inet_ntoa(address.sin_addr) << std::endl;
auto payload_length = packet_length - overhead;
decrypt_package(payload, payload_length);
if (write(tun, payload, payload_length) < 0) {
remote_addr = address;
if (write(tun, inner, payload_length) < 0) {
perror("inbound write");
}
}
......@@ -52,12 +89,15 @@ void inbound(int raw, int tun) {
// tun -> internet
void outbound(int raw, int tun) {
unsigned char buffer[ETH_DATA_LEN];
sockaddr_in address{.sin_family = AF_INET};
address.sin_addr.s_addr = remote;
auto meta = (Meta *) buffer;
meta->src_id = local_id;
meta->dst_id = remote_id;
meta->reversed = 0;
auto inner = buffer + sizeof(Meta);
size_t packet_length;
while ((packet_length = read(tun, buffer, sizeof(buffer))) >= 0) {
encrypt_package(buffer, packet_length);
if (sendto(raw, buffer, packet_length, 0, (sockaddr *) &address, sizeof(address)) < 0) {
while ((packet_length = read(tun, inner, sizeof(buffer) - sizeof(Meta))) >= 0) {
encrypt_package(inner, packet_length);
if (sendto(raw, buffer, packet_length + sizeof(Meta), 0, (sockaddr *) &remote_addr, sizeof(remote_addr)) < 0) {
perror("outbound write");
}
}
......@@ -66,28 +106,21 @@ void outbound(int raw, int tun) {
int main(int argc, char *argv[]) {
po::options_description desc("Allowed options");
desc.add_options()
("help,h", "see how to use me elegantly")
("IP,i", po::value<std::string>(), "IP to connect")
("dev,d", po::value<std::string>(), "tunnel device's name")
("postup,p", po::value<std::string>(), "post up script");
local_id = atoi(getenv("local_id"));
remote_id = atoi(getenv("remote_id"));
auto endpoint = gethostbyname(getenv("endpoint"));
unsigned char proto = atoi(getenv("proto"));
secret = getenv("secret");
auto dev = getenv("dev");
auto up = getenv("up");
po::variables_map args;
po::store(po::parse_command_line(argc, argv, desc), args);
po::notify(args);
if (args.count("help") || !args.count("IP") || !args.count("dev")) {
std::cout << desc << std::endl;
return -1;
}
remote_addr.sin_addr.s_addr = ((in_addr *) endpoint->h_name)->s_addr;
ifreq ifr{};
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
strncpy(ifr.ifr_name, args["dev"].as<std::string>().c_str(), IFNAMSIZ);
remote = inet_addr(args["IP"].as<std::string>().c_str());
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
auto raw = socket(AF_INET, SOCK_RAW, 144);
auto raw = socket(AF_INET, SOCK_RAW, proto);
if (raw < 0) {
perror("socket init error");
return -1;
......@@ -103,9 +136,7 @@ int main(int argc, char *argv[]) {
return -1;
}
if (args.count("postup")) {
system(args["postup"].as<std::string>().c_str());
}
system(up);
std::thread t1(inbound, raw, tun);
std::thread t2(outbound, raw, tun);
......@@ -114,3 +145,4 @@ int main(int argc, char *argv[]) {
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment