source: tools/traceanon/traceanon.c @ 3d4fb8f

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 3d4fb8f was 3d4fb8f, checked in by Perry Lorier <perry@…>, 16 years ago

Cleanup the tools

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