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)Checksums are not computed (they are zeroed)
27 4)DCCP DATA packets are not implemented (Linux doesn't use them)
28 5)DCCP Ack packets show up as TCP packets containing one byte
29 ******************************************************************************/
33 #define DCCP2TCP_VERSION 1.6
34 #define COPYRIGHT_YEAR 2013
37 int debug=0; /*set to 1 to turn on debugging information*/
38 int yellow=0; /*tcptrace yellow line as currently acked packet*/
39 int green=0; /*tcptrace green line as currently acked packet*/
40 int sack=0; /*add TCP SACKS*/
43 pcap_t* in; /*libpcap input file discriptor*/
44 pcap_dumper_t *out; /*libpcap output file discriptor*/
45 struct connection *chead; /*connection list*/
48 void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes);
53 /*Parse commandline options and open files*/
54 int main(int argc, char *argv[])
61 /*parse commandline options*/
66 /*loop through commandline options*/
67 for(int i=1; i < argc; i++){
68 if(argv[i][0]!='-' || (argv[i][0]=='-' && strlen(argv[i])==1)){
69 if(dfile==NULL || argv[i][0]=='-'){
70 /*assign first non-dash (or only dash) argument to the dccp file*/
74 tfile=argv[i]; /*assign second non-dash argument to the dccp file*/
80 if(argv[i][1]=='d' && strlen(argv[i])==2){ /* -d */
83 if(argv[i][1]=='y' && strlen(argv[i])==2){ /* -y */
86 if(argv[i][1]=='g' && strlen(argv[i])==2){ /* -g */
89 if(argv[i][1]=='s' && strlen(argv[i])==2){ /* -s */
92 if(argv[i][1]=='h' && strlen(argv[i])==2){ /* -h */
95 if(argv[i][1]=='V' && strlen(argv[i])==2){ /* -V */
101 if(dfile==NULL || tfile==NULL){
105 /*all options validated*/
108 dbgprintf(1,"Debug On\n");
110 dbgprintf(1,"Tcptrace green line at highest acknowledgment\n");
112 dbgprintf(1,"Tcptrace green line at highest acknowledged acknowledgment\n");
115 dbgprintf(1,"Tcptrace yellow line at highest acknowledgment\n");
117 dbgprintf(1,"Tcptrace yellow line window value (a made up number)\n");
120 dbgprintf(1,"Adding TCP SACKS\n");
122 dbgprintf(1,"Input file: %s\n", dfile);
123 dbgprintf(1,"Output file: %s\n", tfile);
126 /*attempt to open input file*/
127 in=pcap_open_offline(dfile, erbuffer);
129 dbgprintf(0,"Error opening input file\n");
133 /*attempt to open output file*/
134 out=pcap_dump_open(in,tfile);
136 dbgprintf(0,"Error opening output file\n");
142 u_char *user=(u_char*)out;
143 pcap_loop(in, -1, handle_packet, user);
147 pcap_dump_close(out);
149 /*Delete all connections*/
150 cleanup_connections();
155 /*call back function for pcap_loop--do basic packet handling*/
156 void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
159 struct pcap_pkthdr nh;
162 struct const_packet old;
164 /*Determine the link type for this packet*/
165 link_type=pcap_datalink(in);
167 /*create new libpcap header*/
168 memcpy(&nh, h, sizeof(struct pcap_pkthdr));
170 /*Setup packet structs*/
172 old.length=h->caplen;
177 new.length=MAX_PACKET;
181 /*create buffer for new packet*/
182 new.data=ndata=malloc(MAX_PACKET);
184 dbgprintf(0,"Error: Couldn't allocate Memory\n");
188 /*make sure the packet is all zero*/
189 memset(new.data, 0, MAX_PACKET);
191 /*do all the fancy conversions*/
192 if(!do_encap(link_type, &new, &old)){
198 pcap_dump(user,&nh, ndata);
204 /*do all the dccp to tcp conversions*/
205 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 dccph=(struct dccp_hdr*)old->data;
225 dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
227 dbgprintf(2,"Sequence Number: %llu\n", (unsigned long long)
228 (((unsigned long)ntohs(dccph->dccph_seq)<<32) + ntohl(dccphex->dccph_seq_low)));
230 /*Ensure packet is at least as large as DCCP header*/
231 if(old->length < dccph->dccph_doff*4){
232 dbgprintf(0, "Error: DCCP Header truncated\n");
237 if(get_host(new->src_id, new->dest_id, new->id_len,
238 dccph->dccph_sport, dccph->dccph_dport, &h1, &h2)){
239 dbgprintf(0,"Error: Can't Get Hosts!\n");
242 if(h1==NULL || h2==NULL){
243 dbgprintf(0, "Error: Can't Get Hosts!\n");
247 /*TODO: Add CCID detection*/
248 if(h1->type==CCID2 && h2->type==CCID2){
249 return ccid2_convert_packet(new,old);
251 if(h1->type==CCID3 && h2->type==CCID3){
252 //return ccid3_convert_packet(new,old);
255 return ccid2_convert_packet(new,old);
259 dbgprintf(0, "dccp2tcp version %.1f\nCopyright (C) %i Samuel Jero <sj323707@ohio.edu>\n", DCCP2TCP_VERSION,COPYRIGHT_YEAR);
260 dbgprintf(0, "This program comes with ABSOLUTELY NO WARRANTY.\n");
261 dbgprintf(0, "This is free software, and you are welcome to\nredistribute it under certain conditions.\n");
265 /*Usage information for program*/
268 dbgprintf(0,"Usage: dccp2tcp dccp_file tcp_file [-d] [-h] [-V] [-y] [-g] [-s]\n");
269 dbgprintf(0, " -d Debug. May be repeated for aditional verbosity.\n");
270 dbgprintf(0, " -V Version information\n");
271 dbgprintf(0, " -h Help\n");
272 dbgprintf(0, " -y Yellow line is highest ACK\n");
273 dbgprintf(0, " -g Green line is highest ACK\n");
274 dbgprintf(0, " -s convert ACK Vectors to SACKS\n");
279 void dbgprintf(int level, const char *fmt, ...)
284 vfprintf(stderr, fmt, args);