123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- #include <pcap.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "ptwist.h"
- #include "rserv.h"
- #define macaddr "08:00:27:e8:9d:d4"
- //Definitions for parsing packet data
- #define ETHER_ADDR_LEN 6
- #define ETHER_HDR_LEN 2*ETHER_ADDR_LEN + 2
- #define RECORD_HDR 5
- #define CLIENT_HELLO_HDR 4
- #define CLIENT_HELLO_RAND 32
- void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
- //TODO: look for slitheen tag. The ClientHello message starts at offset 0x4d of packet after TCP 3-way handshake and has flag [P.].
- //For now, write *all* clientHello msgs to a file
- void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet){
- pcap_t *handle;
- char errbuf[BUFSIZ];
- char *writedev = args;
- int i, res;
- const unsigned char *p;
- FILE *fp;
- byte privkey[PTWIST_BYTES];
- byte key[16];
- handle = pcap_open_live(writedev, BUFSIZ, 1, 1000, errbuf);
- if (handle == NULL){
- fprintf(stderr, "Couldn't open device %s: %s\n", writedev, errbuf);
- }
- /* check for clientHello */
- p = packet;
- p += ETHER_HDR_LEN; //skip ethernet header
- p += (p[0] & 0x0f)*4; //skip IP header
- p += 12; //skip first part of TCP header
- p += (p[0] >> 4)*4 - 12; //skip rest of TCP header
- //check for handshake message
- if (p[0] == 0x16){
- p += RECORD_HDR;
- if (p[0] == 0x01){
- p += CLIENT_HELLO_HDR;
- p += 2; //dunno what these are
- //now pointing to hello random :D
- p += 4; //skipping time bytes
- /* Load the private key */
- fp = fopen("privkey", "rb");
- if (fp == NULL) {
- perror("fopen");
- exit(1);
- }
- res = fread(privkey, PTWIST_BYTES, 1, fp);
- if (res < 1) {
- perror("fread");
- exit(1);
- }
- fclose(fp);
- /* check tag*/
- res = check_tag(key, privkey, p, (const byte *)"context", 7);
- if (res) {
- printf("Untagged\n");
- } else {
- fp = fopen("tags", "wb");
- if (fp == NULL) {
- perror("fopen");
- exit(1);
- }
- //Write tag to file
- for(i=0; i< 28; i++){
- fprintf(fp, "%02x ", p[i]);
- }
- fclose(fp);
- }
- }
- }
- if((pcap_inject(handle, packet, header->len)) < 0 ){
- fprintf(stderr, "Error: %s\n", pcap_geterr(handle));
- }
- pcap_close(handle);
- }
- int usage(void){
- printf("Usage: slitheen-proxy [internal network interface] [NAT interface]\n");
- }
- int main(int argc, char *argv[]){
- pid_t pid;
- char filter1[33] = "ether src host 08:00:27:e8:9d:d4";
- char filter2[33] = "ether src host 08:00:27:e8:9d:d4";
- char *dev1 = NULL; /* Device that leads to the internal network */
- char *dev2 = NULL; /* Device that leads out to the world */
- if (argc != 3) {
- usage();
- return(2);
- }
- dev1 = argv[1];
- dev2 = argv[2];
- snprintf(filter1, 33, "ether src host %s", macaddr);
- snprintf(filter2, 33, "ether dst host %s", macaddr);
- pid = fork();
- if (pid < 0) {
- fprintf(stderr, "Fork call failed.\n");
- return(2);
- }
- if (pid == 0) {
- sniff_packets(dev1, dev2, filter1);
- } else {
- sniff_packets(dev2, dev1, filter2);
- }
-
- return(0);
- }
- int sniff_packets(char *readdev, char *writedev, char *filter){
- pcap_t *handle;
- char errbuf[BUFSIZ];
- struct bpf_program fp;
- bpf_u_int32 mask;
- bpf_u_int32 net;
- if (pcap_lookupnet(readdev, &net, &mask, errbuf) == -1){
- fprintf(stderr, "Can't get netmask for device %s\n", readdev);
- return(2);
- }
- handle = pcap_open_live(readdev, BUFSIZ, 1, 1000, errbuf);
- if (handle == NULL){
- fprintf(stderr, "Couldn't open device %s: %s\n", readdev, errbuf);
- }
- if(pcap_datalink(handle) != DLT_EN10MB) {
- fprintf(stderr, "Device %s does not provide Ethernet headers - not supported\n", readdev);
- return(2);
- }
- if(pcap_compile(handle, &fp, filter, 0 , net) == -1){
- fprintf(stderr, "Couldn't parse filter %s: %s\n", filter, pcap_geterr(handle));
- return(2);
- }
- if (pcap_setfilter(handle, &fp) == -1) {
- fprintf(stderr, "Couldn't install filter %s: %s\n", filter, pcap_geterr(handle));
- return(2);
- }
- /*callback function*/
- pcap_loop(handle, -1, got_packet, writedev);
- /*Sniff a packet*/
- pcap_close(handle);
- return(0);
- }
|