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)){
44 if(!ipv6_encap(new,old)){
50 /*Linux Cooked Capture*/
51 if(!linux_cooked_encap(new, old)){
56 dbgprintf(0, "Unknown Link Layer\n");
60 /*Adjust libpcap header*/
61 if(new->h->caplen >= new->h->len || new->h->caplen >= new->length){
62 new->h->caplen=new->length;
64 new->h->len=new->length;
69 /*Standard Ethernet Encapsulation*/
70 int ethernet_encap(struct packet *new, const struct const_packet *old)
72 struct ether_header *ethh;
73 struct const_packet nold;
77 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
78 dbgprintf(0,"Error: Ethernet Encapsulation Function given bad data!\n");
81 if(old->length < sizeof(struct ether_header) || new->length < sizeof(struct ether_header)){
82 dbgprintf(0, "Error: Ethernet Encapsulation Function given packet of wrong size!\n");
86 /*Copy Ethernet header over*/
87 memcpy(new->data, old->data, sizeof(struct ether_header));
90 ethh=(struct ether_header*)(new->data);
92 /*Adjust pointers and lengths*/
93 nold.data= old->data+ sizeof(struct ether_header);
94 nnew.data= new->data + sizeof(struct ether_header);
95 nold.length= old->length - sizeof(struct ether_header);
96 nnew.length= new->length - sizeof(struct ether_header);
108 /*Select Next Protocol*/
109 switch(ntohs(ethh->ether_type)){
111 if(!ipv4_encap(&nnew, &nold)){
116 if(!ipv6_encap(&nnew, &nold)){
121 if(!ethernet_vlan_encap(&nnew, &nold)){
126 dbgprintf(1, "Unknown Next Protocol at Ethernet\n");
132 new->length=nnew.length + sizeof(struct ether_header);
136 /*Ethernet 802.1Q VLAN Encapsulation*/
137 int ethernet_vlan_encap(struct packet *new, const struct const_packet *old)
139 struct vlan_tag *tag;
140 struct const_packet nold;
144 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
145 dbgprintf(0,"Error: Ethernet VLAN Encapsulation Function given bad data!\n");
148 if(old->length < sizeof(struct vlan_tag) || new->length < sizeof(struct vlan_tag)){
149 dbgprintf(0, "Error: Ethernet VLAN Encapsulation Function given packet of wrong size!\n");
153 /*Copy VLAN tag over*/
154 memcpy(new->data, old->data, sizeof(struct vlan_tag));
157 tag=(struct vlan_tag*)(new->data);
159 /*Adjust pointers and lengths*/
160 nold.data= old->data+ sizeof(struct vlan_tag);
161 nnew.data= new->data + sizeof(struct vlan_tag);
162 nold.length= old->length - sizeof(struct vlan_tag);
163 nnew.length= new->length - sizeof(struct vlan_tag);
175 /*Select Next Protocol*/
176 switch(ntohs(tag->vlan_tci)){
178 if(!ipv4_encap(&nnew, &nold)){
183 if(!ipv6_encap(&nnew, &nold)){
188 if(!ethernet_vlan_encap(&nnew, &nold)){
193 dbgprintf(1, "Unknown Next Protocol at Ethernet VLAN tag\n");
199 new->length=nnew.length + sizeof(struct vlan_tag);
203 /*IPv6 Encapsulation*/
204 int ipv6_encap(struct packet *new, const struct const_packet *old)
208 struct const_packet nold;
211 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
212 dbgprintf(0,"Error: IPv6 Encapsulation Function given bad data!\n");
215 if(old->length < sizeof(struct ip6_hdr) || new->length < sizeof(struct ip6_hdr)){
216 dbgprintf(0, "Error: IPv6 Encapsulation Function given packet of wrong size!\n");
220 /*Copy IPv6 header over*/
221 memcpy(new->data, old->data, sizeof(struct ip6_hdr));
224 iph=(struct ip6_hdr*)(new->data);
226 /*Adjust pointers and lengths*/
227 nold.data= old->data + sizeof(struct ip6_hdr);
228 nnew.data= new->data +sizeof(struct ip6_hdr);
229 nold.length= old->length - sizeof(struct ip6_hdr);
230 nnew.length= new->length - sizeof(struct ip6_hdr);
233 nnew.print_id=print_ipv6;
234 nold.print_id=print_ipv6;
238 /*Confirm that this is IPv6*/
239 if((ntohl(iph->ip6_ctlun.ip6_un1.ip6_un1_flow) & (0xF0000000)) == (60000000)){
240 dbgprintf(1, "Note: Packet is not IPv6\n");
244 /*Select Next Protocol*/
245 switch(iph->ip6_ctlun.ip6_un1.ip6_un1_nxt){
248 nnew.src_id=malloc(nnew.id_len);
249 nnew.dest_id=malloc(nnew.id_len);
250 nold.src_id=malloc(nold.id_len);
251 nold.dest_id=malloc(nold.id_len);
252 if(nnew.src_id==NULL||nnew.dest_id==NULL ||
253 nold.src_id==NULL||nold.dest_id==NULL){
254 dbgprintf(0,"Error: Couldn't allocate Memory\n");
257 memcpy(nnew.src_id,&iph->ip6_src,nnew.id_len);
258 memcpy(nnew.dest_id,&iph->ip6_dst,nnew.id_len);
259 memcpy(nold.src_id,&iph->ip6_src,nold.id_len);
260 memcpy(nold.dest_id,&iph->ip6_dst,nold.id_len);
261 if(!convert_packet(&nnew, &nold)){
266 dbgprintf(1, "Unknown Next Protocol at IPv6\n");
271 /*set ip to indicate that TCP is next protocol*/
272 iph->ip6_ctlun.ip6_un1.ip6_un1_nxt=6;
274 /*Determine if computed length is reasonable*/
275 if(nnew.length > 0xFFFF){
276 dbgprintf(1, "Error: Given TCP data length is too large for an IPv6 packet!\n");
280 /*Adjust IPv6 header to account for packet's total length*/
281 iph->ip6_ctlun.ip6_un1.ip6_un1_plen=htons(nnew.length);
284 new->length=nnew.length + sizeof(struct ip6_hdr);
294 /*IPv4 Encapsulation*/
295 int ipv4_encap(struct packet *new, const struct const_packet *old)
299 struct const_packet nold;
302 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
303 dbgprintf(0,"Error: IPv4 Encapsulation Function given bad data!\n");
306 if(old->length < sizeof(struct iphdr) || new->length < sizeof(struct iphdr)){
307 dbgprintf(0, "Error: IPv4 Encapsulation Function given packet of wrong size!\n");
311 /*Copy IPv4 header over*/
312 memcpy(new->data, old->data, sizeof(struct iphdr));
315 iph=(struct iphdr*)(new->data);
317 /*Adjust pointers and lengths*/
318 nold.data= old->data +iph->ihl*4;
319 nnew.data= new->data +iph->ihl*4;
320 nold.length= old->length -iph->ihl*4;
321 nnew.length= new->length -iph->ihl*4;
324 nnew.print_id=print_ipv4;
325 nold.print_id=print_ipv4;
329 /*Confirm that this is IPv4*/
331 dbgprintf(1, "Note: Packet is not IPv4\n");
335 /*Select Next Protocol*/
336 switch(iph->protocol){
339 nnew.src_id=malloc(nnew.id_len);
340 nnew.dest_id=malloc(nnew.id_len);
341 nold.src_id=malloc(nold.id_len);
342 nold.dest_id=malloc(nold.id_len);
343 if(nnew.src_id==NULL||nnew.dest_id==NULL||
344 nold.src_id==NULL||nold.dest_id==NULL){
345 dbgprintf(0,"Error: Couldn't allocate Memory\n");
348 memcpy(nnew.src_id,&iph->saddr,nnew.id_len);
349 memcpy(nnew.dest_id,&iph->daddr,nnew.id_len);
350 memcpy(nold.src_id,&iph->saddr,nold.id_len);
351 memcpy(nold.dest_id,&iph->daddr,nold.id_len);
352 if(!convert_packet(&nnew, &nold)){
357 dbgprintf(1, "Unknown Next Protocol at IPv4\n");
362 /*set ip to indicate that TCP is next protocol*/
367 new->length=nnew.length + iph->ihl*4;
369 /*Determine if computed length is reasonable*/
370 if(nnew.length > 0xFFFF){
371 dbgprintf(1, "Error: Given TCP header+data length is too large for an IPv4 packet!\n");
375 /*Adjust IPv4 header to account for packet's total length*/
376 iph->tot_len=htons(new->length);
378 /*Compute IPv4 Checksum*/
380 iph->check=ipv4_chksum(new->data,iph->ihl*4);
390 int linux_cooked_encap(struct packet *new, const struct const_packet *old)
392 struct sll_header *slh;
394 struct const_packet nold;
398 if(!new|| !old || !new->data || !old->data || !new->h || !old->h){
399 dbgprintf(0,"Error: SLL Encapsulation Function given bad data!\n");
402 if(old->length < sizeof(struct sll_header) || new->length < sizeof(struct sll_header)){
403 dbgprintf(0, "Error: SLL Encapsulation Function given packet of wrong size!\n");
407 /*Copy SLL header over*/
408 memcpy(new->data, old->data, sizeof(struct sll_header));
411 slh=(struct sll_header*)(new->data);
413 /*Adjust pointers and lengths*/
414 nold.data= old->data + sizeof(struct sll_header);
415 nnew.data= new->data + sizeof(struct sll_header);
416 nold.length= old->length - sizeof(struct sll_header);
417 nnew.length= new->length- sizeof(struct sll_header);
429 /*Confirm that this is SLL*/
430 if(ntohs(slh->sll_pkttype) > 4){
431 dbgprintf(1, "Note: Packet is not SLL (Linux Cooked Capture)\n");
435 /*Select Next Protocol*/
436 switch(ntohs(slh->sll_protocol)){
438 if(!ipv4_encap(&nnew, &nold)){
443 if(!ipv6_encap(&nnew, &nold)){
448 dbgprintf(1, "Unknown Next Protocol at SLL\n");
454 new->length=nnew.length + sizeof(struct sll_header);
459 char *print_ipv6(char* buf, int len, u_char* id, int id_len)
461 struct sockaddr_in6 sa;
467 memcpy(&sa.sin6_addr, id, id_len);
468 sa.sin6_family=AF_INET6;
469 if(getnameinfo((struct sockaddr*)&sa, sizeof(struct sockaddr_in6),
470 buf, len, NULL,0,NI_NUMERICHOST)<0){
476 char *print_ipv4(char* buf, int len, u_char* id, int id_len)
478 struct sockaddr_in sa;
484 memcpy(&sa.sin_addr, id, id_len);
485 sa.sin_family=AF_INET;
486 if(getnameinfo((struct sockaddr*)&sa, sizeof(struct sockaddr_in),
487 buf, len, NULL,0,NI_NUMERICHOST)<0){