diff options
Diffstat (limited to 'src/common/Network/Packet')
25 files changed, 2811 insertions, 0 deletions
diff --git a/src/common/Network/Packet/CPktCmn.cpp b/src/common/Network/Packet/CPktCmn.cpp new file mode 100755 index 00000000..9f682826 --- /dev/null +++ b/src/common/Network/Packet/CPktCmn.cpp @@ -0,0 +1,145 @@ +#include "CPktCmn.h" +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + + +#define TouchCacheLine(a) + +uint16_t pkt_InetChecksum(uint8_t* data , + uint16_t len, uint8_t* data2 , uint16_t len2){ + + TouchCacheLine(data2); + TouchCacheLine(data2+32); + TouchCacheLine(data2+64); + + int sum = 0; + while(len>1){ + TouchCacheLine(data+96); //three lines ahead ! + sum += PKT_NTOHS(*((uint16_t*)data)); + data += 2; + len -= 2; + } + + while(len2>1){ + TouchCacheLine(data2+96); //three lines ahead ! + sum += PKT_NTOHS(*((uint16_t*)data2)); + data2 += 2; + len2 -= 2; + } + + if(len2){ + sum += (PKT_NTOHS(*((uint16_t*)data2)) & 0xff00); + } + + while(sum >> 16){ + sum = (sum & 0xffff) + (sum >> 16); + } + + return PKT_NTOHS((uint16_t)(~sum)); +} + +uint16_t pkt_InetChecksum(uint8_t* data , uint16_t len){ + + int sum = 0; + while(len>1){ + TouchCacheLine(data+96); //three line ahead ! + sum += PKT_NTOHS(*((uint16_t*)data)); + data += 2; + len -= 2; + } + + if(len){ + sum += (PKT_NTOHS(*((uint16_t*)data)) & 0xff00); + } + + while(sum >> 16){ + sum = (sum & 0xffff) + (sum >> 16); + } + + return PKT_NTOHS((uint16_t)(~sum)); +} + +uint16_t pkt_UpdateInetChecksum(uint16_t csFieldFromPacket, uint16_t oldVal, uint16_t newVal){ + uint32_t newCS; + newCS = (uint16_t)(~PKT_NTOHS(csFieldFromPacket)); + newCS += (uint16_t)(~PKT_NTOHS(oldVal)); + newCS += (uint16_t)PKT_NTOHS(newVal); + while(newCS >> 16){ + newCS = (newCS & 0xffff) + (newCS >> 16); + } + return PKT_NTOHS((uint16_t)(~newCS)); +} + +uint16_t pkt_SubtractInetChecksum(uint16_t checksum, uint16_t csToSubtract){ + uint32_t newCS; + newCS = (uint16_t)(~PKT_NTOHS(checksum)); + + // since the cs is already in ~ format in the packet, there is no need + // to negate it for subtraction in 1's complement. + newCS += (uint16_t)PKT_NTOHS(csToSubtract); + + while(newCS >> 16){ + newCS = (newCS & 0xffff) + (newCS >> 16); + } + return PKT_NTOHS((uint16_t)(~newCS)); +} + +uint16_t pkt_AddInetChecksum(uint16_t checksum, uint16_t csToAdd){ + uint32_t newCS; + newCS = (uint16_t)(~PKT_NTOHS(checksum)); + + // since the cs is already in ~ format in the packet, there is a need + // to negate it for addition in 1's complement. + newCS += (uint16_t)PKT_NTOHS(~csToAdd); + + while(newCS >> 16){ + newCS = (newCS & 0xffff) + (newCS >> 16); + } + return PKT_NTOHS((uint16_t)(~newCS)); +} + + +extern "C" void pkt_ChecksumTest(){ + + uint16_t cs; + uint8_t data[5] = {0xcd,0x7a,0x55,0x55,0xa1}; + + cs = pkt_InetChecksum((uint8_t*)data,5); + printf("CS = 0x%04x: ",cs); + if(cs == 0x2F3C){ + printf("CS func with odd len OK.\n"); + }else{ + printf("ERROR: CS func produced wrong value with odd number of bytes.\n"); + } + + cs = pkt_InetChecksum((uint8_t*)data,4); + printf("CS = 0x%04x: ",cs); + if(cs == 0x2FDD){ + printf("CS func with even len OK.\n"); + }else{ + printf("ERROR: CS func produced wrong value with even number of bytes.\n"); + } + + cs = pkt_UpdateInetChecksum(cs,0x5555,0x8532); + printf("CS = 0x%04x: ",cs); + if(cs == 0x0000){ + printf("Update CS func OK.\n"); + }else{ + printf("ERROR: Update CS func produced wrong value.\n"); + } + +} diff --git a/src/common/Network/Packet/CPktCmn.h b/src/common/Network/Packet/CPktCmn.h new file mode 100755 index 00000000..a107c5a3 --- /dev/null +++ b/src/common/Network/Packet/CPktCmn.h @@ -0,0 +1,88 @@ +#ifndef PKT_CMN_H +#define PKT_CMN_H +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + + +#include <common/c_common.h> +#include <common/bitMan.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "pal_utl.h" + + +#define PKT_HTONL(x) (PAL_NTOHL(x)) +#define PKT_HTONS(x) (PAL_NTOHS(x)) + +#define PKT_NTOHL(x) (PAL_NTOHL(x)) +#define PKT_NTOHS(x) (PAL_NTOHS(x)) + + +// returns cs in NETWROK order +uint16_t pkt_InetChecksum(uint8_t* data , uint16_t len); + +// len MUST be an even number !!! +// len2 can be odd. +// returns cs in NETWROK order +uint16_t pkt_InetChecksum(uint8_t* data , uint16_t len, uint8_t* data2 , uint16_t len2); + +// this functiion updates an inet-checksum. +// It accepts the checksum field AS IS from the packet, the old byte's value +// and the new byte's value. +// the cs, old and new values must be entered in NETWORK byte order !!! +// the return value is also in NETWORK byte order !! +uint16_t pkt_UpdateInetChecksum(uint16_t csFieldFromPacket, uint16_t oldVal, uint16_t newVal); + +// checksum and csToSubtract are two uint16_t cs fields AS THEY APPEAR INSIDE A PACKET ! +uint16_t pkt_SubtractInetChecksum(uint16_t checksum, uint16_t csToSubtract); + +// checksum and csToAdd are two uint16_t cs fields AS THEY APPEAR INSIDE A PACKET ! +uint16_t pkt_AddInetChecksum(uint16_t checksum, uint16_t csToAdd); + + +struct Tunnels +{ + enum Type + { + // basic tunnels have a bit each. They can be bitwise OR ed. + // WARNING: We use this number as a Uint8 in some places - don't go over 1 byte !!! + + //Another warning: DO NOT change the values of these symbols, unless you have permission from everyone who + //uses them. These values are externally exposed through CmdlTunnel interfaces, and therefore JRT relies on these + //specific values. (Assi - Jan 2006) + Empty = 0x00, + UNTUNNELED_Marker = 0x01, + VLAN = 0x01, + MPLS = 0x02, + L2TP = 0x04, + IPinIP = 0x08, + GRE = 0x10, + Ethernet = 0x20,//This is not tunneled. It's an exception, until all these values are changed. + AnyIP = 0x40, + AnyTunneled = 0x7f, + TUNNELED_Marker = AnyTunneled,//Any sum of the values written above mustn't reach this value + Unrecognized = 0x80, + GTP = 0x81 + }; +}; + + + + +#endif + diff --git a/src/common/Network/Packet/EthernetHeader.cpp b/src/common/Network/Packet/EthernetHeader.cpp new file mode 100755 index 00000000..2c6891a1 --- /dev/null +++ b/src/common/Network/Packet/EthernetHeader.cpp @@ -0,0 +1,32 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +#include "EthernetHeader.h" + +void EthernetHeader::dump(FILE* fd) +{ + fprintf(fd,"EthernetHeader\n"); + fprintf(fd,"Destination : "); + myDestination.dump(fd);; + fprintf(fd,"Source : "); + mySource.dump(fd);; + fprintf(fd,"Protocol : 0x%04x \n",getNextProtocol()); +} + + + + diff --git a/src/common/Network/Packet/EthernetHeader.h b/src/common/Network/Packet/EthernetHeader.h new file mode 100755 index 00000000..87d1ed91 --- /dev/null +++ b/src/common/Network/Packet/EthernetHeader.h @@ -0,0 +1,98 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _ETHERNET_HEADER_H_ +#define _ETHERNET_HEADER_H_ + +#include "PacketHeaderBase.h" +#include "MacAddress.h" + + +/** + * This class encapsulates an ethernet header. + * It has fields that are equivalent to the ethernet header fields. + * The data is saved in network byte order, and therefore the class can be used to create a packet in a buffer + * and send it over the network. + */ +class EthernetHeader +{ +public: + + struct Protocol + { + enum Type + { + IP = 0x0800, + VLAN = 0x8100, + ARP = 0x0806, + IPv6 = 0x86DD, + MPLS_Unicast = 0x8847, + MPLS_Multicast = 0x8848, + PPP = 0x880b, + PPPoED = 0x8863, + PPPoES = 0x8864 + }; + }; + + +//////////////////////////////////////////////////////////////////////////////////////// +// Common Header Interface +//////////////////////////////////////////////////////////////////////////////////////// + +public: + //Empty constructor + EthernetHeader() : + myProtocol(0) + {} + //Construct an EthernetHeader object from a given buffer, ordered in Network byte order + inline EthernetHeader(uint8_t* packet); + + inline uint8_t* getPointer (){return (uint8_t*)this;} + static inline uint32_t getSize (){return (uint32_t)sizeof(EthernetHeader);} + + // Get dest MAC pointer + MacAddress *getDestMacP() { return &myDestination; } + + // Get source MAC pointer + MacAddress *getSrcMacP() { return &mySource; } + + //Returns the next protocol, in host byte order + inline uint16_t getNextProtocol (); + + //Set the next protocol value. The argument is receieved in host byte order. + inline void setNextProtocol (uint16_t); + + // Retrieve VLAN fields for tag and protocol information + inline uint16_t getVlanTag (); + inline uint16_t getVlanProtocol (); + + void dump (FILE* fd); + + +public: + MacAddress myDestination; + MacAddress mySource; +private: + uint16_t myProtocol; + uint16_t myVlanTag; + uint16_t myVlanProtocol; + +}; + +#include "EthernetHeader.inl" + +#endif //_ETHERNET_HEADER_H_ + diff --git a/src/common/Network/Packet/EthernetHeader.inl b/src/common/Network/Packet/EthernetHeader.inl new file mode 100755 index 00000000..0d6e32c9 --- /dev/null +++ b/src/common/Network/Packet/EthernetHeader.inl @@ -0,0 +1,39 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +inline EthernetHeader::EthernetHeader(uint8_t* packet) +{ + *this = *((EthernetHeader*)packet); +} +inline void EthernetHeader::setNextProtocol(uint16_t argProtocol) +{ + myProtocol = PKT_HTONS(argProtocol); +} + +inline uint16_t EthernetHeader::getNextProtocol() +{ + return( PKT_HTONS(myProtocol)); +} + +inline uint16_t EthernetHeader::getVlanProtocol() +{ + return( PKT_HTONS(myVlanProtocol)); +} + +inline uint16_t EthernetHeader::getVlanTag() +{ + return( PKT_HTONS(myVlanTag)); +} diff --git a/src/common/Network/Packet/IPHeader.cpp b/src/common/Network/Packet/IPHeader.cpp new file mode 100755 index 00000000..3b90a1aa --- /dev/null +++ b/src/common/Network/Packet/IPHeader.cpp @@ -0,0 +1,71 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "IPHeader.h" + + +char * IPHeader::Protocol::interpretIpProtocolName(uint8_t argType) +{ + switch (argType) + { + case TCP: + return (char *)"TCP"; + break; + case UDP: + return (char *)"UDP"; + break; + case IP: + return (char *)"IP"; + break; + case ICMP: + return (char *)"ICMP"; + break; + case ESP: + return (char *)"ESP"; + break; + case AH: + return (char *)"AH"; + break; + case IGMP: + return (char *)"IGMP"; + break; + default: + return (char *)NULL; + break; + } +} + +void IPHeader::dump(FILE *fd) +{ + fprintf(fd, "\nIPHeader"); + fprintf(fd, "\nSource 0x%.8lX, Destination 0x%.8lX, Protocol 0x%.1X", + getSourceIp(), getDestIp(), getProtocol()); + fprintf(fd, "\nTTL : %d, Id : 0x%.2X, Ver %d, Header Length %d, Total Length %d", + getTimeToLive(), getId(), getVersion(), getHeaderLength(), getTotalLength()); + if(isFragmented()) + { + fprintf(fd,"\nIsFirst %d, IsMiddle %d, IsLast %d, Offset %d", + isFirstFragment(), isMiddleFragment(), isLastFragment(), getFragmentOffset()); + } + else + { + fprintf(fd, "\nDont fragment %d", isDontFragment()); + } + fprintf(fd, "\n"); +} + + + diff --git a/src/common/Network/Packet/IPHeader.h b/src/common/Network/Packet/IPHeader.h new file mode 100755 index 00000000..5dfd03d8 --- /dev/null +++ b/src/common/Network/Packet/IPHeader.h @@ -0,0 +1,197 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _IP_HEADER_H_ +#define _IP_HEADER_H_ + +#include "PacketHeaderBase.h" + +#define IPV4_HDR_LEN 20 + +class IPHeader +{ + +public: + IPHeader() + { + myVer_HeaderLength = 0; //must initialize it cause when doing setLenght or setVersion we mask it (found in purify) + setDestIp(0xDEADBEEF); + setSourceIp(0xBEEFDEAD); + setProtocol(0xDD); + }; + + IPHeader (uint32_t argSource, + uint32_t argDestinaction, + uint8_t argProtocol) + { + myVer_HeaderLength = 0; //must initialize it cause when doing setLenght or setVersion we mask it + setDestIp(argDestinaction); + setSourceIp(argSource); + setProtocol(argProtocol); + }; + + + struct Protocol + { + enum Type + { + IP = 0x04 , + TCP = 0x06 , + UDP = 0x11 , + ICMP = 0x01 , + IGMP = 0x02, + ESP = 0x32, + AH = 0x33, + GRE = 0x2F, + IPV6_ICMP = 0x3A, + IPV6_NONXT = 0x3B, + }; + //get the IP-Protocol name by protocol number + static char * interpretIpProtocolName(uint8_t argType); + }; + + enum + { + DefaultSize = 20 + }; + + +public: + + inline uint8_t getVersion (); + inline void setVersion (uint8_t); + + /** + * Return the header length in bytes + * + * @return + */ + inline uint8_t getHeaderLength (); + + /** + * Receives the header length in bytes and sets it + * appropriately in the packet + */ + inline void setHeaderLength (uint8_t); + + inline uint8_t getTOS (); + inline void setTOS (uint8_t); + + inline uint16_t getTotalLength (); + inline void setTotalLength (uint16_t); + + inline uint16_t getId (); + inline void setId (uint16_t); + + inline uint16_t getFragmentOffset ();// return the result in bytes + inline bool isFirstFragment (); + inline bool isMiddleFragment (); + inline bool isFragmented (); + inline bool isMoreFragments (); + inline bool isDontFragment (); + inline bool isLastFragment (); + inline bool isNotFirstFragment (); + inline void setFragment (uint16_t argOffset, + bool argMoreFrag, + bool argDontFrag); + + inline uint8_t getTimeToLive (void); + inline void setTimeToLive (uint8_t); + + inline uint8_t getProtocol (void); + inline void setProtocol (uint8_t); + + inline uint32_t getSourceIp (); + inline void setSourceIp (uint32_t); + + inline uint32_t getDestIp (); + inline void setDestIp (uint32_t); + + bool isMulticast (); + bool isBroadcast (); + + inline uint16_t getChecksum (); + bool isChecksumOK (); + +public: + + inline void updateTos (uint8_t newTos); + inline void updateTotalLength (uint16_t newlen); + inline void updateIpSrc(uint32_t ipsrc); + inline void updateIpDst(uint32_t ipsrc); + + + + inline void updateCheckSum (); + inline void updateCheckSum2(uint8_t* data1, uint16_t len1, uint8_t* data2 , uint16_t len2); + + inline void swapSrcDest (); + +//////////////////////////////////////////////////////////////////////////////////////// +// Common Header Interface +//////////////////////////////////////////////////////////////////////////////////////// + +public: + inline uint8_t* getPointer (){return (uint8_t*)this;} + inline uint32_t getSize (){return getHeaderLength();} + + inline uint8_t getNextProtocol (); + + void dump (FILE* fd); + + inline uint8_t* getOption (){ return ((uint8_t*)&myOption[0]); } + inline uint8_t getOptionLen() { return ( getHeaderLength() - DefaultSize ); } + + +public: + uint8_t myVer_HeaderLength; + uint8_t myTos; + uint16_t myLength; + + uint16_t myId; + uint16_t myFrag; + + uint8_t myTTL; + uint8_t myProtocol; + uint16_t myChecksum; + + uint32_t mySource; + uint32_t myDestination; + uint32_t myOption[1]; +}; + + +class IPPseudoHeader +{ +public: + uint32_t m_source_ip; + uint32_t m_dest_ip; + uint8_t m_zero; + uint8_t m_protocol; + uint16_t m_length; +public: + inline uint8_t* getPointer(){return (uint8_t*)this;} + + inline uint32_t getSize(); + + inline uint16_t inetChecksum(); +}; + + +#include "IPHeader.inl" + +#endif + diff --git a/src/common/Network/Packet/IPHeader.inl b/src/common/Network/Packet/IPHeader.inl new file mode 100755 index 00000000..e7b87f06 --- /dev/null +++ b/src/common/Network/Packet/IPHeader.inl @@ -0,0 +1,290 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include <common/BigEndianBitManipulation.h> + + +inline void IPHeader::setVersion(uint8_t argVersion) +{ + setMaskBit8(myVer_HeaderLength, 0, 3, argVersion); +} + +inline uint8_t IPHeader::getVersion() +{ + return getMaskBit8(myVer_HeaderLength, 0, 3); +} + +inline uint8_t IPHeader::getHeaderLength() +{ + return (getMaskBit8(myVer_HeaderLength, 4, 7) << 2); +} + +inline void IPHeader::setHeaderLength(uint8_t argLength) +{ + setMaskBit8(myVer_HeaderLength, 4, 7, (argLength>>2)); +} + +inline uint8_t IPHeader::getNextProtocol() +{ + return myProtocol; +} + +//-------------------------------- + +inline void IPHeader::setTOS(uint8_t argTOS) +{ + myTos = argTOS; +} + +inline uint8_t IPHeader::getTOS() +{ + return myTos; +} + +//-------------------------------- +// length of ip packet +inline void IPHeader::setTotalLength(uint16_t argLength) +{ + myLength = PKT_NTOHS(argLength); +} + +inline uint16_t IPHeader::getTotalLength() +{ + return(PKT_NTOHS(myLength)); +} + +//-------------------------------- +inline uint16_t IPHeader::getId() +{ + return(PKT_NTOHS(myId)); +} + +inline void IPHeader::setId(uint16_t argID) +{ + myId = PKT_NTOHS(argID); +} + +//-------------------------------- + +uint16_t IPHeader::getFragmentOffset() +{ + uint16_t theFrag = (PKT_NTOHS(myFrag)); + return ((theFrag & 0x1FFF) << 3); + //return (getMaskBit16(theFrag, 3, 15) << 3);//The field is in 8 byte units +} + +bool IPHeader::isMoreFragments() +{ + uint16_t theFrag = (PKT_NTOHS(myFrag)); + if(theFrag & 0x2000) + //if(getMaskBit16(theFrag, 2, 2) == 1) + { + return true; + } + else + { + return false; + } +} + +bool IPHeader::isDontFragment() +{ + uint16_t theFrag = (PKT_NTOHS(myFrag)); + if(theFrag & 0x4000) + //if(getMaskBit16(theFrag, 1, 1) == 1) + { + return true; + } + else + { + return false; + } +} + +inline void IPHeader::setFragment (uint16_t argOffset , + bool argMoreFrag, + bool argDontFrag) +{ + uint16_t theFragmentWord = 0; + setMaskBit16(theFragmentWord, 3, 15, argOffset); + setMaskBit16(theFragmentWord, 1, 1, argDontFrag ? 1 : 0); + setMaskBit16(theFragmentWord, 2, 2, argMoreFrag ? 1 : 0); + myFrag = (PKT_NTOHS(theFragmentWord)); +} + +inline bool IPHeader::isFirstFragment() +{ + return((getFragmentOffset() == 0) && (isMoreFragments() == true)); +} + +inline bool IPHeader::isMiddleFragment() +{ + return((getFragmentOffset() != 0) && (isMoreFragments() == true)); +} + +inline bool IPHeader::isFragmented() +{ + return((getFragmentOffset() != 0) || (isMoreFragments() == true)); +} + +inline bool IPHeader::isLastFragment() +{ + return((getFragmentOffset() != 0) && (isMoreFragments() == false)); +} + +//return true if this is fragment but not first +inline bool IPHeader::isNotFirstFragment() +{ + return((isFragmented() == true) && (isFirstFragment() == false)); + +} + + +//-------------------------------- +inline uint8_t IPHeader::getTimeToLive() +{ + return(myTTL); +} +inline void IPHeader::setTimeToLive(uint8_t argTTL) +{ + myTTL = argTTL; +} + +//-------------------------------- +inline uint8_t IPHeader::getProtocol() +{ + return (myProtocol); +} + +inline void IPHeader::setProtocol(uint8_t argProtocol) +{ + myProtocol = argProtocol; +} +//-------------------------------- + + +inline uint32_t IPHeader::getSourceIp() +{ + return (PKT_NTOHL(mySource)); +} + +inline void IPHeader::setSourceIp(uint32_t argSourceAddress) +{ + mySource = PKT_NTOHL(argSourceAddress); +} + +//-------------------------------- +inline uint32_t IPHeader::getDestIp() +{ + return (PKT_NTOHL(myDestination)); +} + +inline void IPHeader::setDestIp(uint32_t argDestAddress) +{ + myDestination = PKT_NTOHL(argDestAddress); +} + +//-------------------------------- +inline bool IPHeader::isMulticast() +{ + return((getDestIp() & 0xf0) == 0xe0); +} + +inline bool IPHeader::isBroadcast() +{ + return(getDestIp() == 0xffffffff); +} +//-------------------------------- + +inline uint16_t IPHeader::getChecksum() +{ + return PKT_NTOHS(myChecksum); +} + +inline bool IPHeader::isChecksumOK() +{ + uint16_t theChecksum = pkt_InetChecksum(getPointer(),(uint16_t)getSize() ); + return(theChecksum == 0); +} + + +inline void IPHeader::updateTos(uint8_t newTos) +{ + uint16_t oldWord = *((uint16_t *)(getPointer())); + myTos = newTos; + uint16_t newWord = *((uint16_t *)(getPointer())); + myChecksum = pkt_UpdateInetChecksum(myChecksum,oldWord,newWord); +} + + + + +inline void IPHeader::updateIpDst(uint32_t ipsrc){ + uint32_t old = myDestination; + uint32_t _new_src = PKT_NTOHL(ipsrc); + + myChecksum = pkt_UpdateInetChecksum(myChecksum,(old&0xffff0000)>>16,((_new_src&0xffff0000)>>16)); + myChecksum = pkt_UpdateInetChecksum(myChecksum,(old&0xffff),(_new_src&0xffff)); + myDestination=_new_src; +} + +inline void IPHeader::updateIpSrc(uint32_t ipsrc){ + uint32_t old = mySource; + uint32_t _new_src = PKT_NTOHL(ipsrc); + + myChecksum = pkt_UpdateInetChecksum(myChecksum,(old&0xffff0000)>>16,((_new_src&0xffff0000)>>16)); + myChecksum = pkt_UpdateInetChecksum(myChecksum,(old&0xffff),(_new_src&0xffff)); + mySource=_new_src; +} + + +inline void IPHeader::updateTotalLength(uint16_t newlen) +{ + uint16_t oldLen = myLength; + myLength = PKT_NTOHS(newlen); + myChecksum = pkt_UpdateInetChecksum(myChecksum,oldLen,myLength); +} + +inline void IPHeader::updateCheckSum() +{ + myChecksum = 0; + myChecksum = pkt_InetChecksum(getPointer(), (uint16_t)getSize()); +} + +inline void IPHeader::updateCheckSum2(uint8_t* data1, uint16_t len1, uint8_t* data2 , uint16_t len2) +{ + myChecksum = 0; + myChecksum = pkt_InetChecksum(data1, len1, data2, len2); +} + +inline void IPHeader::swapSrcDest() +{ + uint32_t tmp = myDestination; + myDestination = mySource; + mySource = tmp; +} + +inline uint32_t IPPseudoHeader::getSize() +{ + return sizeof(IPPseudoHeader); +} +inline uint16_t IPPseudoHeader::inetChecksum() +{ + return(pkt_InetChecksum(getPointer(), (uint16_t)getSize())); +} + + + diff --git a/src/common/Network/Packet/IPv6Header.cpp b/src/common/Network/Packet/IPv6Header.cpp new file mode 100755 index 00000000..cf1f632a --- /dev/null +++ b/src/common/Network/Packet/IPv6Header.cpp @@ -0,0 +1,71 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "IPv6Header.h" + + +char * IPv6Header::Protocol::interpretIpProtocolName(uint8_t argType) +{ + switch (argType) + { + case TCP: + return (char *)"TCP"; + break; + case UDP: + return (char *)"UDP"; + break; + case IP: + return (char *)"IP"; + break; + case ICMP: + return (char *)"ICMP"; + break; + case ESP: + return (char *)"ESP"; + break; + case AH: + return (char *)"AH"; + break; + case IGMP: + return (char *)"IGMP"; + break; + default: + return (char *)NULL; + break; + } +} + +void IPv6Header::dump(FILE *fd) +{ + fprintf(fd, "\nIPv6Header"); + fprintf(fd, "\nSource 0x%.8lX, Destination 0x%.8lX, Protocol 0x%.1X", + getSourceIp(), getDestIp(), getProtocol()); + fprintf(fd, "\nTTL : %d, Id : 0x%.2X, Ver %d, Header Length %d, Total Length %d", + getTimeToLive(), getId(), getVersion(), getHeaderLength(), getTotalLength()); + if(isFragmented()) + { + fprintf(fd,"\nIsFirst %d, IsMiddle %d, IsLast %d, Offset %d", + isFirstFragment(), isMiddleFragment(), isLastFragment(), getFragmentOffset()); + } + else + { + fprintf(fd, "\nDont fragment %d", isDontFragment()); + } + fprintf(fd, "\n"); +} + + + diff --git a/src/common/Network/Packet/IPv6Header.h b/src/common/Network/Packet/IPv6Header.h new file mode 100755 index 00000000..8a246359 --- /dev/null +++ b/src/common/Network/Packet/IPv6Header.h @@ -0,0 +1,142 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _IPV6_HEADER_H_ +#define _IPV6_HEADER_H_ + +#include "PacketHeaderBase.h" + +#define IPV6_16b_ADDR_GROUPS 8 +#define IPV6_16b_ADDR_GROUPS_MSB 6 +#define IPV6_HDR_LEN 40 +static uint16_t default_ipv6[8] = { 0xDEAD, 0xBEEF, + 0xDEAD, 0xBEEF, + 0xDEAD, 0xBEEF, + 0xDEAD, 0xBEEF }; + + +class IPv6Header +{ + +public: + IPv6Header() + { + setDestIpv6(default_ipv6); + setSourceIpv6(default_ipv6); + setTrafficClass(0xDD); + }; + + IPv6Header (uint16_t *argSource, + uint16_t *argDestinaction, + uint8_t argTrafficClass) + { + setDestIpv6(argDestinaction); + setSourceIpv6(argSource); + setTrafficClass(argTrafficClass); + }; + + enum + { + DefaultSize = 40 + }; + + +public: + + inline uint8_t getVersion (); + inline void setVersion (uint8_t); + + inline uint8_t getHeaderLength (){return (IPV6_HDR_LEN);} + + inline uint16_t getTrafficClass (); + inline void setTrafficClass (uint16_t); + + inline uint32_t getFlowLabel (); + inline void setFlowLabel (uint32_t); + + inline uint16_t getPayloadLen (); + inline void setPayloadLen (uint16_t); + + inline uint8_t getNextHdr (); + inline void setNextHdr (uint8_t); + + inline uint8_t getHopLimit (); + inline void setHopLimit (uint8_t); + + inline void getSourceIpv6 (uint16_t *); + inline void setSourceIpv6 (uint16_t *); + + inline void getDestIpv6 (uint16_t *); + inline void setDestIpv6 (uint16_t *); + +public: + + inline void updateTrafficClass(uint8_t newclass); + inline void updatePayloadLength(uint16_t newlen); + inline void updateIpv6Src(uint16_t *ipsrc); + inline void updateIpv6Dst(uint16_t *ipdst); + inline void updateMSBIpv6Src(uint16_t *ipsrc); + inline void updateMSBIpv6Dst(uint16_t *ipdst); + inline void updateLSBIpv6Src(uint32_t ipsrc); + inline void updateLSBIpv6Dst(uint32_t ipdst); + + inline void swapSrcDest(); + +//////////////////////////////////////////////////////////////////////////////////////// +// Common Header Interface +//////////////////////////////////////////////////////////////////////////////////////// + +public: + inline uint8_t* getPointer (){return (uint8_t*)this;} + inline uint32_t getSize (){return getHeaderLength();} + + void dump (FILE* fd); + + +public: + uint32_t myVer_TrafficClass_FlowLabel; + + uint16_t myPayloadLen; + uint8_t myNextHdr; + uint8_t myHopLimit; + + uint16_t mySource[IPV6_16b_ADDR_GROUPS]; + uint16_t myDestination[IPV6_16b_ADDR_GROUPS]; + uint32_t myOption[1]; +}; + + +class IPv6PseudoHeader +{ +public: + uint32_t m_source_ip; + uint32_t m_dest_ip; + uint8_t m_zero; + uint8_t m_protocol; + uint16_t m_length; +public: + inline uint8_t* getPointer(){return (uint8_t*)this;} + + inline uint32_t getSize(); + + inline uint16_t inetChecksum(); +}; + + +#include "IPv6Header.inl" + +#endif + diff --git a/src/common/Network/Packet/IPv6Header.inl b/src/common/Network/Packet/IPv6Header.inl new file mode 100755 index 00000000..5098bc3e --- /dev/null +++ b/src/common/Network/Packet/IPv6Header.inl @@ -0,0 +1,182 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include <common/BigEndianBitManipulation.h> + +//-------------------------------- +inline uint8_t IPv6Header::getVersion() +{ + return getMaskBit32(PKT_NTOHL(myVer_TrafficClass_FlowLabel), 0, 3); +} + +inline void IPv6Header::setVersion(uint8_t argVersion) +{ + uint32_t myVer = PKT_HTONL(myVer_TrafficClass_FlowLabel); + setMaskBit32(myVer, 0, 3, argVersion); + myVer_TrafficClass_FlowLabel = PKT_NTOHL(myVer); +} + +//-------------------------------- +inline uint16_t IPv6Header::getTrafficClass() +{ + return getMaskBit32(PKT_NTOHL(myVer_TrafficClass_FlowLabel), 4, 11); +} + +inline void +IPv6Header::setTrafficClass(uint16_t argTrafficClass) +{ + uint32_t myTrafficClass = PKT_HTONL(myVer_TrafficClass_FlowLabel); + setMaskBit32(myTrafficClass, 4, 11, argTrafficClass); + myVer_TrafficClass_FlowLabel = PKT_NTOHL(myTrafficClass); +} + +//-------------------------------- +inline uint32_t IPv6Header::getFlowLabel() +{ + return getMaskBit32(PKT_NTOHL(myVer_TrafficClass_FlowLabel), 12, 31); +} + +inline void IPv6Header::setFlowLabel(uint32_t argFlowLabel) +{ + uint32_t myFlowLabel = PKT_HTONL(myVer_TrafficClass_FlowLabel); + setMaskBit32(myFlowLabel, 12, 31, argFlowLabel); + myVer_TrafficClass_FlowLabel = PKT_NTOHL(myFlowLabel); +} + +//-------------------------------- +inline uint16_t IPv6Header::getPayloadLen() +{ + return PKT_NTOHS(myPayloadLen); +} + +inline void IPv6Header::setPayloadLen(uint16_t argPayloadLen) +{ + myPayloadLen = PKT_HTONS(argPayloadLen); +} + +//-------------------------------- +inline uint8_t IPv6Header::getNextHdr() +{ + return myNextHdr; +} + +inline void IPv6Header::setNextHdr(uint8_t argNextHdr) +{ + myNextHdr = argNextHdr; +} + +//-------------------------------- +inline uint8_t IPv6Header::getHopLimit() +{ + return myHopLimit; +} + +inline void IPv6Header::setHopLimit(uint8_t argHopLimit) +{ + myHopLimit = argHopLimit; +} + +//-------------------------------- +inline void IPv6Header::getSourceIpv6(uint16_t *argSourceAddress) +{ + uint8_t i; + for (i=0; i<IPV6_16b_ADDR_GROUPS; i++) { + argSourceAddress[i] = PKT_NTOHS(mySource[i]); + } +} + +inline void IPv6Header::setSourceIpv6(uint16_t *argSourceAddress) +{ + uint8_t i; + for (i=0; i<IPV6_16b_ADDR_GROUPS; i++) { + mySource[i] = PKT_HTONS(argSourceAddress[i]); + } +} + +//-------------------------------- +inline void IPv6Header::getDestIpv6(uint16_t *argDestAddress) +{ + uint8_t i; + for (i=0; i<IPV6_16b_ADDR_GROUPS; i++) { + argDestAddress[i] = PKT_NTOHS(myDestination[i]); + } +} + +inline void IPv6Header::setDestIpv6(uint16_t *argDestAddress) +{ + uint8_t i; + for (i=0; i<IPV6_16b_ADDR_GROUPS; i++) { + myDestination[i] = PKT_HTONS(argDestAddress[i]); + } +} + +//-------------------------------- +inline void IPv6Header::updateIpv6Src(uint16_t *ipsrc) +{ + uint8_t i; + for (i=0; i<IPV6_16b_ADDR_GROUPS; i++) { + mySource[i] = PKT_HTONS(ipsrc[i]); + } +} + +inline void IPv6Header::updateIpv6Dst(uint16_t *ipdst) +{ + uint8_t i; + for (i=0; i<IPV6_16b_ADDR_GROUPS; i++) { + myDestination[i] = PKT_HTONS(ipdst[i]); + } +} + +//-------------------------------- +inline void IPv6Header::updateMSBIpv6Src(uint16_t *ipsrc) +{ + uint8_t i; + for (i=0; i<IPV6_16b_ADDR_GROUPS_MSB; i++) { + mySource[i] = PKT_HTONS(ipsrc[i]); + } +} + +inline void IPv6Header::updateMSBIpv6Dst(uint16_t *ipdst) +{ + uint8_t i; + for (i=0; i<IPV6_16b_ADDR_GROUPS_MSB; i++) { + myDestination[i] = PKT_HTONS(ipdst[i]); + } +} + +//-------------------------------- +inline void IPv6Header::updateLSBIpv6Src(uint32_t ipsrc) +{ + uint32_t *lsb = (uint32_t *)&mySource[6]; + *lsb = PKT_HTONL(ipsrc); +} + +inline void IPv6Header::updateLSBIpv6Dst(uint32_t ipdst) +{ + uint32_t *lsb = (uint32_t *)&myDestination[6]; + *lsb = PKT_HTONL(ipdst); +} + +//-------------------------------- +inline void IPv6Header::swapSrcDest() +{ + uint8_t i; + uint16_t tmp[IPV6_16b_ADDR_GROUPS]; + for (i=0; i<IPV6_16b_ADDR_GROUPS; i++) { + tmp[i] = myDestination[i]; + myDestination[i] = mySource[i]; + mySource[i] = tmp[i]; + } +} diff --git a/src/common/Network/Packet/MacAddress.cpp b/src/common/Network/Packet/MacAddress.cpp new file mode 100755 index 00000000..42331e50 --- /dev/null +++ b/src/common/Network/Packet/MacAddress.cpp @@ -0,0 +1,24 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "MacAddress.h" + + +void MacAddress::dump(FILE *fd) const +{ + +} + diff --git a/src/common/Network/Packet/MacAddress.h b/src/common/Network/Packet/MacAddress.h new file mode 100755 index 00000000..69272339 --- /dev/null +++ b/src/common/Network/Packet/MacAddress.h @@ -0,0 +1,130 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _MAC_ADDRESS_H_ +#define _MAC_ADDRESS_H_ + +#include "CPktCmn.h" + + +class MacAddress +{ +public: + + MacAddress() + { + set(0xca, 0xfe, 0xde, 0xad, 0xbe, 0xef); + }; + + MacAddress(uint8_t a0, + uint8_t a1, + uint8_t a2, + uint8_t a3, + uint8_t a4, + uint8_t a5) + { + set(a0, + a1, + a2, + a3, + a4, + a5); + }; + + MacAddress(uint8_t macAddr[6]) + { + set(macAddr[0], + macAddr[1], + macAddr[2], + macAddr[3], + macAddr[4], + macAddr[5] ); + }; + + void set(uint8_t a0, + uint8_t a1, + uint8_t a2, + uint8_t a3, + uint8_t a4, + uint8_t a5) + { + data[0]=a0; + data[1]=a1; + data[2]=a2; + data[3]=a3; + data[4]=a4; + data[5]=a5; + }; + + void set(uint8_t *argPtr) { + memcpy( data, argPtr, sizeof(data) ); + } + + void set(uint8_t *argPtr,uint8_t val) { + memcpy( data, argPtr, sizeof(data) ); + data[5]=val; + } + + + bool isInvalidAddress() const + { + static MacAddress allZeros(0,0,0,0,0,0); + static MacAddress cafeDeadBeef; + return (*this == allZeros || *this == cafeDeadBeef); + } + void setIdentifierAsBogusAddr(uint32_t identifier) + { + *(uint32_t*)data = identifier; + } + + uint32_t getIdentifierFromBogusAddr() + { + return *(uint32_t*)data; + } + + bool operator == (const MacAddress& rhs) const + { + for(int i=0; i<6; i++) + { + if(data[i] != rhs.data[i]) + return false; + } + + return true; + } + + uint8_t* GetBuffer() + { + return data; + } + + const uint8_t* GetConstBuffer() const + { + return data; + } + void dump(FILE *fd) const; + + void copyToArray(uint8_t *arrayToFill) const + { + ((uint32_t*)arrayToFill)[0] = ((uint32_t*)data)[0];//Copy first 32bit + ((uint16_t*)arrayToFill)[2] = ((uint16_t*)data)[2];//Copy last 16bit + } + +public: + uint8_t data[6]; +}; + +#endif //_MAC_ADDRESS_H_ diff --git a/src/common/Network/Packet/PacketHeaderBase.h b/src/common/Network/Packet/PacketHeaderBase.h new file mode 100755 index 00000000..14a570c8 --- /dev/null +++ b/src/common/Network/Packet/PacketHeaderBase.h @@ -0,0 +1,50 @@ +#ifndef _PACKET_HEADER_BASE_H_ +#define _PACKET_HEADER_BASE_H_ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +#include "CPktCmn.h" + +/** + * This class should be the base class for all packet headers in the system. + * Its target is to obligate all the headers to implement some common interface. + * e.g. Providing the pointer for the header, its size, dumping itself etc. + * Since that all header are being casted over some memory because + * of performance orientation, we are not using the pure virtual feature + * of C++. Thus this obligation is enforced at link time since there will be + * no implmentation in the base and if the interface will be used in some derived + * that didn't implement it, it will fail at link time. + */ +class PacketHeaderBase +{ +public: + uint8_t* getPointer (){return (uint8_t*)this;}; + uint32_t getSize (); + + uint16_t getNextProtocol (); + void setNextProtocol (uint16_t); + + void dump (FILE* fd); +}; + +enum +{ + TCPDefaultHeaderSize = 20,//TCP + UDPDefaultHeaderSize = 8 //UDP +}; + +#endif //_PACKET_HEADER_BASE_H_ diff --git a/src/common/Network/Packet/TCPHeader.cpp b/src/common/Network/Packet/TCPHeader.cpp new file mode 100755 index 00000000..bf28db2e --- /dev/null +++ b/src/common/Network/Packet/TCPHeader.cpp @@ -0,0 +1,35 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +#include "TcpHeader.h" + + + +void TCPHeader::dump(FILE *fd) +{ + fprintf(fd, "\nTCPHeader"); + fprintf(fd, "\nSourcePort 0x%.4X, DestPort 0x%.4X", + getSourcePort(), getDestPort()); + fprintf(fd, "\nSeqNum 0x%.8lX, AckNum 0x%.8lX, Window %d", + getSeqNumber(), getAckNumber(), getWindowSize()); + fprintf(fd, "\nHeader Length : %d, Checksum : 0x%.4X", + getHeaderLength(), getChecksum()); + fprintf(fd, "\nFlags : SYN - %d, FIN - %d, ACK - %d, URG - %d, RST - %d, PSH - %d", + getSynFlag(), getFinFlag(), getAckFlag(), getUrgentFlag(), getResetFlag(), getPushFlag()); + fprintf(fd, "\nUrgent Offset %d", getUrgentOffset()); + fprintf(fd, "\n"); +} diff --git a/src/common/Network/Packet/TCPOptions.cpp b/src/common/Network/Packet/TCPOptions.cpp new file mode 100755 index 00000000..d8312ccc --- /dev/null +++ b/src/common/Network/Packet/TCPOptions.cpp @@ -0,0 +1,176 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +#include "TCPOptions.h" +#include "IPHeader.h" + +bool TCPOptions::ourOneShotDump = false; +TCPOptions::Counters TCPOptions::ourCounters = {0,0,0}; + +TCPOptions::TCPOptions(uint8_t* argOptionsP, uint16_t argOptionsSize): +myOptionsP (argOptionsP), +myOptionsSize (argOptionsSize), +myCurrentOptionP((Option*)argOptionsP) +{ + ; +} + +bool TCPOptions::doesContain(TCPOptions::Kind::Val argKind) +{ + uint32_t optionTypeIdx = 0;// Used to verify that we're not in infinite loop + + // we'll run over the whole list of TLVs and check each relative to the time stamp + // option kind value. + do + { + Kind::Val theCurrentOptionKind; + uint8_t theOptionLength; + getCurrentOption(theCurrentOptionKind, theOptionLength); + optionTypeIdx++; + if( theCurrentOptionKind == argKind ) + { + return true; + } + } while( (nextOption() == true) && (optionTypeIdx < MaxOptionsInPacket)); + + if(optionTypeIdx >= MaxOptionsInPacket) + { + ourCounters.itsPossibleEndlessLoop++; + } + + // none of the TLV was of type TimeStamp + return false; +} + +//-------------------------------------------------------------------------------------------------- +// Set methods +//-------------------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------------------- +// Miscellaneous Operations +//-------------------------------------------------------------------------------------------------- + +void TCPOptions::dump(FILE* argOutputFile) +{ + fprintf(argOutputFile, "\nNot supported yet!\n"); +} + +void TCPOptions::get(TCPOptions::Counters& argCounters) +{ + argCounters.itsOptionsSizeMismatch = ourCounters.itsOptionsSizeMismatch; + argCounters.itsZeroLengthOptions = ourCounters.itsZeroLengthOptions; + argCounters.itsPossibleEndlessLoop = ourCounters.itsPossibleEndlessLoop; +} + +uint8_t* TCPOptions::getCurrentOption (Kind::Val& argKind, uint8_t& argLength) +{ + argKind = (Kind::Val)myCurrentOptionP->theKind; + argLength = getCurrentOptionLength(); + return(uint8_t*)myCurrentOptionP; +} + + +uint8_t TCPOptions::getCurrentOptionLength() +{ + if(myCurrentOptionP->theKind == Kind::NO_OP || + myCurrentOptionP->theKind == Kind::EOL) + { + return 1; + } + else + { + return myCurrentOptionP->theLength; + } +} + + +// This is a patch for temporary packet dump facility +// +#define MAX_BUFFER_SIZE (8 * 2048) +static char theDumpBuffer[MAX_BUFFER_SIZE] ={0}; + +bool TCPOptions::isLastOption () +{ + // Below is the total length of the options we've passed so far + uint32_t theCurrentOffset = (uint32_t)((uintptr_t)((char *)myCurrentOptionP - (char *)myOptionsP)); + + uint32_t theCurrentLength = getCurrentOptionLength(); + if( (theCurrentOffset + theCurrentLength) >= myOptionsSize ) + { + // debug check + if( (theCurrentOffset + theCurrentLength) > myOptionsSize ) + { + ourCounters.itsOptionsSizeMismatch++; + if(ourOneShotDump == false) + { + ourOneShotDump = true;//disable for next time + uint8_t* theIPPacket = (uint8_t*)((uintptr_t)(myOptionsP - 40)); + IPHeader* theIPHeader = (IPHeader*)theIPPacket; + uint16_t thePacketLength = theIPHeader->getTotalLength(); + + if(thePacketLength < (MAX_BUFFER_SIZE / 8)) + { + int numWritten = sprintf(theDumpBuffer, "\nDump Size %u\n", thePacketLength); + + for (uint32_t i = 0; i < thePacketLength; i++) + { + numWritten += sprintf(theDumpBuffer + numWritten,"%.2x ", theIPPacket[i]); + + if ((i % 16) == 15) + { + numWritten += sprintf(theDumpBuffer + numWritten,"\n"); + } + } + } + } + } + return true; + } + else + { + return false; + } +} + +//-------------------------------------------------------------------------------------------------- +// Set methods +//-------------------------------------------------------------------------------------------------- + +bool TCPOptions::nextOption () +{ + if( isLastOption() == true ) + { + return false; + } + else + { + uint32_t theCurrentOptionLength = getCurrentOptionLength(); + if(theCurrentOptionLength > 0) + { + uint8_t* theCurrentP = (uint8_t*)myCurrentOptionP; + theCurrentP += theCurrentOptionLength; + myCurrentOptionP = (Option*)theCurrentP; + return true; + } + else + { + ourCounters.itsZeroLengthOptions++; + return false; + } + } +} + diff --git a/src/common/Network/Packet/TCPOptions.h b/src/common/Network/Packet/TCPOptions.h new file mode 100755 index 00000000..2133db5a --- /dev/null +++ b/src/common/Network/Packet/TCPOptions.h @@ -0,0 +1,163 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#ifndef _TCP_OPTIONS_H_ +#define _TCP_OPTIONS_H_ + +#include "PacketHeaderBase.h" + + +class TCPOptions +{ + +public: + +//-------------------------------------------------------------------------------------------------- +// Typedef & Enum +//-------------------------------------------------------------------------------------------------- + + struct Kind + { + enum Val + { + EOL = 0, + NO_OP = 1, + MSS = 2, + WIN_SCL = 3, + SACK_PER = 4, + SACK = 5, + TIME_STAMP = 8 + }; + }; + + enum + { + TimeStampSize = 12 + }; + + enum + { + MaxOptionsInPacket = 64 + }; + + struct Option + { + uint8_t theKind; + uint8_t theLength; //Not always valid, depends on theKind + uint8_t theData[1];//variable. [1] only for compilation + }; + + struct Counters + { + uint32_t itsOptionsSizeMismatch; + uint32_t itsZeroLengthOptions; + uint32_t itsPossibleEndlessLoop; + }; + + +//-------------------------------------------------------------------------------------------------- +// Constructor & Destructor +//-------------------------------------------------------------------------------------------------- + + TCPOptions(uint8_t* argOptionsP, uint16_t argOptionsSize); + +//-------------------------------------------------------------------------------------------------- +// Utility methods +//-------------------------------------------------------------------------------------------------- + + /** + * This method allows the user of this class to query whether + * the options in hand contains a specific type of its + * interest. + * + * @return true if the specified option exist. + */ + bool doesContain(Kind::Val); + +//-------------------------------------------------------------------------------------------------- +// Get methods +//-------------------------------------------------------------------------------------------------- + + + /** + * Returns a pointer to the current option. + * With the kind and length of it. + * + * @param argKind + * @param argLength + * @return + */ + uint8_t* getCurrentOption (Kind::Val& argKind, uint8_t& argLength); + + /** + * This method gives the length of the current option. + * Can vary since there are two options that are exception to + * the usual TLV definition. + * + * @return + */ + uint8_t getCurrentOptionLength(); + + /** + * This is an internal method that verifies based on the current + * pointer, the total options length and the current options length, + * whether this is the last option. + * + * @return + */ + bool isLastOption (); + +//-------------------------------------------------------------------------------------------------- +// Set methods +//-------------------------------------------------------------------------------------------------- + + /** + * This method tells the object to advance one option ahead. + * i.e. to the next option. + * + * @return True if next option exist. + * False if we are at the last option. + */ + bool nextOption (); + + +//-------------------------------------------------------------------------------------------------- +// Miscellaneous Operations +//-------------------------------------------------------------------------------------------------- + + static void get (Counters&); + + void dump(FILE* argOutputFile); + + +private: + +//-------------------------------------------------------------------------------------------------- +// Data members +//-------------------------------------------------------------------------------------------------- + + uint8_t* myOptionsP; + uint16_t myOptionsSize; + + Option* myCurrentOptionP; + + static Counters ourCounters; + + static bool ourOneShotDump; +}; + + +#endif // _TCP_OPTIONS_H_ + diff --git a/src/common/Network/Packet/TcpHeader.h b/src/common/Network/Packet/TcpHeader.h new file mode 100755 index 00000000..e07df927 --- /dev/null +++ b/src/common/Network/Packet/TcpHeader.h @@ -0,0 +1,124 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#ifndef _TCP_HEADER_H_ +#define _TCP_HEADER_H_ + +#include "PacketHeaderBase.h" + + +class TCPHeader +{ + +public: + TCPHeader(){} + + TCPHeader(uint16_t argSourcePort, + uint16_t argDestinationPort, + uint8_t argFlags, + uint32_t argSeqNum, + uint32_t argAckNum); + + struct Flag + { + enum Type + { + FIN = 0x01, + SYN = 0x02, + RST = 0x04, + PSH = 0x08, + ACK = 0x10, + URG = 0x20 + }; + }; + + void setSourcePort (uint16_t); + uint16_t getSourcePort (); + + void setDestPort (uint16_t); + uint16_t getDestPort (); + + void setSeqNumber (uint32_t); + uint32_t getSeqNumber (); + + void setAckNumber (uint32_t); + uint32_t getAckNumber (); + + //this is factor 4 + void setHeaderLength (uint8_t); + uint8_t getHeaderLength (); + + void setFlag (uint8_t); + uint8_t getFlags (); + + void setFinFlag (bool); + bool getFinFlag (); + + void setSynFlag (bool); + bool getSynFlag (); + + void setResetFlag (bool); + bool getResetFlag (); + + void setPushFlag (bool); + bool getPushFlag (); + + void setAckFlag (bool); + bool getAckFlag (); + + void setUrgentFlag (bool); + bool getUrgentFlag (); + + void setWindowSize (uint16_t); + uint16_t getWindowSize (); + + void setChecksum (uint16_t); + uint16_t getChecksum (); + + void setUrgentOffset (uint16_t); + uint16_t getUrgentOffset (); + + uint32_t* getOptionPtr (); + + +//////////////////////////////////////////////////////////////////////////////////////// +// Common Header Interface +//////////////////////////////////////////////////////////////////////////////////////// + +public: + uint8_t* getPointer (){return (uint8_t*)this;} + uint32_t getSize (){return getHeaderLength();} + + uint16_t getNextProtocol (); + void setNextProtocol (uint16_t); + + void dump (FILE* fd); + +private: + uint16_t mySourcePort; + uint16_t myDestinationPort; + uint32_t mySeqNum; + uint32_t myAckNum; + uint8_t myHeaderLength; + uint8_t myFlags; + uint16_t myWindowSize; + uint16_t myChecksum; + uint16_t myUrgentPtr; + uint32_t myOption[1]; +}; + +#include "TcpHeader.inl" + +#endif //_TCP_HEADER_H_ diff --git a/src/common/Network/Packet/TcpHeader.inl b/src/common/Network/Packet/TcpHeader.inl new file mode 100755 index 00000000..52364d06 --- /dev/null +++ b/src/common/Network/Packet/TcpHeader.inl @@ -0,0 +1,220 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include <common/BigEndianBitManipulation.h> + +inline void TCPHeader::setSourcePort(uint16_t argSourcePort) +{ + mySourcePort = PKT_NTOHS(argSourcePort); +} + +inline uint16_t TCPHeader::getSourcePort() +{ + return(PKT_NTOHS(mySourcePort)); +} + +inline void TCPHeader::setDestPort(uint16_t argDestinationPort) +{ + myDestinationPort = PKT_NTOHS(argDestinationPort); +} + +inline uint16_t TCPHeader::getDestPort() +{ + return (PKT_NTOHS(myDestinationPort)); +} + +inline void TCPHeader::setSeqNumber(uint32_t argSeqNum) +{ + mySeqNum = PKT_NTOHL(argSeqNum); +} + +inline uint32_t TCPHeader::getSeqNumber() +{ + return (PKT_NTOHL(mySeqNum)); +} + +inline void TCPHeader::setAckNumber(uint32_t argAckNum) +{ + myAckNum = PKT_NTOHL(argAckNum); +} + +inline uint32_t TCPHeader::getAckNumber() +{ + return(PKT_NTOHL(myAckNum)); +} + +inline void TCPHeader::setHeaderLength(uint8_t argHeaderLength) +{ + setMaskBit8(myHeaderLength, 0, 3, argHeaderLength >> 2); +} + +inline uint8_t TCPHeader::getHeaderLength() +{ + return getMaskBit8(myHeaderLength, 0, 3) << 2; +} + +inline void TCPHeader::setFlag(uint8_t data) +{ + btSetMaskBit8(myFlags,5,0,data); +} + +inline uint8_t TCPHeader::getFlags() +{ + return(myFlags & 0x3f); +} + +inline void TCPHeader::setFinFlag(bool toSet) +{ + if(toSet) + { + myFlags |= Flag::FIN; + } + else + { + myFlags &= ~Flag::FIN; + } +} + +inline bool TCPHeader::getFinFlag() +{ + return(getFlags() & Flag::FIN)?true:false; +} + +inline void TCPHeader::setSynFlag(bool toSet) +{ + if(toSet) + { + myFlags|=Flag::SYN; + } + else + { + myFlags&=~Flag::SYN; + } +} + +inline bool TCPHeader::getSynFlag() +{ + return(getFlags() & Flag::SYN)?true:false; +} + +inline void TCPHeader::setResetFlag(bool toSet) +{ + if(toSet) + { + myFlags|=Flag::RST; + } + else + { + myFlags&=~Flag::RST; + } +} + +inline bool TCPHeader::getResetFlag() +{ + return(getFlags() & Flag::RST)?true:false; +} + +inline void TCPHeader::setPushFlag(bool toSet) +{ + if(toSet) + { + myFlags|=Flag::PSH; + } + else + { + myFlags&=~Flag::PSH; + } +} + +inline bool TCPHeader::getPushFlag() +{ + return(getFlags() & Flag::PSH)?true:false; +} + +inline void TCPHeader::setAckFlag(bool toSet) +{ + if(toSet) + { + myFlags|=Flag::ACK; + } + else + { + myFlags&=~Flag::ACK; + } +} + +inline bool TCPHeader::getAckFlag() +{ + return(getFlags() & Flag::ACK)?true:false; +} + +inline void TCPHeader::setUrgentFlag(bool toSet) +{ + if(toSet) + { + myFlags|=Flag::URG; + } + else + { + myFlags&=~Flag::URG; + } +} + +inline bool TCPHeader::getUrgentFlag() +{ + return(getFlags() & Flag::URG)?true:false; +} + +//--------------------------------------- +inline void TCPHeader::setWindowSize(uint16_t argWindowSize) +{ + myWindowSize = PKT_NTOHS(argWindowSize); +} +inline uint16_t TCPHeader::getWindowSize() +{ + return PKT_NTOHS(myWindowSize); +} + +inline void TCPHeader::setChecksum(uint16_t argChecksum) +{ + myChecksum = PKT_NTOHS(argChecksum); + +} + +inline uint16_t TCPHeader::getChecksum() +{ + return PKT_NTOHS(myChecksum); +} + +inline void TCPHeader::setUrgentOffset(uint16_t argUrgentOffset) +{ + myUrgentPtr = argUrgentOffset; +} + +inline uint16_t TCPHeader::getUrgentOffset() +{ + return PKT_NTOHS(myUrgentPtr); +} + +inline uint32_t * TCPHeader::getOptionPtr() +{ + return(myOption); +} + + + + + diff --git a/src/common/Network/Packet/UDPHeader.cpp b/src/common/Network/Packet/UDPHeader.cpp new file mode 100755 index 00000000..159e14fc --- /dev/null +++ b/src/common/Network/Packet/UDPHeader.cpp @@ -0,0 +1,28 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "UdpHeader.h" + + +void UDPHeader::dump(FILE *fd) +{ + fprintf(fd, "\nUDPHeader"); + fprintf(fd, "\nSourcePort 0x%.4X, DestPort 0x%.4X", + getSourcePort(), getDestPort()); + fprintf(fd, "\nLength : %d, Checksum : 0x%.4X", + getLength(), getChecksum()); + fprintf(fd, "\n"); +} diff --git a/src/common/Network/Packet/UdpHeader.h b/src/common/Network/Packet/UdpHeader.h new file mode 100755 index 00000000..43d08fe1 --- /dev/null +++ b/src/common/Network/Packet/UdpHeader.h @@ -0,0 +1,86 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _UDP_HEADER_H_ +#define _UDP_HEADER_H_ + +#include "PacketHeaderBase.h" +#include "IPHeader.h" + +class UDPHeader +{ + +public: + UDPHeader() + { + setDestPort(0xDEAD); + setSourcePort(0xBEEF); + setChecksum(0); + setLength(0); + } + + UDPHeader(uint16_t argSourcePort, + uint16_t argDestinationPort) + { + setDestPort(argDestinationPort); + setSourcePort(argSourcePort); + } + + + inline void setSourcePort(uint16_t data); + inline uint16_t getSourcePort(); + + inline void setDestPort(uint16_t data); + inline uint16_t getDestPort(); + + inline void setLength(uint16_t data); + inline uint16_t getLength(); + + inline void setChecksum(uint16_t data); + inline uint16_t getChecksum(); + + inline void updateCheckSum(IPHeader *ipHeader); + inline bool isCheckSumOk(IPHeader *ipHeader); + inline uint16_t calcCheckSum(IPHeader *ipHeader); + + inline void swapSrcDest(); + +//////////////////////////////////////////////////////////////////////////////////////// +// Common Header Interface +//////////////////////////////////////////////////////////////////////////////////////// + +public: + inline uint8_t* getPointer (){return (uint8_t*)this;} + inline uint32_t getSize (){return 8;} + + inline uint16_t getNextProtocol (){return getDestPort();}; + inline void setNextProtocol (uint16_t argNextProtcool){setDestPort(argNextProtcool);}; + + void dump (FILE* fd); + + +private: + uint16_t mySourcePort; + uint16_t myDestinationPort; + uint16_t myLength; + uint16_t myChecksum; +}; + + +#include "UdpHeader.inl" + +#endif + diff --git a/src/common/Network/Packet/UdpHeader.inl b/src/common/Network/Packet/UdpHeader.inl new file mode 100755 index 00000000..77afc193 --- /dev/null +++ b/src/common/Network/Packet/UdpHeader.inl @@ -0,0 +1,102 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +inline void UDPHeader::setSourcePort(uint16_t argSourcePort) +{ + mySourcePort = PKT_NTOHS(argSourcePort); +} + +uint16_t UDPHeader::getSourcePort() +{ + return PKT_NTOHS(mySourcePort); +} + +inline void UDPHeader::setDestPort(uint16_t argDestPort) +{ + myDestinationPort = PKT_NTOHS(argDestPort); +} + +uint16_t UDPHeader::getDestPort() +{ + return PKT_NTOHS(myDestinationPort); +} + +inline void UDPHeader::setLength(uint16_t argLength) +{ + myLength = PKT_NTOHS(argLength); +} + +uint16_t UDPHeader::getLength() +{ + return PKT_NTOHS(myLength); +} + +inline void UDPHeader::setChecksum(uint16_t argNewChecksum) +{ + myChecksum = PKT_NTOHS(argNewChecksum); +} + +uint16_t UDPHeader::getChecksum() +{ + return PKT_NTOHS(myChecksum); +} + +void UDPHeader::updateCheckSum(IPHeader *ipHeader) +{ + setChecksum(0);// must be here + + myChecksum =calcCheckSum(ipHeader); +} + +bool UDPHeader::isCheckSumOk(IPHeader *ipHeader) +{ + uint16_t theChecksum= PKT_NTOHS(calcCheckSum(ipHeader)); + + return(theChecksum == 0); +} + +uint16_t UDPHeader::calcCheckSum(IPHeader *ipHeader) +{ + IPPseudoHeader pseudo; + + uint16_t length= ipHeader->getTotalLength() - ipHeader->getHeaderLength(); + + pseudo.m_source_ip = PKT_NTOHL(ipHeader->getSourceIp()); + + pseudo.m_dest_ip = PKT_NTOHL(ipHeader->getDestIp()); + + pseudo.m_zero = 0; + + pseudo.m_protocol = ipHeader->getProtocol(); + + pseudo.m_length = PKT_NTOHS(length); + + uint16_t theChecksum = pkt_InetChecksum((uint8_t*)this,length); + + theChecksum = pkt_AddInetChecksum(theChecksum,pseudo.inetChecksum()); + + return(theChecksum); +} + +void UDPHeader::swapSrcDest() +{ + uint16_t tmp = myDestinationPort; + myDestinationPort = mySourcePort; + mySourcePort = tmp; +} + + + diff --git a/src/common/Network/Packet/VLANHeader.cpp b/src/common/Network/Packet/VLANHeader.cpp new file mode 100755 index 00000000..3bb48fdd --- /dev/null +++ b/src/common/Network/Packet/VLANHeader.cpp @@ -0,0 +1,100 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "VLANHeader.h" + + +/* + VLAN Header Fields + ------------------ + + 0 2 3 4 15 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + |Priority| CFI | Tag | + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + | Type | + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +*/ + + +void VLANHeader::dump (FILE* fd) +{ + fprintf(fd, "\nVLAN Header"); + fprintf(fd, "\nTag %d (0x%.2X), Pri %d, CFI - %d, Next protocol - %d (0x%.2X)", + getTagID(), getTagID(), getTagUserPriorty(), getTagCFI(), getNextProtocolHostOrder(), getNextProtocolHostOrder()); + fprintf(fd, "\n"); +} + +uint8_t VLANHeader::reconstructFromBuffer(uint8_t* destBuffer, uint8_t* srcBuffer) +{ + uint8_t type = srcBuffer[0]; + uint8_t size = srcBuffer[1]; + if((type != Tunnels::VLAN) || (size != sizeof(VLANHeader))) + { + // DBG_Error2(PACKET_DBG_TUNNEL_RECONSTRUCTION_ERROR,Tunnels::VLAN,size); + return 0; + } + memcpy(destBuffer,srcBuffer+2,sizeof(VLANHeader)); + return size; +} + +uint8_t VLANHeader::fillReconstructionBuffer(uint8_t* destBuffer, uint8_t* srcBuffer) +{ + destBuffer[0] = (uint8_t)Tunnels::VLAN; + destBuffer[1] = sizeof(VLANHeader); + memcpy(destBuffer+2,srcBuffer,sizeof(VLANHeader)); + return sizeof(VLANHeader)+2; +} + +uint8_t VLANHeader::fillReconstructionBuffer(uint8_t* destBuffer, VLANHeader& vHeader) +{ + destBuffer[0] = (uint8_t)Tunnels::VLAN; + destBuffer[1] = sizeof(VLANHeader); + vHeader.reconstructPkt(destBuffer+2); + return sizeof(VLANHeader)+2; +} + +#if 0 +Status VLANHeader::parseAsText(uint8_t* srcBuffer, TextCollectorInterface &tc) +{ + uint8_t type = srcBuffer[0]; + uint8_t size = srcBuffer[1]; + if((type != Tunnels::VLAN) //The buffer doesn't contain valid information + || (size < sizeof(VLANHeader))) //The buffer isn't big enough + { + return FAIL; + } + tc << "VLAN: "; + uint32_t offset = 0; + while (offset < size) + { + VLANHeader vlanHeader; + vlanHeader.setFromPkt(&srcBuffer[2+offset]); + + tc.printf("Tag %d (0x%.2X), Pri %d, CFI - %d, Next protocol - %d (0x%.2X)\n", + vlanHeader.getTagID(), vlanHeader.getTagID(), vlanHeader.getTagUserPriorty(), vlanHeader.getTagCFI(), vlanHeader.getNextProtocolHostOrder(), vlanHeader.getNextProtocolHostOrder()); + offset += sizeof(VLANHeader); + } + + return SUCCESS; +} +#endif + + + + + + diff --git a/src/common/Network/Packet/VLANHeader.h b/src/common/Network/Packet/VLANHeader.h new file mode 100755 index 00000000..cf6b2eff --- /dev/null +++ b/src/common/Network/Packet/VLANHeader.h @@ -0,0 +1,107 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _VLAN_HEADER_H_ +#define _VLAN_HEADER_H_ + +#include "PacketHeaderBase.h" +#include "EthernetHeader.h" + + +/* + VLAN Header Fields + ------------------ + + 0 2 3 4 15 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + |Priority| CFI | | + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + | Type | + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +*/ +/** + * This class encapsulates a VLAN header. + * It has fields that are equivalent to the VLAN header fields. + * The data is saved in network byte order, and therefore the class can be used to create a packet in a buffer + * and send it over the network. + */ +class VLANHeader +{ + + +//////////////////////////////////////////////////////////////////////////////////////// +// Field Manipulation +//////////////////////////////////////////////////////////////////////////////////////// +public: + + // Sets the complete tag field without sub fields manipulation + void setVlanTag (uint16_t data); + uint16_t getVlanTag (); + + void setTagUserPriorty (uint8_t data); + uint8_t getTagUserPriorty (); + + bool getTagCFI (); + void setTagCFI (bool); + + uint16_t getTagID (); + void setTagID (uint16_t); + + void incrementTagID(uint16_t inc_value); + + void setFromPkt (uint8_t* data); + + uint8_t reconstructPkt (uint8_t* destBuff); + + +//////////////////////////////////////////////////////////////////////////////////////// +// Common Interface +//////////////////////////////////////////////////////////////////////////////////////// + +public: + uint8_t* getPointer (){return (uint8_t*)this;} + uint32_t getSize (){return (uint32_t)sizeof(VLANHeader);} + + uint16_t getNextProtocolNetOrder (); + uint16_t getNextProtocolHostOrder (); + void setNextProtocolFromNetOrder(uint16_t); + void setNextProtocolFromHostOrder(uint16_t); + + void dump (FILE* fd); + + static uint16_t bytesToSkip(uint8_t* base) + { + return sizeof(VLANHeader); + } + + static uint8_t reconstructFromBuffer(uint8_t* destBuffer, uint8_t* srcBuffer); + + static uint8_t fillReconstructionBuffer(uint8_t* destBuffer, uint8_t* srcBuffer); + + static uint8_t fillReconstructionBuffer(uint8_t* destBuffer, VLANHeader& vHeader); + + + static uint32_t getMaxVlanTag() { return (1<<12) - 1 ; } + +public: + uint16_t myTag; + uint16_t myNextProtocol; +}; + +#include "VLANHeader.inl" + +#endif //_VLAN_HEADER_H_ + diff --git a/src/common/Network/Packet/VLANHeader.inl b/src/common/Network/Packet/VLANHeader.inl new file mode 100755 index 00000000..a1c584c1 --- /dev/null +++ b/src/common/Network/Packet/VLANHeader.inl @@ -0,0 +1,111 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include <common/BigEndianBitManipulation.h> + +inline void VLANHeader::setVlanTag(uint16_t data) +{ + myTag = PKT_HTONS(data); +} + +inline uint16_t VLANHeader::getVlanTag() +{ + return(PKT_HTONS(myTag)); +} + +inline void VLANHeader::setTagUserPriorty(uint8_t argUserPriority) +{ + uint16_t tempTag = myTag; + setMaskBit16(tempTag, 0, 2, argUserPriority); + myTag = tempTag; +} + +inline uint8_t VLANHeader::getTagUserPriorty() +{ + return (uint8_t)(getMaskBit16(myTag, 0, 2)); +} + + +inline void VLANHeader::setTagCFI(bool isSet) +{ + uint16_t tempTag = myTag; + setMaskBit16(tempTag, 3, 3, isSet? 1 : 0); + myTag = tempTag; +} + +inline bool VLANHeader::getTagCFI() +{ + return (getMaskBit16(myTag, 3, 3) == 1); +} + +// This returns host order +inline uint16_t VLANHeader::getTagID(void) +{ + return getMaskBit16(myTag, 4, 15); +} + +inline void VLANHeader::setTagID(uint16_t argNewTag) +{ + uint16_t tempTag = myTag; + setMaskBit16(tempTag, 4, 15, argNewTag); + myTag = tempTag; +} + +inline void VLANHeader::incrementTagID(uint16_t inc_value) +{ + uint16_t tempTag_Host = myTag; + uint16_t curTagID_Host = getTagID(); + uint16_t newTagId_Host = (0xfff & (curTagID_Host + (0xfff & inc_value))); // addition with 12 LSBits + setMaskBit16(tempTag_Host, 4, 15, newTagId_Host); + myTag = tempTag_Host; +} + +inline uint16_t VLANHeader::getNextProtocolNetOrder() +{ + return myNextProtocol; +} + +inline uint16_t VLANHeader::getNextProtocolHostOrder() +{ + return (PKT_HTONS(myNextProtocol)); +} + +inline void VLANHeader::setNextProtocolFromHostOrder(uint16_t argNextProtocol) +{ + myNextProtocol = PKT_HTONS(argNextProtocol); +} + +inline void VLANHeader::setNextProtocolFromNetOrder(uint16_t argNextProtocol) +{ + myNextProtocol = argNextProtocol; +} + +inline void VLANHeader::setFromPkt (uint8_t* data) +{ + // set the tag from the data + setVlanTag(*(uint16_t*)data); + setNextProtocolFromNetOrder(*((uint16_t*)(data + 2))); // next protocol is after the vlan tag +} + +inline uint8_t VLANHeader::reconstructPkt (uint8_t* destBuff) +{ + *(uint16_t*)destBuff = getVlanTag(); + *(uint16_t*)(destBuff+2) = getNextProtocolNetOrder(); + return sizeof(VLANHeader); +} + + + |