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)){
47 /*Linux Cooked Capture*/
48 if(!linux_cooked_encap(old)){
53 dbgprintf(0, "Unknown Link Layer\n");
59 /*Standard Ethernet Encapsulation*/
60 int ethernet_encap(const struct const_packet *old)
62 struct ether_header *ethh;
63 struct const_packet nold;
66 if(!old|| !old->data ||!old->h){
67 dbgprintf(0,"Error: Ethernet Encapsulation Function given bad data!\n");
70 if(old->length < sizeof(struct ether_header)){
71 dbgprintf(0, "Error: Ethernet Encapsulation Function given packet of wrong size!\n");
76 ethh=(struct ether_header*)(old->data);
78 /*Adjust pointers and lengths*/
79 nold.data= old->data+ sizeof(struct ether_header);
80 nold.length= old->length - sizeof(struct ether_header);
82 nold.private=old->private;
84 /*Select Next Protocol*/
85 switch(ntohs(ethh->ether_type)){
87 if(!ipv4_encap(&nold)){
92 if(!ipv6_encap(&nold)){
97 if(!ethernet_vlan_encap(&nold)){
102 dbgprintf(1, "Unknown Next Protocol at Ethernet\n");
109 /*Ethernet 802.1Q VLAN Encapsulation*/
110 int ethernet_vlan_encap(const struct const_packet *old)
112 struct vlan_tag *tag;
113 struct const_packet nold;
116 if(!old || !old->data || !old->h){
117 dbgprintf(0,"Error: Ethernet VLAN Encapsulation Function given bad data!\n");
120 if(old->length < sizeof(struct vlan_tag)){
121 dbgprintf(0, "Error: Ethernet VLAN Encapsulation Function given packet of wrong size!\n");
126 tag=(struct vlan_tag*)(old->data);
128 /*Adjust pointers and lengths*/
129 nold.data= old->data+ sizeof(struct vlan_tag);
130 nold.length= old->length - sizeof(struct vlan_tag);
132 nold.private=old->private;
134 /*Select Next Protocol*/
135 switch(ntohs(tag->vlan_tci)){
137 if(!ipv4_encap(&nold)){
142 if(!ipv6_encap(&nold)){
147 if(!ethernet_vlan_encap(&nold)){
152 dbgprintf(1, "Unknown Next Protocol at Ethernet VLAN tag\n");
159 /*IPv6 Encapsulation*/
160 int ipv6_encap(const struct const_packet *old)
163 struct const_packet nold;
166 if(!old->data || !old->h){
167 dbgprintf(0,"Error: IPv6 Encapsulation Function given bad data!\n");
170 if(old->length < sizeof(struct ip6_hdr)){
171 dbgprintf(0, "Error: IPv6 Encapsulation Function given packet of wrong size!\n");
176 iph=(struct ip6_hdr*)(old->data);
178 /*Adjust pointers and lengths*/
179 nold.data= old->data + sizeof(struct ip6_hdr);
180 nold.length= old->length - sizeof(struct ip6_hdr);
182 nold.private=old->private;
184 /*Confirm that this is IPv6*/
185 if((ntohl(iph->ip6_ctlun.ip6_un1.ip6_un1_flow) & (0xF0000000)) == (60000000)){
186 dbgprintf(1, "Note: Packet is not IPv6\n");
190 /*Select Next Protocol*/
191 switch(iph->ip6_ctlun.ip6_un1.ip6_un1_nxt){
194 if(!decap_packet(&nold)){
199 dbgprintf(1, "Unknown Next Protocol at IPv6\n");
206 /*IPv4 Encapsulation*/
207 int ipv4_encap(const struct const_packet *old)
210 struct const_packet nold;
213 if(!old || !old->data || !old->h){
214 dbgprintf(0,"Error: IPv4 Encapsulation Function given bad data!\n");
217 if(old->length < sizeof(struct iphdr)){
218 dbgprintf(0, "Error: IPv4 Encapsulation Function given packet of wrong size!\n");
223 iph=(struct iphdr*)(old->data);
225 /*Adjust pointers and lengths*/
226 nold.data= old->data +iph->ihl*4;
227 nold.length= old->length -iph->ihl*4;
229 nold.private=old->private;
231 /*Confirm that this is IPv4*/
233 dbgprintf(1, "Note: Packet is not IPv4\n");
237 /*Select Next Protocol*/
238 switch(iph->protocol){
241 if(!decap_packet(&nold)){
246 dbgprintf(1, "Unknown Next Protocol at IPv4\n");
253 int linux_cooked_encap(const struct const_packet *old)
255 struct sll_header *slh;
256 struct const_packet nold;
260 if(!old || !old->data ||!old->h){
261 dbgprintf(0,"Error: SLL Encapsulation Function given bad data!\n");
264 if(old->length < sizeof(struct sll_header)){
265 dbgprintf(0, "Error: SLL Encapsulation Function given packet of wrong size!\n");
270 slh=(struct sll_header*)(old->data);
272 /*Adjust pointers and lengths*/
273 nold.data= old->data + sizeof(struct sll_header);
274 nold.length= old->length - sizeof(struct sll_header);
276 nold.private=old->private;
278 /*Confirm that this is SLL*/
279 if(ntohs(slh->sll_pkttype) > 4){
280 dbgprintf(1, "Note: Packet is not SLL (Linux Cooked Capture)\n");
284 /*Select Next Protocol*/
285 switch(ntohs(slh->sll_protocol)){
287 if(!ipv4_encap(&nold)){
292 if(!ipv6_encap(&nold)){
297 dbgprintf(1, "Unknown Next Protocol at SLL\n");