1 /******************************************************************************
2 Utility to convert a LTP flow to a TCP flow for LTP analysis via tcptrace.
3 <ETH, IPv4, DCCP> encapsulation functions
5 Copyright (C) 2013 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>
24 1)Only handles one LTP "connection". There isn't a good way to separate
25 different LTP "connections" from new sessions of the same "connection".
26 Use Tcpdump filters to separate connections. Libpcap filtering could also
28 2)Uses some special types from Linux (u_char, u_int32_t)
29 ******************************************************************************/
31 #include <linux/dccp.h>
39 /* encapsulation manipulation previous to packet conversion */
40 int dccp_encap_pre(struct pcap_pkthdr *h, const u_char **odata, u_char **ndata, int* olength, int* nlength)
43 struct ether_header *ethh;
44 struct dccp_hdr *dccph;
47 if(!h || !odata || !ndata || !*odata || !*ndata || !olength || !nlength){
48 dbgprintf(0,"Error: DCCP Encapsulation given bad data!\n");
51 if(*olength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct dccp_hdr )
52 || *nlength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct tcphdr)){
53 dbgprintf(0, "Error: DCCP Encapsulation given packet of wrong size!\n");
57 /*Determine what type of DCCP packet this is*/
58 dccph=(struct dccp_hdr*) (*odata + sizeof(struct ether_header)+sizeof(struct iphdr));
59 if(dccph->dccph_type!=DCCP_PKT_DATA && dccph->dccph_type!=DCCP_PKT_DATAACK){
60 /*Packet Contains no data, discard*/
61 dbgprintf(2, "Note: DCCP Encapsulation discarding non-data-carrying packet. Type: %i\n", dccph->dccph_type);
65 /*We have a data carrying packet, proceed to process*/
68 /*initialize encapsulation private data*/
69 if(state.en_priv==NULL){
70 /* First time, allocate memory and copy libpcap header and encap headers
71 * this guarantees the IP "direction" of the encap headers */
72 state.en_priv=malloc(sizeof(struct eip4_en_p));
73 if(state.en_priv==NULL){
74 dbgprintf(0,"Error: Couldn't allocate Memory\n");
78 if(fill_eip4_encap((struct eip4_en_p*)state.en_priv, *odata, *olength, h)<0){
82 /*Copy Ethernet and IPv4 headers over*/
83 memcpy(*ndata, *odata, sizeof(struct ether_header)+sizeof(struct iphdr));
84 *odata+=sizeof(struct ether_header)+ sizeof(struct iphdr);
85 *ndata+=sizeof(struct ether_header)+ sizeof(struct iphdr);
87 /*Confirm that this is Ethernet and that IPv4 is next*/
88 ethh=(struct ether_header*)(*odata -sizeof(struct ether_header)- sizeof(struct iphdr));
89 if(ethh->ether_type!=htons(ETHERTYPE_IP)){
90 dbgprintf(1, "Note: Packet not Ethernet or Not IPv4 next\n");
94 /* Check That this is IPv4 and that DCCP is next*/
95 iph= (struct iphdr *) (*ndata - sizeof(struct iphdr));
97 dbgprintf(1, "Note: Packet is not IPv4\n");
100 if(iph->protocol!=33){
101 dbgprintf(1, "Note: Packet is not DCCP\n");
105 /*set IP to indicate that TCP is next protocol*/
109 /* Adjust libpcap headers*/
110 h->caplen=sizeof(struct ether_header) +sizeof(struct iphdr);
111 h->len=sizeof(struct ether_header) +sizeof(struct iphdr);
113 /*Adjust packet length*/
114 *olength=ntohs(iph->tot_len) - dccph->dccph_doff*4;
116 /*Adjust New Packet Length*/
117 *nlength-=sizeof(struct ether_header) +sizeof(struct iphdr);
119 /*Move Packet Pointer past DCCP header*/
120 *odata+=dccph->dccph_doff*4;
125 /* encapsulation manipulation after conversion */
126 int dccp_encap_post(int tlen, u_char *data)
128 return eip4_post((struct eip4_en_p*)state.en_priv, tlen, data);
131 /* Create a TCP three-way handshake */
132 int dccp_encap_handshake(struct pcap_pkthdr *h)
134 return eip4_handshake((struct eip4_en_p*)state.en_priv, h);
137 /* Create a TCP ending handshake */
140 return eip4_fin((struct eip4_en_p*)state.en_priv);
146 /* The DCCP Encapsulation Structure*/
147 struct encap_ops dccp_encap = {
149 .post=dccp_encap_post,
150 .handshake=dccp_encap_handshake,