/* Name: packet.c * * Slitheen - a decoy routing system for censorship resistance * Copyright (C) 2017 Cecylia Bocovich (cbocovic@uwaterloo.ca) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining * it with the OpenSSL library (or a modified version of that library), * containing parts covered by the terms of the OpenSSL Licence and the * SSLeay license, the licensors of this Program grant you additional * permission to convey the resulting work. Corresponding Source for a * non-source form of such a combination shall include the source code * for the parts of the OpenSSL library used as well as that of the covered * work. */ #include #include "packet.h" #include "util.h" /** This function extracts the ip, tcp, and tls record headers * from a received packet (if they exist), and put them in * a packet_info struct */ void extract_packet_headers(uint8_t *packet, struct packet_info *info){ /* First fill in IP header */ uint8_t *p = packet; p += ETHER_HEADER_LEN; //skip ethernet header info->ip_hdr = (struct ip_header*) p; info->size_ip_hdr = IP_HEADER_LEN(info->ip_hdr); /* Verify this is an IP packet */ if( (info->ip_hdr->versionihl >>4) != 4){ info->ip_hdr = NULL; info->size_ip_hdr = 0; info->tcp_hdr = NULL; info->size_tcp_hdr = 0; info->record_hdr = NULL; return; } /* If this is a TCP segment, fill in TCP header */ if (info->ip_hdr->proto == IPPROTO_TCP){ p += info->size_ip_hdr; //skip IP header info->tcp_hdr = (struct tcp_header*) p; info->size_tcp_hdr = TCP_HEADER_LEN(info->tcp_hdr); p += info->size_tcp_hdr; } else { info->tcp_hdr = NULL; info->size_tcp_hdr = 0; info->record_hdr = NULL; return; } /* If the application data contains a TLS record, fill in hdr */ info->app_data_len = htons(info->ip_hdr->len) - (info->size_ip_hdr + info->size_tcp_hdr); if(info->app_data_len > 0){ info->app_data = p; info->record_hdr = (struct tls_header*) p; //check to see if this is a valid record if((info->record_hdr->type < 0x14) || (info->record_hdr->type > 0x18)){ info->record_hdr = NULL; } } else { info->record_hdr = NULL; info->app_data = NULL; } return; } /** Copies a packet_info structure and returns a pointer to the duplicate. */ struct packet_info *copy_packet_info(struct packet_info *src_info){ struct packet_info *dst_info = smalloc(sizeof(struct packet_info)); dst_info->ip_hdr = src_info->ip_hdr; dst_info->tcp_hdr = src_info->tcp_hdr; dst_info->size_tcp_hdr = src_info->size_tcp_hdr; dst_info->size_ip_hdr = src_info->size_ip_hdr; dst_info->app_data = src_info->app_data; dst_info->app_data_len = src_info->app_data_len; return dst_info; } /* * Injects a packet back out the opposite interface */ void inject_packet(struct inject_args *iargs, const struct pcap_pkthdr *header, uint8_t *packet){ pcap_t *handle = iargs->write_dev; //write back out to the MAC ADDR it came in on //memmove(packet, packet+ETHER_ADDR_LEN, ETHER_ADDR_LEN); //memcpy(packet+ETHER_ADDR_LEN, iargs->mac_addr, ETHER_ADDR_LEN); if((pcap_inject(handle, packet, header->len)) < 0 ){ fprintf(stderr, "Error: %s\n", pcap_geterr(handle)); printf("Length: %d\n", header->len); } free(packet); }