static void remote_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { struct remote_context *remote; struct client_context *client; remote = stream->data; client = remote->client; if (nread > 0) { reset_timer(remote); struct packet *packet = &remote->packet; int rc = packet_filter(packet, buf->base, nread); if (rc == PACKET_COMPLETED) { int clen = packet->size; int mlen = packet->size - PRIMITIVE_BYTES; uint8_t *c = packet->buf, *m = packet->buf; assert(mlen > 0 && mlen <= MAX_PACKET_SIZE - PRIMITIVE_BYTES); int err = crypto_decrypt(m, c, clen); if (err) { goto error; } uv_read_stop(&remote->handle.stream); forward_to_client(client, m, mlen); } else if (rc == PACKET_INVALID) { goto error; } } else if (nread < 0){ if (nread != UV_EOF && verbose) { char addrbuf[INET6_ADDRSTRLEN + 1]; int port = ip_name(&client->target_addr, addrbuf, sizeof(addrbuf)); logger_log(LOG_ERR, "receive from %s:%d failed: %s", addrbuf, port, uv_strerror(nread)); } close_client(client); close_remote(remote); } return; error: logger_log(LOG_ERR, "invalid tcp packet"); if (verbose) { dump_hex(buf->base, nread, "invalid tcp Packet"); } close_client(client); close_remote(remote); }
int main(int argc, char *argv[]) { pcap_t *pcap; const unsigned char *packet; char errbuf[PCAP_ERRBUF_SIZE]; struct pcap_pkthdr header; int pkt_count = 0; pcap_t *adhandle; pcap_dumper_t *dumpfile; /* We expect exactly one argument, the name of the file to dump. */ if (argc != 4) { fprintf(stderr, "Usage: %s rule.txt in.pcap out.pcap\n", argv[0]); exit(1); } parse_rule_file(argv[1]); // success or die pcap = pcap_open_offline(argv[2], errbuf); if (pcap == NULL) { fprintf(stderr, "error reading pcap file: %s\n", errbuf); exit(1); } dumpfile = pcap_dump_open(pcap, argv[3]); if(dumpfile==NULL) { fprintf(stderr,"\nError opening output file\n"); return -1; } /* Now just loop through extracting packets as long as we have * some to read. */ while ((packet = pcap_next(pcap, &header)) != NULL){ int res = packet_filter(packet, header.ts, header.caplen); // printf("Processing %d packet, result: %s\n", pkt_count, res ? "accept" : "reject"); pkt_count++; if (res) pcap_dump((unsigned char *) dumpfile, &header, packet); } // terminate return 0; }
static void source_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { struct source_context *source = stream->data; struct target_context *target = source->target; if (nread > 0) { if (mode == TUNNEL_MODE_CLIENT) { int clen = nread + PRIMITIVE_BYTES; uint8_t *c = source->packet.buf + HEADER_BYTES; int rc = crypto_encrypt(c, (uint8_t*)buf->base, nread); if (rc) { goto error; } forward_to_target(target, c, clen); } else { struct packet *packet = &source->packet; int rc = packet_filter(packet, buf->base, nread); if (rc == PACKET_COMPLETED) { uint8_t *m = packet->buf; int mlen = packet->size - PRIMITIVE_BYTES; int err = crypto_decrypt(m, packet->buf, packet->size); if (err) { goto error; } forward_to_target(target, m, mlen); } else if (rc == PACKET_INVALID) { goto error; } } } else if (nread < 0){ close_source(source); close_target(target); } return; error: logger_log(LOG_ERR, "invalid packet"); close_source(source); close_target(target); }
int main(int argc, char *argv[]) { // find_alldev(); if (init_mapping() == 1) { fprintf(stderr, "Couldn't initialize port mapping table\n"); exit(0); } if (virtual_server() == 1) { fprintf(stderr, "Couldn't initialize virtual server table\n"); exit(0); } packet_filter(); }
static void remote_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { struct remote_context *remote; struct client_context *client; remote = stream->data; client = remote->client; if (nread > 0) { reset_timer(remote); struct packet *packet = &remote->packet; int rc = packet_filter(packet, buf->base, nread); if (rc == PACKET_COMPLETED) { uint8_t *m = packet->buf; int mlen = packet->size - PRIMITIVE_BYTES; int err = crypto_decrypt(m, packet->buf, packet->size); if (err) { goto error; } uv_read_stop(&remote->handle.stream); forward_to_client(client, m, mlen); } else if (rc == PACKET_INVALID) { goto error; } } else if (nread < 0){ if (nread != UV_EOF) { logger_log(LOG_ERR, "receive from %s failed: %s", client->target_addr, uv_strerror(nread)); } goto destroy; } return; error: logger_log(LOG_ERR, "invalid tcp packet"); destroy: close_client(client); close_remote(remote); }
static void *worker_thread(void *arg) { // RNG for packet_dispatch random_state_t rng = random_init(); // The main loop. // Handles either incoming packets, or requests from the configuration // server. while (true) { uint8_t packet[CKTP_MAX_PACKET_SIZE + sizeof(struct ethhdr)]; uint8_t packet_buff[PACKET_BUFF_SIZE]; size_t packet_len = get_packet(packet, sizeof(packet)); struct config_s config; config_get(&config); // Do we need to tunnel this packet? if (!packet_filter(&config, packet, packet_len)) { inject_packet(packet, packet_len); continue; } // Is there a tunnel available for use? if (config.tunnel && !tunnel_ready()) { warning("unable to tunnel packet (no suitable tunnel is open); " "the packet will be sent via the normal route"); inject_packet(packet, packet_len); continue; } // Is this packet a repeat or not? uint64_t packet_hash; unsigned packet_rep; packet_track(packet, &packet_hash, &packet_rep); // Dispatch the packet (fragments) struct ethhdr *allowed_packets[DISPATCH_MAX_FRAGMENTS+1]; struct ethhdr *tunneled_packets[DISPATCH_MAX_FRAGMENTS+1]; allowed_packets[0] = NULL; tunneled_packets[0] = NULL; packet_dispatch(&config, rng, packet, packet_len, packet_hash, packet_rep, allowed_packets, tunneled_packets, packet_buff); // Tunnel the packets if (config.tunnel) { if (!tunnel_packets(packet, (uint8_t **)tunneled_packets, packet_hash, packet_rep, config.mtu, config.multi_route)) { continue; } } else { allow_packets(true, tunneled_packets); } // Allow packets. allow_packets(false, allowed_packets); } return NULL; }
static void recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { struct tundev_context *ctx; struct client_context *client; ctx = stream->data; client = container_of(stream, struct client_context, handle.stream); struct packet *packet = &client->packet; if (nread > 0) { if ((ctx->connect == AUTHING) && ( (0 == memcmp(packet->buf, "GET ", 4)) || (0 == memcmp(packet->buf, "POST", 4)) ) ) { http_auth(stream, packet->buf); packet_reset(packet); ctx->connect = CONNECTED; return; } int rc = packet_filter(packet, buf->base, nread); if (rc == PACKET_UNCOMPLETE) { return; } else if (rc == PACKET_INVALID) { logger_log(LOG_ERR, "Filter Invalid: %d", nread); goto error; } int clen = packet->size; int mlen = packet->size - PRIMITIVE_BYTES; uint8_t *c = packet->buf, *m = packet->buf; assert(mlen > 0 && mlen <= ctx->tun->mtu); int err = crypto_decrypt(m, c, clen); if (err) { logger_log(LOG_ERR, "Fail Decrypt: %d", clen); goto error; } struct iphdr *iphdr = (struct iphdr *) m; in_addr_t client_network = iphdr->saddr & htonl(ctx->tun->netmask); if (client_network != ctx->tun->network) { char *a = inet_ntoa(*(struct in_addr *) &iphdr->saddr); logger_log(LOG_ERR, "Invalid client: %s", a); close_client(client); return; } if (client->peer == NULL) { uv_rwlock_rdlock(&rwlock); struct peer *peer = lookup_peer(iphdr->saddr, peers); uv_rwlock_rdunlock(&rwlock); if (peer == NULL) { char saddr[24] = {0}, daddr[24] = {0}; parse_addr(iphdr, saddr, daddr); logger_log(LOG_WARNING, "[TCP] Cache miss: %s -> %s", saddr, daddr); uv_rwlock_wrlock(&rwlock); peer = save_peer(iphdr->saddr, &client->addr, peers); uv_rwlock_wrunlock(&rwlock); } else { if (peer->data) { struct client_context *old = peer->data; close_client(old); } } peer->protocol= xTUN_TCP; peer->data = client; client->peer = peer; } network_to_tun(ctx->tunfd, m, mlen); packet_reset(packet); } else if (nread < 0) { if (nread != UV_EOF) { logger_log(LOG_ERR, "Receive from client failed: %s", uv_strerror(nread)); } close_client(client); } return; error: if (verbose) { dump_hex(buf->base, nread, "Invalid tcp Packet"); } handle_invalid_packet(client); }