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>
25 2)DCCP MUST use 48 bit sequence numbers
26 3)DCCP DATA packets are not implemented (Linux doesn't use them)
27 4)DCCP Ack packets show up as TCP packets containing one byte
28 ******************************************************************************/
31 #include "checksums.h"
33 #include <netinet/ip6.h>
35 /*Encapsulation start point and link layer selector*/
36 int do_encap(int link, struct packet *new, const struct const_packet *old)
41 if(!ethernet_encap(new, old)){
47 if(!ipv4_encap(new, old)){
52 /*Linux Cooked Capture*/
53 if(!linux_cooked_encap(new, old)){
58 dbgprintf(0, "Unknown Link Layer\n");
62 /*Adjust libpcap header*/
63 if(new->h->caplen >= new->h->len || new->h->caplen >= new->length){
64 new->h->caplen=new->length;
66 new->h->len=new->length;
71 /*Standard Ethernet Encapsulation*/
72 int ethernet_encap(struct packet *new, const struct const_packet *old)
74 struct ether_header *ethh;
75 struct const_packet nold;
79 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
80 dbgprintf(0,"Error: Ethernet Encapsulation Function given bad data!\n");
83 if(old->length < sizeof(struct ether_header) || new->length < sizeof(struct ether_header)){
84 dbgprintf(0, "Error: Ethernet Encapsulation Function given packet of wrong size!\n");
88 /*Copy Ethernet header over*/
89 memcpy(new->data, old->data, sizeof(struct ether_header));
92 ethh=(struct ether_header*)(new->data);
94 /*Adjust pointers and lengths*/
95 nold.data= old->data+ sizeof(struct ether_header);
96 nnew.data= new->data + sizeof(struct ether_header);
97 nold.length= old->length - sizeof(struct ether_header);
98 nnew.length= new->length - sizeof(struct ether_header);
102 /*Select Next Protocol*/
103 switch(ntohs(ethh->ether_type)){
105 if(!ipv4_encap(&nnew, &nold)){
110 if(!ipv6_encap(&nnew, &nold)){
115 dbgprintf(1, "Unknown Next Protocol at Ethernet\n");
121 new->length=nnew.length + sizeof(struct ether_header);
125 /*IPv6 Encapsulation*/
126 int ipv6_encap(struct packet *new, const struct const_packet *old)
130 struct const_packet nold;
133 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
134 dbgprintf(0,"Error: IPv6 Encapsulation Function given bad data!\n");
137 if(old->length < sizeof(struct ip6_hdr) || new->length < sizeof(struct ip6_hdr)){
138 dbgprintf(0, "Error: IPv6 Encapsulation Function given packet of wrong size!\n");
142 /*Copy IPv6 header over*/
143 memcpy(new->data, old->data, sizeof(struct ip6_hdr));
146 iph=(struct ip6_hdr*)(new->data);
148 /*Adjust pointers and lengths*/
149 nold.data= old->data + sizeof(struct ip6_hdr);
150 nnew.data= new->data +sizeof(struct ip6_hdr);
151 nold.length= old->length - sizeof(struct ip6_hdr);
152 nnew.length= new->length - sizeof(struct ip6_hdr);
156 /*Confirm that this is IPv6*/
157 if((ntohl(iph->ip6_ctlun.ip6_un1.ip6_un1_flow) & (0xF0000000)) == (60000000)){
158 dbgprintf(1, "Note: Packet is not IPv6\n");
162 /*Select Next Protocol*/
163 switch(iph->ip6_ctlun.ip6_un1.ip6_un1_nxt){
167 nnew.src_id=malloc(nnew.id_len);
168 nnew.dest_id=malloc(nnew.id_len);
169 if(nnew.src_id==NULL||nnew.dest_id==NULL){
170 dbgprintf(0,"Error: Couldn't allocate Memory\n");
173 memcpy(nnew.src_id,&iph->ip6_src,nnew.id_len);
174 memcpy(nnew.dest_id,&iph->ip6_dst,nnew.id_len);
175 if(!convert_packet(&nnew, &nold)){
180 dbgprintf(1, "Unknown Next Protocol at IPv6\n");
185 /*set ip to indicate that TCP is next protocol*/
186 iph->ip6_ctlun.ip6_un1.ip6_un1_nxt=6;
188 /*Determine if computed length is reasonable*/
189 if(nnew.length > 0xFFFF){
190 dbgprintf(1, "Error: Given TCP data length is too large for an IPv6 packet!\n");
194 /*Adjust IPv6 header to account for packet's total length*/
195 iph->ip6_ctlun.ip6_un1.ip6_un1_plen=htons(new->length);
198 new->length=nnew.length + sizeof(struct ip6_hdr);
206 /*IPv4 Encapsulation*/
207 int ipv4_encap(struct packet *new, const struct const_packet *old)
211 struct const_packet nold;
214 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
215 dbgprintf(0,"Error: IPv4 Encapsulation Function given bad data!\n");
218 if(old->length < sizeof(struct iphdr) || new->length < sizeof(struct iphdr)){
219 dbgprintf(0, "Error: IPv4 Encapsulation Function given packet of wrong size!\n");
223 /*Copy IPv4 header over*/
224 memcpy(new->data, old->data, sizeof(struct iphdr));
227 iph=(struct iphdr*)(new->data);
229 /*Adjust pointers and lengths*/
230 nold.data= old->data +iph->ihl*4;
231 nnew.data= new->data +iph->ihl*4;
232 nold.length= old->length -iph->ihl*4;
233 nnew.length= new->length -iph->ihl*4;
237 /*Confirm that this is IPv4*/
239 dbgprintf(1, "Note: Packet is not IPv4\n");
243 /*Select Next Protocol*/
244 switch(iph->protocol){
248 nnew.src_id=malloc(nnew.id_len);
249 nnew.dest_id=malloc(nnew.id_len);
250 if(nnew.src_id==NULL||nnew.dest_id==NULL){
251 dbgprintf(0,"Error: Couldn't allocate Memory\n");
254 memcpy(nnew.src_id,&iph->saddr,nnew.id_len);
255 memcpy(nnew.dest_id,&iph->daddr,nnew.id_len);
256 if(!convert_packet(&nnew, &nold)){
261 dbgprintf(1, "Unknown Next Protocol at IPv4\n");
266 /*set ip to indicate that TCP is next protocol*/
271 new->length=nnew.length + iph->ihl*4;
273 /*Determine if computed length is reasonable*/
274 if(nnew.length > 0xFFFF){
275 dbgprintf(1, "Error: Given TCP header+data length is too large for an IPv4 packet!\n");
279 /*Adjust IPv4 header to account for packet's total length*/
280 iph->tot_len=htons(new->length);
282 /*Compute IPv4 Checksum*/
284 iph->check=ipv4_chksum(new->data,iph->ihl*4);
292 int linux_cooked_encap(struct packet *new, const struct const_packet *old)
294 struct sll_header *slh;
296 struct const_packet nold;
300 if(!new|| !old || !new->data || !old->data || !new->h || !old->h){
301 dbgprintf(0,"Error: SLL Encapsulation Function given bad data!\n");
304 if(old->length < sizeof(struct sll_header) || new->length < sizeof(struct sll_header)){
305 dbgprintf(0, "Error: SLL Encapsulation Function given packet of wrong size!\n");
309 /*Copy SLL header over*/
310 memcpy(new->data, old->data, sizeof(struct sll_header));
313 slh=(struct sll_header*)(new->data);
315 /*Adjust pointers and lengths*/
316 nold.data= old->data + sizeof(struct sll_header);
317 nnew.data= new->data + sizeof(struct sll_header);
318 nold.length= old->length - sizeof(struct sll_header);
319 nnew.length= new->length- sizeof(struct sll_header);
323 /*Confirm that this is SLL*/
324 if(ntohs(slh->sll_pkttype) > 4){
325 dbgprintf(1, "Note: Packet is not SLL (Linux Cooked Capture)\n");
329 /*Select Next Protocol*/
330 switch(ntohs(slh->sll_protocol)){
332 if(!ipv4_encap(&nnew, &nold)){
337 if(!ipv6_encap(&nnew, &nold)){
342 dbgprintf(1, "Unknown Next Protocol at SLL\n");
348 new->length=nnew.length + sizeof(struct sll_header);