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 <pcap/vlan.h>
28 #include <netinet/ip6.h>
31 /*Encapsulation start point and link layer selector*/
32 int do_encap(int link, struct packet *new, const struct const_packet *old)
37 if(!ethernet_encap(new, old)){
43 if(!ipv4_encap(new, old)){
48 /*Linux Cooked Capture*/
49 if(!linux_cooked_encap(new, old)){
54 dbgprintf(0, "Unknown Link Layer\n");
58 /*Adjust libpcap header*/
59 if(new->h->caplen >= new->h->len || new->h->caplen >= new->length){
60 new->h->caplen=new->length;
62 new->h->len=new->length;
67 /*Standard Ethernet Encapsulation*/
68 int ethernet_encap(struct packet *new, const struct const_packet *old)
70 struct ether_header *ethh;
71 struct const_packet nold;
75 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
76 dbgprintf(0,"Error: Ethernet Encapsulation Function given bad data!\n");
79 if(old->length < sizeof(struct ether_header) || new->length < sizeof(struct ether_header)){
80 dbgprintf(0, "Error: Ethernet Encapsulation Function given packet of wrong size!\n");
84 /*Copy Ethernet header over*/
85 memcpy(new->data, old->data, sizeof(struct ether_header));
88 ethh=(struct ether_header*)(new->data);
90 /*Adjust pointers and lengths*/
91 nold.data= old->data+ sizeof(struct ether_header);
92 nnew.data= new->data + sizeof(struct ether_header);
93 nold.length= old->length - sizeof(struct ether_header);
94 nnew.length= new->length - sizeof(struct ether_header);
106 /*Select Next Protocol*/
107 switch(ntohs(ethh->ether_type)){
109 if(!ipv4_encap(&nnew, &nold)){
114 if(!ipv6_encap(&nnew, &nold)){
119 if(!ethernet_vlan_encap(&nnew, &nold)){
124 dbgprintf(1, "Unknown Next Protocol at Ethernet\n");
130 new->length=nnew.length + sizeof(struct ether_header);
134 /*Ethernet 802.1Q VLAN Encapsulation*/
135 int ethernet_vlan_encap(struct packet *new, const struct const_packet *old)
137 struct vlan_tag *tag;
138 struct const_packet nold;
142 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
143 dbgprintf(0,"Error: Ethernet VLAN Encapsulation Function given bad data!\n");
146 if(old->length < sizeof(struct vlan_tag) || new->length < sizeof(struct vlan_tag)){
147 dbgprintf(0, "Error: Ethernet VLAN Encapsulation Function given packet of wrong size!\n");
151 /*Copy VLAN tag over*/
152 memcpy(new->data, old->data, sizeof(struct vlan_tag));
155 tag=(struct vlan_tag*)(new->data);
157 /*Adjust pointers and lengths*/
158 nold.data= old->data+ sizeof(struct vlan_tag);
159 nnew.data= new->data + sizeof(struct vlan_tag);
160 nold.length= old->length - sizeof(struct vlan_tag);
161 nnew.length= new->length - sizeof(struct vlan_tag);
173 /*Select Next Protocol*/
174 switch(ntohs(tag->vlan_tci)){
176 if(!ipv4_encap(&nnew, &nold)){
181 if(!ipv6_encap(&nnew, &nold)){
186 if(!ethernet_vlan_encap(&nnew, &nold)){
191 dbgprintf(1, "Unknown Next Protocol at Ethernet VLAN tag\n");
197 new->length=nnew.length + sizeof(struct vlan_tag);
201 /*IPv6 Encapsulation*/
202 int ipv6_encap(struct packet *new, const struct const_packet *old)
206 struct const_packet nold;
209 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
210 dbgprintf(0,"Error: IPv6 Encapsulation Function given bad data!\n");
213 if(old->length < sizeof(struct ip6_hdr) || new->length < sizeof(struct ip6_hdr)){
214 dbgprintf(0, "Error: IPv6 Encapsulation Function given packet of wrong size!\n");
218 /*Copy IPv6 header over*/
219 memcpy(new->data, old->data, sizeof(struct ip6_hdr));
222 iph=(struct ip6_hdr*)(new->data);
224 /*Adjust pointers and lengths*/
225 nold.data= old->data + sizeof(struct ip6_hdr);
226 nnew.data= new->data +sizeof(struct ip6_hdr);
227 nold.length= old->length - sizeof(struct ip6_hdr);
228 nnew.length= new->length - sizeof(struct ip6_hdr);
231 nnew.print_id=print_ipv6;
232 nold.print_id=print_ipv6;
236 /*Confirm that this is IPv6*/
237 if((ntohl(iph->ip6_ctlun.ip6_un1.ip6_un1_flow) & (0xF0000000)) == (60000000)){
238 dbgprintf(1, "Note: Packet is not IPv6\n");
242 /*Select Next Protocol*/
243 switch(iph->ip6_ctlun.ip6_un1.ip6_un1_nxt){
246 nnew.src_id=malloc(nnew.id_len);
247 nnew.dest_id=malloc(nnew.id_len);
248 nold.src_id=malloc(nold.id_len);
249 nold.dest_id=malloc(nold.id_len);
250 if(nnew.src_id==NULL||nnew.dest_id==NULL ||
251 nold.src_id==NULL||nold.dest_id==NULL){
252 dbgprintf(0,"Error: Couldn't allocate Memory\n");
255 memcpy(nnew.src_id,&iph->ip6_src,nnew.id_len);
256 memcpy(nnew.dest_id,&iph->ip6_dst,nnew.id_len);
257 memcpy(nold.src_id,&iph->ip6_src,nold.id_len);
258 memcpy(nold.dest_id,&iph->ip6_dst,nold.id_len);
259 if(!convert_packet(&nnew, &nold)){
264 dbgprintf(1, "Unknown Next Protocol at IPv6\n");
269 /*set ip to indicate that TCP is next protocol*/
270 iph->ip6_ctlun.ip6_un1.ip6_un1_nxt=6;
272 /*Determine if computed length is reasonable*/
273 if(nnew.length > 0xFFFF){
274 dbgprintf(1, "Error: Given TCP data length is too large for an IPv6 packet!\n");
278 /*Adjust IPv6 header to account for packet's total length*/
279 iph->ip6_ctlun.ip6_un1.ip6_un1_plen=htons(nnew.length);
282 new->length=nnew.length + sizeof(struct ip6_hdr);
292 /*IPv4 Encapsulation*/
293 int ipv4_encap(struct packet *new, const struct const_packet *old)
297 struct const_packet nold;
300 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
301 dbgprintf(0,"Error: IPv4 Encapsulation Function given bad data!\n");
304 if(old->length < sizeof(struct iphdr) || new->length < sizeof(struct iphdr)){
305 dbgprintf(0, "Error: IPv4 Encapsulation Function given packet of wrong size!\n");
309 /*Copy IPv4 header over*/
310 memcpy(new->data, old->data, sizeof(struct iphdr));
313 iph=(struct iphdr*)(new->data);
315 /*Adjust pointers and lengths*/
316 nold.data= old->data +iph->ihl*4;
317 nnew.data= new->data +iph->ihl*4;
318 nold.length= old->length -iph->ihl*4;
319 nnew.length= new->length -iph->ihl*4;
322 nnew.print_id=print_ipv4;
323 nold.print_id=print_ipv4;
327 /*Confirm that this is IPv4*/
329 dbgprintf(1, "Note: Packet is not IPv4\n");
333 /*Select Next Protocol*/
334 switch(iph->protocol){
337 nnew.src_id=malloc(nnew.id_len);
338 nnew.dest_id=malloc(nnew.id_len);
339 nold.src_id=malloc(nold.id_len);
340 nold.dest_id=malloc(nold.id_len);
341 if(nnew.src_id==NULL||nnew.dest_id==NULL||
342 nold.src_id==NULL||nold.dest_id==NULL){
343 dbgprintf(0,"Error: Couldn't allocate Memory\n");
346 memcpy(nnew.src_id,&iph->saddr,nnew.id_len);
347 memcpy(nnew.dest_id,&iph->daddr,nnew.id_len);
348 memcpy(nold.src_id,&iph->saddr,nold.id_len);
349 memcpy(nold.dest_id,&iph->daddr,nold.id_len);
350 if(!convert_packet(&nnew, &nold)){
355 dbgprintf(1, "Unknown Next Protocol at IPv4\n");
360 /*set ip to indicate that TCP is next protocol*/
365 new->length=nnew.length + iph->ihl*4;
367 /*Determine if computed length is reasonable*/
368 if(nnew.length > 0xFFFF){
369 dbgprintf(1, "Error: Given TCP header+data length is too large for an IPv4 packet!\n");
373 /*Adjust IPv4 header to account for packet's total length*/
374 iph->tot_len=htons(new->length);
376 /*Compute IPv4 Checksum*/
378 iph->check=ipv4_chksum(new->data,iph->ihl*4);
388 int linux_cooked_encap(struct packet *new, const struct const_packet *old)
390 struct sll_header *slh;
392 struct const_packet nold;
396 if(!new|| !old || !new->data || !old->data || !new->h || !old->h){
397 dbgprintf(0,"Error: SLL Encapsulation Function given bad data!\n");
400 if(old->length < sizeof(struct sll_header) || new->length < sizeof(struct sll_header)){
401 dbgprintf(0, "Error: SLL Encapsulation Function given packet of wrong size!\n");
405 /*Copy SLL header over*/
406 memcpy(new->data, old->data, sizeof(struct sll_header));
409 slh=(struct sll_header*)(new->data);
411 /*Adjust pointers and lengths*/
412 nold.data= old->data + sizeof(struct sll_header);
413 nnew.data= new->data + sizeof(struct sll_header);
414 nold.length= old->length - sizeof(struct sll_header);
415 nnew.length= new->length- sizeof(struct sll_header);
427 /*Confirm that this is SLL*/
428 if(ntohs(slh->sll_pkttype) > 4){
429 dbgprintf(1, "Note: Packet is not SLL (Linux Cooked Capture)\n");
433 /*Select Next Protocol*/
434 switch(ntohs(slh->sll_protocol)){
436 if(!ipv4_encap(&nnew, &nold)){
441 if(!ipv6_encap(&nnew, &nold)){
446 dbgprintf(1, "Unknown Next Protocol at SLL\n");
452 new->length=nnew.length + sizeof(struct sll_header);
457 char *print_ipv6(char* buf, int len, u_char* id, int id_len)
459 struct sockaddr_in6 sa;
465 memcpy(&sa.sin6_addr, id, id_len);
466 sa.sin6_family=AF_INET6;
467 if(getnameinfo((struct sockaddr*)&sa, sizeof(struct sockaddr_in6),
468 buf, len, NULL,0,NI_NUMERICHOST)<0){
474 char *print_ipv4(char* buf, int len, u_char* id, int id_len)
476 struct sockaddr_in sa;
482 memcpy(&sa.sin_addr, id, id_len);
483 sa.sin_family=AF_INET;
484 if(getnameinfo((struct sockaddr*)&sa, sizeof(struct sockaddr_in),
485 buf, len, NULL,0,NI_NUMERICHOST)<0){