]> sjero.net Git - dccp2tcp/commitdiff
Add Support for Ethernet VLAN tags
authorSamuel Jero <sj323707@ohio.edu>
Thu, 14 Feb 2013 03:33:18 +0000 (22:33 -0500)
committerSamuel Jero <sj323707@ohio.edu>
Thu, 14 Feb 2013 03:33:18 +0000 (22:33 -0500)
encap.c
encap.h

diff --git a/encap.c b/encap.c
index 6f79307afd811ecf235c499385065e81edefb2c8..d2c06b1b44b98ce80131ef7fb2f87b7545141ac4 100644 (file)
--- a/encap.c
+++ b/encap.c
@@ -24,6 +24,7 @@ Date: 11/2012
 #include "encap.h"
 #include "checksums.h"
 #include <pcap/sll.h>
+#include <pcap/vlan.h>
 #include <netinet/ip6.h>
 #include <netdb.h>
 
@@ -114,6 +115,11 @@ int ethernet_encap(struct packet *new, const struct const_packet *old)
                                                        return 0;
                                        }
                                        break;
+                       case ETHERTYPE_VLAN:
+                                       if(!ethernet_vlan_encap(&nnew, &nold)){
+                                                       return 0;
+                                       }
+                                       break;
                        default:
                                        dbgprintf(1, "Unknown Next Protocol at Ethernet\n");
                                        return 0;
@@ -125,6 +131,73 @@ int ethernet_encap(struct packet *new, const struct const_packet *old)
 return 1;
 }
 
+/*Ethernet 802.1Q VLAN Encapsulation*/
+int ethernet_vlan_encap(struct packet *new, const struct const_packet *old)
+{
+               struct vlan_tag         *tag;
+               struct const_packet nold;
+               struct packet           nnew;
+
+               /*Safety checks*/
+               if(!new || !old || !new->data || !old->data || !new->h || !old->h){
+                       dbgprintf(0,"Error: Ethernet VLAN Encapsulation Function given bad data!\n");
+                       return 0;
+               }
+               if(old->length < sizeof(struct vlan_tag) || new->length < sizeof(struct vlan_tag)){
+                       dbgprintf(0, "Error: Ethernet VLAN Encapsulation Function given packet of wrong size!\n");
+                       return 0;
+               }
+
+               /*Copy VLAN tag over*/
+               memcpy(new->data, old->data, sizeof(struct vlan_tag));
+
+               /*Cast Pointer*/
+               tag=(struct vlan_tag*)(new->data);
+
+               /*Adjust pointers and lengths*/
+               nold.data= old->data+ sizeof(struct vlan_tag);
+               nnew.data= new->data + sizeof(struct vlan_tag);
+               nold.length= old->length - sizeof(struct vlan_tag);
+               nnew.length= new->length - sizeof(struct vlan_tag);
+               nnew.h=new->h;
+               nold.h=old->h;
+               nnew.print_id=NULL;
+               nnew.dest_id=NULL;
+               nnew.src_id=NULL;
+               nnew.id_len=0;
+               nold.print_id=NULL;
+               nold.dest_id=NULL;
+               nold.src_id=NULL;
+               nold.id_len=0;
+
+               /*Select Next Protocol*/
+               switch(ntohs(tag->vlan_tci)){
+                       case ETHERTYPE_IP:
+                                       if(!ipv4_encap(&nnew, &nold)){
+                                                       return 0;
+                                       }
+                                       break;
+                       case ETHERTYPE_IPV6:
+                                       if(!ipv6_encap(&nnew, &nold)){
+                                                       return 0;
+                                       }
+                                       break;
+                       case ETHERTYPE_VLAN:
+                                       if(!ethernet_vlan_encap(&nnew, &nold)){
+                                                       return 0;
+                                       }
+                                       break;
+                       default:
+                                       dbgprintf(1, "Unknown Next Protocol at Ethernet VLAN tag\n");
+                                       return 0;
+                                       break;
+               }
+
+               /*Adjust length*/
+               new->length=nnew.length + sizeof(struct vlan_tag);
+return 1;
+}
+
 /*IPv6 Encapsulation*/
 int ipv6_encap(struct packet *new, const struct const_packet *old)
 {
diff --git a/encap.h b/encap.h
index 890335abcbe9d1cd9fa606c1d16c1b82b344df5b..010cac2531da54cddf152568b34d82fb69d59cef 100644 (file)
--- a/encap.h
+++ b/encap.h
@@ -76,6 +76,7 @@ int convert_packet(struct packet *new, const struct const_packet *old);
 
 /*Standard Encapsulation Functions*/
 int ethernet_encap(struct packet *new, const struct const_packet *old);
+int ethernet_vlan_encap(struct packet *new, const struct const_packet *old);
 int linux_cooked_encap(struct packet *new, const struct const_packet *old);
 int ipv4_encap(struct packet *new, const struct const_packet *old);
 int ipv6_encap(struct packet *new, const struct const_packet *old);