1 /******************************************************************************
2 Utility to convert a DCCP flow to a TCP flow for DCCP analysis via
3 tcptrace. Encapsulation Functions for DCCP conversion to TCP.
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>
22 ******************************************************************************/
25 #include "checksums.h"
27 #include <netinet/ip6.h>
29 /*Encapsulation start point and link layer selector*/
30 int do_encap(int link, struct packet *new, const struct const_packet *old)
35 if(!ethernet_encap(new, old)){
41 if(!ipv4_encap(new, old)){
46 /*Linux Cooked Capture*/
47 if(!linux_cooked_encap(new, old)){
52 dbgprintf(0, "Unknown Link Layer\n");
56 /*Adjust libpcap header*/
57 if(new->h->caplen >= new->h->len || new->h->caplen >= new->length){
58 new->h->caplen=new->length;
60 new->h->len=new->length;
65 /*Standard Ethernet Encapsulation*/
66 int ethernet_encap(struct packet *new, const struct const_packet *old)
68 struct ether_header *ethh;
69 struct const_packet nold;
73 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
74 dbgprintf(0,"Error: Ethernet Encapsulation Function given bad data!\n");
77 if(old->length < sizeof(struct ether_header) || new->length < sizeof(struct ether_header)){
78 dbgprintf(0, "Error: Ethernet Encapsulation Function given packet of wrong size!\n");
82 /*Copy Ethernet header over*/
83 memcpy(new->data, old->data, sizeof(struct ether_header));
86 ethh=(struct ether_header*)(new->data);
88 /*Adjust pointers and lengths*/
89 nold.data= old->data+ sizeof(struct ether_header);
90 nnew.data= new->data + sizeof(struct ether_header);
91 nold.length= old->length - sizeof(struct ether_header);
92 nnew.length= new->length - sizeof(struct ether_header);
96 /*Select Next Protocol*/
97 switch(ntohs(ethh->ether_type)){
99 if(!ipv4_encap(&nnew, &nold)){
104 if(!ipv6_encap(&nnew, &nold)){
109 dbgprintf(1, "Unknown Next Protocol at Ethernet\n");
115 new->length=nnew.length + sizeof(struct ether_header);
119 /*IPv6 Encapsulation*/
120 int ipv6_encap(struct packet *new, const struct const_packet *old)
124 struct const_packet nold;
127 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
128 dbgprintf(0,"Error: IPv6 Encapsulation Function given bad data!\n");
131 if(old->length < sizeof(struct ip6_hdr) || new->length < sizeof(struct ip6_hdr)){
132 dbgprintf(0, "Error: IPv6 Encapsulation Function given packet of wrong size!\n");
136 /*Copy IPv6 header over*/
137 memcpy(new->data, old->data, sizeof(struct ip6_hdr));
140 iph=(struct ip6_hdr*)(new->data);
142 /*Adjust pointers and lengths*/
143 nold.data= old->data + sizeof(struct ip6_hdr);
144 nnew.data= new->data +sizeof(struct ip6_hdr);
145 nold.length= old->length - sizeof(struct ip6_hdr);
146 nnew.length= new->length - sizeof(struct ip6_hdr);
150 /*Confirm that this is IPv6*/
151 if((ntohl(iph->ip6_ctlun.ip6_un1.ip6_un1_flow) & (0xF0000000)) == (60000000)){
152 dbgprintf(1, "Note: Packet is not IPv6\n");
156 /*Select Next Protocol*/
157 switch(iph->ip6_ctlun.ip6_un1.ip6_un1_nxt){
161 nnew.src_id=malloc(nnew.id_len);
162 nnew.dest_id=malloc(nnew.id_len);
163 if(nnew.src_id==NULL||nnew.dest_id==NULL){
164 dbgprintf(0,"Error: Couldn't allocate Memory\n");
167 memcpy(nnew.src_id,&iph->ip6_src,nnew.id_len);
168 memcpy(nnew.dest_id,&iph->ip6_dst,nnew.id_len);
169 if(!convert_packet(&nnew, &nold)){
174 dbgprintf(1, "Unknown Next Protocol at IPv6\n");
179 /*set ip to indicate that TCP is next protocol*/
180 iph->ip6_ctlun.ip6_un1.ip6_un1_nxt=6;
182 /*Determine if computed length is reasonable*/
183 if(nnew.length > 0xFFFF){
184 dbgprintf(1, "Error: Given TCP data length is too large for an IPv6 packet!\n");
188 /*Adjust IPv6 header to account for packet's total length*/
189 iph->ip6_ctlun.ip6_un1.ip6_un1_plen=htons(nnew.length);
192 new->length=nnew.length + sizeof(struct ip6_hdr);
200 /*IPv4 Encapsulation*/
201 int ipv4_encap(struct packet *new, const struct const_packet *old)
205 struct const_packet nold;
208 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
209 dbgprintf(0,"Error: IPv4 Encapsulation Function given bad data!\n");
212 if(old->length < sizeof(struct iphdr) || new->length < sizeof(struct iphdr)){
213 dbgprintf(0, "Error: IPv4 Encapsulation Function given packet of wrong size!\n");
217 /*Copy IPv4 header over*/
218 memcpy(new->data, old->data, sizeof(struct iphdr));
221 iph=(struct iphdr*)(new->data);
223 /*Adjust pointers and lengths*/
224 nold.data= old->data +iph->ihl*4;
225 nnew.data= new->data +iph->ihl*4;
226 nold.length= old->length -iph->ihl*4;
227 nnew.length= new->length -iph->ihl*4;
231 /*Confirm that this is IPv4*/
233 dbgprintf(1, "Note: Packet is not IPv4\n");
237 /*Select Next Protocol*/
238 switch(iph->protocol){
242 nnew.src_id=malloc(nnew.id_len);
243 nnew.dest_id=malloc(nnew.id_len);
244 if(nnew.src_id==NULL||nnew.dest_id==NULL){
245 dbgprintf(0,"Error: Couldn't allocate Memory\n");
248 memcpy(nnew.src_id,&iph->saddr,nnew.id_len);
249 memcpy(nnew.dest_id,&iph->daddr,nnew.id_len);
250 if(!convert_packet(&nnew, &nold)){
255 dbgprintf(1, "Unknown Next Protocol at IPv4\n");
260 /*set ip to indicate that TCP is next protocol*/
265 new->length=nnew.length + iph->ihl*4;
267 /*Determine if computed length is reasonable*/
268 if(nnew.length > 0xFFFF){
269 dbgprintf(1, "Error: Given TCP header+data length is too large for an IPv4 packet!\n");
273 /*Adjust IPv4 header to account for packet's total length*/
274 iph->tot_len=htons(new->length);
276 /*Compute IPv4 Checksum*/
278 iph->check=ipv4_chksum(new->data,iph->ihl*4);
286 int linux_cooked_encap(struct packet *new, const struct const_packet *old)
288 struct sll_header *slh;
290 struct const_packet nold;
294 if(!new|| !old || !new->data || !old->data || !new->h || !old->h){
295 dbgprintf(0,"Error: SLL Encapsulation Function given bad data!\n");
298 if(old->length < sizeof(struct sll_header) || new->length < sizeof(struct sll_header)){
299 dbgprintf(0, "Error: SLL Encapsulation Function given packet of wrong size!\n");
303 /*Copy SLL header over*/
304 memcpy(new->data, old->data, sizeof(struct sll_header));
307 slh=(struct sll_header*)(new->data);
309 /*Adjust pointers and lengths*/
310 nold.data= old->data + sizeof(struct sll_header);
311 nnew.data= new->data + sizeof(struct sll_header);
312 nold.length= old->length - sizeof(struct sll_header);
313 nnew.length= new->length- sizeof(struct sll_header);
317 /*Confirm that this is SLL*/
318 if(ntohs(slh->sll_pkttype) > 4){
319 dbgprintf(1, "Note: Packet is not SLL (Linux Cooked Capture)\n");
323 /*Select Next Protocol*/
324 switch(ntohs(slh->sll_protocol)){
326 if(!ipv4_encap(&nnew, &nold)){
331 if(!ipv6_encap(&nnew, &nold)){
336 dbgprintf(1, "Unknown Next Protocol at SLL\n");
342 new->length=nnew.length + sizeof(struct sll_header);