1 /******************************************************************************
2 Utility to convert a DCCP flow to a TCP flow for DCCP analysis via
5 Copyright (C) 2012 Samuel Jero <sj323707@ohio.edu>
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 Author: Samuel Jero <sj323707@ohio.edu>
25 2)DCCP MUST use 48 bit sequence numbers
26 3)DCCP DATA packets are not implemented (Linux doesn't use them)
27 4)DCCP Ack packets show up as TCP packets containing one byte
28 ******************************************************************************/
32 #define DCCP2TCP_VERSION 1.6
33 #define COPYRIGHT_YEAR 2013
36 int debug=0; /*set to 1 to turn on debugging information*/
37 int yellow=0; /*tcptrace yellow line as currently acked packet*/
38 int green=0; /*tcptrace green line as currently acked packet*/
39 int sack=0; /*add TCP SACKS*/
42 pcap_t* in; /*libpcap input file discriptor*/
43 pcap_dumper_t *out; /*libpcap output file discriptor*/
44 struct connection *chead; /*connection list*/
47 void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes);
52 /*Parse commandline options and open files*/
53 int main(int argc, char *argv[])
60 /*parse commandline options*/
65 /*loop through commandline options*/
66 for(int i=1; i < argc; i++){
67 if(argv[i][0]!='-' || (argv[i][0]=='-' && strlen(argv[i])==1)){
68 if(dfile==NULL || argv[i][0]=='-'){
69 /*assign first non-dash (or only dash) argument to the dccp file*/
73 tfile=argv[i]; /*assign second non-dash argument to the dccp file*/
79 if(argv[i][1]=='d' && strlen(argv[i])==2){ /* -d */
82 if(argv[i][1]=='y' && strlen(argv[i])==2){ /* -y */
85 if(argv[i][1]=='g' && strlen(argv[i])==2){ /* -g */
88 if(argv[i][1]=='s' && strlen(argv[i])==2){ /* -s */
91 if(argv[i][1]=='h' && strlen(argv[i])==2){ /* -h */
94 if(argv[i][1]=='V' && strlen(argv[i])==2){ /* -V */
100 if(dfile==NULL || tfile==NULL){
104 /*all options validated*/
107 dbgprintf(1,"Debug On\n");
109 dbgprintf(1,"Tcptrace green line at highest acknowledgment\n");
111 dbgprintf(1,"Tcptrace green line at highest acknowledged acknowledgment\n");
114 dbgprintf(1,"Tcptrace yellow line at highest acknowledgment\n");
116 dbgprintf(1,"Tcptrace yellow line window value (a made up number)\n");
119 dbgprintf(1,"Adding TCP SACKS\n");
121 dbgprintf(1,"Input file: %s\n", dfile);
122 dbgprintf(1,"Output file: %s\n", tfile);
125 /*attempt to open input file*/
126 in=pcap_open_offline(dfile, erbuffer);
128 dbgprintf(0,"Error opening input file\n");
132 /*attempt to open output file*/
133 out=pcap_dump_open(in,tfile);
135 dbgprintf(0,"Error opening output file\n");
141 u_char *user=(u_char*)out;
142 pcap_loop(in, -1, handle_packet, user);
146 pcap_dump_close(out);
148 /*Delete all connections*/
149 cleanup_connections();
154 /*call back function for pcap_loop--do basic packet handling*/
155 void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
158 struct pcap_pkthdr nh;
161 struct const_packet old;
163 /*Determine the link type for this packet*/
164 link_type=pcap_datalink(in);
166 /*create new libpcap header*/
167 memcpy(&nh, h, sizeof(struct pcap_pkthdr));
169 /*Setup packet structs*/
171 old.length=h->caplen;
176 new.length=MAX_PACKET;
180 /*create buffer for new packet*/
181 new.data=ndata=malloc(MAX_PACKET);
183 dbgprintf(0,"Error: Couldn't allocate Memory\n");
187 /*make sure the packet is all zero*/
188 memset(new.data, 0, MAX_PACKET);
190 /*do all the fancy conversions*/
191 if(!do_encap(link_type, &new, &old)){
197 pcap_dump(user,&nh, ndata);
203 /*do all the dccp to tcp conversions*/
204 int convert_packet(struct packet *new, const struct const_packet* old)
207 struct dccp_hdr *dccph;
208 struct dccp_hdr_ext *dccphex;
209 struct host *h1=NULL;
210 struct host *h2=NULL;
213 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
214 dbgprintf(0,"Error: Convert Packet Function given bad data!\n");
218 if(old->length < (sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext)) || new->length < sizeof(struct dccp_hdr)){
219 dbgprintf(0, "Error: DCCP Packet Too short!\n");
223 /*cast header pointers*/
224 tcph=(struct tcphdr*)new->data;
225 dccph=(struct dccp_hdr*)old->data;
226 dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
228 dbgprintf(2,"Sequence Number: %llu\n", (unsigned long long)
229 (((unsigned long)ntohs(dccph->dccph_seq)<<32) + ntohl(dccphex->dccph_seq_low)));
231 /*Ensure packet is at least as large as DCCP header*/
232 if(old->length < dccph->dccph_doff*4){
233 dbgprintf(0, "Error: DCCP Header truncated\n");
238 if(get_host(new->src_id, new->dest_id, new->id_len,
239 dccph->dccph_sport, dccph->dccph_dport, &h1, &h2)){
240 dbgprintf(0,"Error: Can't Get Hosts!\n");
243 if(h1==NULL || h2==NULL){
244 dbgprintf(0, "Error: Can't Get Hosts!\n");
248 /*TODO: Add CCID detection*/
249 if(h1->type==CCID2 && h2->type==CCID2){
250 if(ccid2_convert_packet(new,old)==0){
254 if(h1->type==CCID3 && h2->type==CCID3){
255 //ccid3_convert_packet(new,old);
257 if(ccid2_convert_packet(new,old)==0){
261 /*Compute TCP checksums*/
262 if(new->id_len==IP4_ADDR_LEN){
264 tcph->check=ipv4_pseudohdr_chksum(new->data,
265 new->length, new->dest_id, new->src_id, 6);
266 }else if(new->id_len==IP6_ADDR_LEN){
268 tcph->check=ipv6_pseudohdr_chksum(new->data,
269 new->length, new->dest_id, new->src_id, 6);
272 dbgprintf(2,"Unknown ID Length, can't do checksums");
279 dbgprintf(0, "dccp2tcp version %.1f\nCopyright (C) %i Samuel Jero <sj323707@ohio.edu>\n", DCCP2TCP_VERSION,COPYRIGHT_YEAR);
280 dbgprintf(0, "This program comes with ABSOLUTELY NO WARRANTY.\n");
281 dbgprintf(0, "This is free software, and you are welcome to\nredistribute it under certain conditions.\n");
285 /*Usage information for program*/
288 dbgprintf(0,"Usage: dccp2tcp dccp_file tcp_file [-d] [-h] [-V] [-y] [-g] [-s]\n");
289 dbgprintf(0, " -d Debug. May be repeated for aditional verbosity.\n");
290 dbgprintf(0, " -V Version information\n");
291 dbgprintf(0, " -h Help\n");
292 dbgprintf(0, " -y Yellow line is highest ACK\n");
293 dbgprintf(0, " -g Green line is highest ACK\n");
294 dbgprintf(0, " -s convert ACK Vectors to SACKS\n");
299 void dbgprintf(int level, const char *fmt, ...)
304 vfprintf(stderr, fmt, args);