]> sjero.net Git - ltp2tcp/blob - udp_encap.c
Remove extra SLL.patch
[ltp2tcp] / udp_encap.c
1 /******************************************************************************
2 Utility to convert a LTP flow to a TCP flow for LTP analysis via tcptrace.
3 <ETH, IPv4, UDP> 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 <netinet/udp.h>
32
33
34
35 extern int debug;
36
37
38
39
40 /* encapsulation manipulation previous to packet conversion */
41 int udp_encap_pre(struct pcap_pkthdr *h, const u_char **odata, u_char **ndata, int* olength, int* nlength)
42 {
43         struct iphdr                    *iph;
44         struct ether_header             *ethh;
45         struct udphdr                   *udph;
46
47         /*Safety checks*/
48         if(!h || !odata || !ndata || !*odata || !*ndata || !olength || !nlength){
49                 dbgprintf(0,"Error: UDP Encapsulation given bad data!\n");
50                 exit(1);
51         }
52         if(*olength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct udphdr)
53                         || *nlength < sizeof(struct ether_header)+sizeof(struct iphdr)+sizeof(struct tcphdr)){
54                         dbgprintf(0, "Error: UDP Encapsulation given packet of wrong size!\n");
55                         return -1;
56         }
57
58         /*initialize encapsulation private data*/
59         if(state.en_priv==NULL){
60                 /* First time, allocate memory and copy libpcap header and encap headers
61                  * this guarantees the IP "direction" of the encap headers */
62                 state.en_priv=malloc(sizeof(struct eip4_en_p));
63                 if(state.en_priv==NULL){
64                         dbgprintf(0,"Error: Couldn't allocate Memory\n");
65                         exit(1);
66                 }
67         }
68         if(fill_eip4_encap((struct eip4_en_p*)state.en_priv, *odata, *olength, h)<0){
69                 return -1;
70         }
71
72         /*Copy Ethernet and IPv4 headers over*/
73         memcpy(*ndata, *odata, sizeof(struct ether_header)+sizeof(struct iphdr));
74         *odata+=sizeof(struct ether_header)+ sizeof(struct iphdr);
75         *ndata+=sizeof(struct ether_header)+ sizeof(struct iphdr);
76
77         /*Confirm that this is Ethernet and that IPv4 is next*/
78         ethh=(struct ether_header*)(*odata -sizeof(struct ether_header)- sizeof(struct iphdr));
79         if(ethh->ether_type!=htons(ETHERTYPE_IP)){
80                 dbgprintf(1, "Note: Packet not Ethernet or Not IPv4 next\n");
81                 return -1;
82         }
83
84         /* Check That this is IPv4 and that UDP is next*/
85         iph= (struct iphdr *) (*ndata - sizeof(struct iphdr));
86         if(iph->version!=4){
87                 dbgprintf(1, "Note: Packet is not IPv4\n");
88                 return -1;
89         }
90         if(iph->protocol!=0x11){
91                 dbgprintf(1, "Note: Packet is not UDP\n");
92                 return -1;
93         }
94
95         /*set ip to indicate that tcp is next protocol*/
96         iph->protocol=6;
97         iph->check=htonl(0);
98
99         /* Adjust libpcap headers*/
100         h->caplen=sizeof(struct ether_header) +sizeof(struct iphdr);
101         h->len=sizeof(struct ether_header) +sizeof(struct iphdr);
102
103         /*Adjust packet length*/
104         udph=(struct udphdr*)*odata;
105         *olength=ntohs(udph->len);
106
107         /*Adjust New Packet Length*/
108         *nlength-=sizeof(struct ether_header) +sizeof(struct iphdr);
109
110         /*Move Packet Pointer past UDP header*/
111         *odata+=sizeof(struct udphdr);
112 return 0;
113 }
114
115 /* encapsulation manipulation after conversion */
116 int udp_encap_post(int tlen, u_char *data)
117 {
118         return eip4_post((struct eip4_en_p*)state.en_priv, tlen, data);
119 }
120
121 /* Create a TCP three-way handshake */
122 int udp_encap_handshake(struct pcap_pkthdr *h)
123 {
124         return eip4_handshake((struct eip4_en_p*)state.en_priv, h);
125 }
126
127 /* Create a TCP ending handshake */
128 int udp_encap_fin()
129 {
130         return eip4_fin((struct eip4_en_p*)state.en_priv);
131 }
132
133
134
135
136 /* The UDP Encapsulation Structure*/
137 struct encap_ops udp_encap = {
138         .pre=udp_encap_pre,
139         .post=udp_encap_post,
140         .handshake=udp_encap_handshake,
141         .fin=udp_encap_fin
142 };