1 /******************************************************************************
2 Utility to create a pcap file of a 6in4 stream present in an origin pcap file
4 Copyright (C) 2013 Samuel Jero <sj323707@ohio.edu>
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 Author: Samuel Jero <sj323707@ohio.edu>
21 ******************************************************************************/
22 #include "strip6in4.h"
25 #include <pcap/vlan.h>
26 #include <netinet/ip6.h>
27 #include <netinet/if_ether.h>
28 #include <netinet/ip.h>
30 /*Encapsulation start point and link layer selector*/
31 int do_encap(int link, const struct const_packet *old)
36 if(!ethernet_encap(old)){
49 /*Linux Cooked Capture*/
50 if(!linux_cooked_encap(old)){
55 dbgprintf(0, "Unknown Link Layer\n");
61 /*Standard Ethernet Encapsulation*/
62 int ethernet_encap(const struct const_packet *old)
64 struct ether_header *ethh;
65 struct const_packet nold;
68 if(!old|| !old->data ||!old->h){
69 dbgprintf(0,"Error: Ethernet Encapsulation Function given bad data!\n");
72 if(old->length < sizeof(struct ether_header)){
73 dbgprintf(0, "Error: Ethernet Encapsulation Function given packet of wrong size!\n");
78 ethh=(struct ether_header*)(old->data);
80 /*Adjust pointers and lengths*/
81 nold.data= old->data+ sizeof(struct ether_header);
82 nold.length= old->length - sizeof(struct ether_header);
84 nold.private=old->private;
86 /*Select Next Protocol*/
87 switch(ntohs(ethh->ether_type)){
89 if(!ipv4_encap(&nold)){
94 if(!ipv6_encap(&nold)){
99 if(!ethernet_vlan_encap(&nold)){
104 dbgprintf(1, "Unknown Next Protocol at Ethernet\n");
111 /*Ethernet 802.1Q VLAN Encapsulation*/
112 int ethernet_vlan_encap(const struct const_packet *old)
114 struct vlan_tag *tag;
115 struct const_packet nold;
118 if(!old || !old->data || !old->h){
119 dbgprintf(0,"Error: Ethernet VLAN Encapsulation Function given bad data!\n");
122 if(old->length < sizeof(struct vlan_tag)){
123 dbgprintf(0, "Error: Ethernet VLAN Encapsulation Function given packet of wrong size!\n");
128 tag=(struct vlan_tag*)(old->data);
130 /*Adjust pointers and lengths*/
131 nold.data= old->data+ sizeof(struct vlan_tag);
132 nold.length= old->length - sizeof(struct vlan_tag);
134 nold.private=old->private;
136 /*Select Next Protocol*/
137 switch(ntohs(tag->vlan_tci)){
139 if(!ipv4_encap(&nold)){
144 if(!ipv6_encap(&nold)){
149 if(!ethernet_vlan_encap(&nold)){
154 dbgprintf(1, "Unknown Next Protocol at Ethernet VLAN tag\n");
161 /*IPv6 Encapsulation*/
162 int ipv6_encap(const struct const_packet *old)
165 struct const_packet nold;
168 if(!old->data || !old->h){
169 dbgprintf(0,"Error: IPv6 Encapsulation Function given bad data!\n");
172 if(old->length < sizeof(struct ip6_hdr)){
173 dbgprintf(0, "Error: IPv6 Encapsulation Function given packet of wrong size!\n");
178 iph=(struct ip6_hdr*)(old->data);
180 /*Adjust pointers and lengths*/
181 nold.data= old->data + sizeof(struct ip6_hdr);
182 nold.length= old->length - sizeof(struct ip6_hdr);
184 nold.private=old->private;
186 /*Confirm that this is IPv6*/
187 if((ntohl(iph->ip6_ctlun.ip6_un1.ip6_un1_flow) & (0xF0000000)) == (60000000)){
188 dbgprintf(1, "Note: Packet is not IPv6\n");
192 /*Select Next Protocol*/
193 switch(iph->ip6_ctlun.ip6_un1.ip6_un1_nxt){
196 if(!decap_packet(&nold)){
201 dbgprintf(1, "Unknown Next Protocol at IPv6\n");
208 /*IPv4 Encapsulation*/
209 int ipv4_encap(const struct const_packet *old)
212 struct const_packet nold;
215 if(!old || !old->data || !old->h){
216 dbgprintf(0,"Error: IPv4 Encapsulation Function given bad data!\n");
219 if(old->length < sizeof(struct iphdr)){
220 dbgprintf(0, "Error: IPv4 Encapsulation Function given packet of wrong size!\n");
225 iph=(struct iphdr*)(old->data);
227 /*Adjust pointers and lengths*/
228 nold.data= old->data +iph->ihl*4;
229 nold.length= old->length -iph->ihl*4;
231 nold.private=old->private;
233 /*Confirm that this is IPv4*/
235 dbgprintf(1, "Note: Packet is not IPv4\n");
239 /*Select Next Protocol*/
240 switch(iph->protocol){
243 if(!decap_packet(&nold)){
248 dbgprintf(1, "Unknown Next Protocol at IPv4\n");
255 int linux_cooked_encap(const struct const_packet *old)
257 struct sll_header *slh;
258 struct const_packet nold;
262 if(!old || !old->data ||!old->h){
263 dbgprintf(0,"Error: SLL Encapsulation Function given bad data!\n");
266 if(old->length < sizeof(struct sll_header)){
267 dbgprintf(0, "Error: SLL Encapsulation Function given packet of wrong size!\n");
272 slh=(struct sll_header*)(old->data);
274 /*Adjust pointers and lengths*/
275 nold.data= old->data + sizeof(struct sll_header);
276 nold.length= old->length - sizeof(struct sll_header);
278 nold.private=old->private;
280 /*Confirm that this is SLL*/
281 if(ntohs(slh->sll_pkttype) > 4){
282 dbgprintf(1, "Note: Packet is not SLL (Linux Cooked Capture)\n");
286 /*Select Next Protocol*/
287 switch(ntohs(slh->sll_protocol)){
289 if(!ipv4_encap(&nold)){
294 if(!ipv6_encap(&nold)){
299 dbgprintf(1, "Unknown Next Protocol at SLL\n");