source: tools/traceanon/traceanon.c @ 5b91b48

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 5b91b48 was d56089a, checked in by Shane Alcock <salcock@…>, 16 years ago

Updated examples and tools to use new function names

  • Property mode set to 100644
File size: 4.7 KB
Line 
1#define _GNU_SOURCE
2#include "libtrace.h"
3#include <stdio.h>
4#include <unistd.h>
5#include <stdlib.h>
6#include <getopt.h>
7#include <stdbool.h>
8#include <stddef.h>
9#include <string.h>
10#include <time.h>
11#include "ipenc.h"
12
13
14void usage(char *argv0)
15{
16        fprintf(stderr,"Usage:\n"
17        "%s flags inputfile outputfile\n"
18        "-s --encrypt-source    Encrypt the source addresses\n"
19        "-d --encrypt-dest      Encrypt the destination addresses\n"
20        "-c --cryptopan=key     Encrypt the addresses with the cryptopan\n"
21        "                       prefix preserving\n"
22        "-p --prefix=C.I.D.R/bits Substitute the prefix of the address\n"
23        ,argv0);
24        exit(1);
25}
26
27// Incrementally update a checksum
28void update_in_cksum(uint16_t *csum, uint16_t old, uint16_t new)
29{
30        uint32_t sum = (~htons(*csum) & 0xFFFF) 
31                     + (~htons(old) & 0xFFFF) 
32                     + htons(new);
33        sum = (sum & 0xFFFF) + (sum >> 16);
34        *csum = htons(~(sum + (sum >> 16)));
35}
36
37void update_in_cksum32(uint16_t *csum, uint32_t old, uint32_t new)
38{
39        update_in_cksum(csum,old>>16,new>>16);
40        update_in_cksum(csum,old&0xFFFF,new&0xFFFF);
41}
42
43/* Ok this is remarkably complicated
44 *
45 * We want to change one, or the other IP address, while preserving the
46 * checksum.  TCP and UDP both include the faux header in their checksum
47 * calculations, so you have to update them too.  ICMP is even worse --
48 * it can include the original IP packet that caused the error!  So anonymise
49 * that too, but remember that it's travelling in the opposite direction so
50 * we need to encrypt the destination and source instead of the source and
51 * destination!
52 */
53void encrypt_ips(struct libtrace_ip *ip,bool enc_source,bool enc_dest)
54{
55        struct libtrace_tcp *tcp;
56        struct libtrace_udp *udp;
57        struct libtrace_icmp *icmp;
58
59        tcp=trace_get_tcp_from_ip(ip,NULL);
60        udp=trace_get_udp_from_ip(ip,NULL);
61        icmp=trace_get_icmp_from_ip(ip,NULL);
62
63        if (enc_source) {
64                uint32_t old_ip=ip->ip_src.s_addr;
65                uint32_t new_ip=htonl(enc_ip(
66                                        htonl(ip->ip_src.s_addr)
67                                        ));
68                update_in_cksum32(&ip->ip_sum,old_ip,new_ip);
69                if (tcp) update_in_cksum(&tcp->check,old_ip,new_ip);
70                if (udp) update_in_cksum(&udp->check,old_ip,new_ip);
71                ip->ip_src.s_addr = new_ip;
72        }
73
74        if (enc_dest) {
75                uint32_t old_ip=ip->ip_dst.s_addr;
76                uint32_t new_ip=htonl(enc_ip(
77                                        htonl(ip->ip_dst.s_addr)
78                                        ));
79                update_in_cksum32(&ip->ip_sum,old_ip,new_ip);
80                if (tcp) update_in_cksum(&tcp->check,old_ip,new_ip);
81                if (udp) update_in_cksum(&udp->check,old_ip,new_ip);
82                ip->ip_dst.s_addr = new_ip;
83        }
84
85        if (icmp) {
86                /* These are error codes that return the IP packet internally */
87                if (icmp->type == 3 || icmp->type == 5 || icmp->type == 11) {
88                        encrypt_ips(
89                                        (struct libtrace_ip*)icmp+
90                                                sizeof(struct libtrace_icmp),
91                                        enc_dest,
92                                        enc_source);
93                }
94        }
95}
96
97int main(int argc, char *argv[]) 
98{
99        enum enc_type_t enc_type = ENC_NONE;
100        char *key = NULL;
101        struct libtrace_t *trace = 0;
102        struct libtrace_packet_t *packet = trace_create_packet();
103        struct libtrace_out_t *writer = 0;
104        bool enc_source = false;
105        bool enc_dest   = false;
106        char *output = 0;
107
108        if (argc<2)
109                usage(argv[0]);
110
111        while (1) {
112                int option_index;
113                struct option long_options[] = {
114                        { "encrypt-source",     0, 0, 's' },
115                        { "encrypt-dest",       0, 0, 'd' },
116                        { "cryptopan",          1, 0, 'c' },
117                        { "prefix",             1, 0, 'p' },
118                        { NULL,                 0, 0, 0 },
119                };
120
121                int c=getopt_long(argc, argv, "sc:dp:",
122                                long_options, &option_index);
123
124                if (c==-1)
125                        break;
126
127                switch (c) {
128                        case 's': enc_source=true; break;
129                        case 'd': enc_dest  =true; break;
130                        case 'c':
131                                  if (key!=NULL) {
132                                          fprintf(stderr,"You can only have one encryption type and one key\n");
133                                          usage(argv[0]);
134                                  }
135                                  key=strdup(optarg);
136                                  enc_type = ENC_CRYPTOPAN;
137                                  break;
138                        case 'p':
139                                  if (key!=NULL) {
140                                          fprintf(stderr,"You can only have one encryption type and one key\n");
141                                          usage(argv[0]);
142                                  }
143                                  key=strdup(optarg);
144                                  enc_type = ENC_PREFIX_SUBSTITUTION;
145                                  break;
146                        default:
147                                fprintf(stderr,"unknown option: %c\n",c);
148                                usage(argv[0]);
149
150                }
151
152        }
153
154        enc_init(enc_type,key);
155
156        // open input uri
157        trace = trace_create(argv[optind]);
158        if (!trace) {
159                fprintf(stderr,"Cannot open %s\n",argv[optind]);
160                trace_perror(argv[optind]);
161                return 1;
162        }
163       
164        if (optind == argc) {
165                // no output specified, output in same format to stdout
166                asprintf(&output,"%s:-","erf");
167                writer = trace_create_output(output);
168        } else {
169                writer = trace_create_output(argv[optind +1]);
170        }
171        if (!writer) {
172                trace_perror("trace_create_output");
173                return 1;
174        }
175       
176       
177        for(;;) {
178                struct libtrace_ip *ipptr;
179                int psize;
180                if ((psize = trace_read_packet(trace, packet)) <= 0) {
181                        break;
182                }
183
184                ipptr = trace_get_ip(packet);
185
186                if (ipptr && (enc_source || enc_dest))
187                        encrypt_ips(ipptr,enc_source,enc_dest);
188
189                /* TODO: Encrypt IP's in ARP packets */
190
191                trace_write_packet(writer,packet);
192        }
193        return 0;
194}
Note: See TracBrowser for help on using the repository browser.