]> sjero.net Git - ltp2tcp/blob - dccp_encap.c
Remove extra SLL.patch
[ltp2tcp] / dccp_encap.c
1 /******************************************************************************
2 Utility to convert a LTP flow to a TCP flow for LTP analysis via tcptrace.
3 <ETH, IPv4, DCCP> encapsulation functions
4
5 Copyright (C) 2013  Samuel Jero <sj323707@ohio.edu>
6
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.
11
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.
16
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/>.
19
20 Author: Samuel Jero <sj323707@ohio.edu>
21 Date: 06/2013
22
23 Notes:
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
27                 be added in ltp2tcp.
28         2)Uses some special types from Linux (u_char, u_int32_t)
29 ******************************************************************************/
30 #include "ltp2tcp.h"
31 #include <linux/dccp.h>
32
33
34
35 extern int debug;
36
37
38
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)
41 {
42         struct iphdr                    *iph;
43         struct ether_header             *ethh;
44         struct dccp_hdr                 *dccph;
45
46         /*Safety checks*/
47         if(!h || !odata || !ndata || !*odata || !*ndata || !olength || !nlength){
48                 dbgprintf(0,"Error: DCCP Encapsulation given bad data!\n");
49                 exit(1);
50         }
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");
54                         return -1;
55         }
56
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);
62                 return -1;
63         }
64
65         /*We have a data carrying packet, proceed to process*/
66
67
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");
75                         exit(1);
76                 }
77         }
78         if(fill_eip4_encap((struct eip4_en_p*)state.en_priv, *odata, *olength, h)<0){
79                 return -1;
80         }
81
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);
86
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");
91                 return -1;
92         }
93
94         /* Check That this is IPv4 and that DCCP is next*/
95         iph= (struct iphdr *) (*ndata - sizeof(struct iphdr));
96         if(iph->version!=4){
97                 dbgprintf(1, "Note: Packet is not IPv4\n");
98                 return -1;
99         }
100         if(iph->protocol!=33){
101                 dbgprintf(1, "Note: Packet is not DCCP\n");
102                 return -1;
103         }
104
105         /*set IP to indicate that TCP is next protocol*/
106         iph->protocol=6;
107         iph->check=htonl(0);
108
109         /* Adjust libpcap headers*/
110         h->caplen=sizeof(struct ether_header) +sizeof(struct iphdr);
111         h->len=sizeof(struct ether_header) +sizeof(struct iphdr);
112
113         /*Adjust packet length*/
114         *olength=ntohs(iph->tot_len) - dccph->dccph_doff*4;
115
116         /*Adjust New Packet Length*/
117         *nlength-=sizeof(struct ether_header) +sizeof(struct iphdr);
118
119         /*Move Packet Pointer past DCCP header*/
120         *odata+=dccph->dccph_doff*4;
121
122         return 0;
123 }
124
125 /* encapsulation manipulation after conversion */
126 int dccp_encap_post(int tlen, u_char *data)
127 {
128         return eip4_post((struct eip4_en_p*)state.en_priv, tlen, data);
129 }
130
131 /* Create a TCP three-way handshake */
132 int dccp_encap_handshake(struct pcap_pkthdr *h)
133 {
134         return eip4_handshake((struct eip4_en_p*)state.en_priv, h);
135 }
136
137 /* Create a TCP ending handshake */
138 int dccp_encap_fin()
139 {
140         return eip4_fin((struct eip4_en_p*)state.en_priv);
141 }
142
143
144
145
146 /* The DCCP Encapsulation Structure*/
147 struct encap_ops dccp_encap = {
148         .pre=dccp_encap_pre,
149         .post=dccp_encap_post,
150         .handshake=dccp_encap_handshake,
151         .fin=dccp_encap_fin
152 };