1 //
2 // Copyright (C) 2008-2011 Institute of Telematics, Karlsruhe Institute of Technology (KIT)
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 //
18 
19 #include "Ipv6Packet.h"
20 #include "TcpPacket.h"
21 #include "UdpPacket.h"
22 
23 AnonPrimitive* Ipv6Packet::anonTrafficclass	= NULL;
24 AnonPrimitive* Ipv6Packet::anonFlowlabel	= NULL;
25 AnonPrimitive* Ipv6Packet::anonHoplimit		= NULL;
26 AnonPrimitive* Ipv6Packet::anonSourceaddr	= NULL;
27 AnonPrimitive* Ipv6Packet::anonDestaddr		= NULL;
28 
Ipv6Packet()29 Ipv6Packet::Ipv6Packet ()
30 {
31 	memset	 (&header, 0, sizeof (IPV6_HEADER));
32 	protocol = Packet::PROTO_IPV6;
33 }
34 
~Ipv6Packet()35 Ipv6Packet::~Ipv6Packet ()
36 {
37 }
38 
parsePacket()39 bool Ipv6Packet::parsePacket ()
40 {
41 	memcpy		(&header, buffer, sizeof (IPV6_HEADER));
42 	layersize	= sizeof (IPV6_HEADER);
43 
44 	header.version_trafficclass_flowlabel	= swap32 (header.version_trafficclass_flowlabel);
45 	header.payloadlen			= swap16 (header.payloadlen);
46 
47 	nextProtocol = IpPacket::getTransportProtocol (header.nextheader);
48 
49 	//
50 	// remove ethernet padding
51 	//
52 
53 	if (getSize () > sizeof (IPV6_HEADER) + header.payloadlen)
54 		this->size = sizeof (IPV6_HEADER) + header.payloadlen;
55 
56 	return true;
57 }
58 
assemblePacket()59 void Ipv6Packet::assemblePacket ()
60 {
61 	if (nextPacket != NULL) {
62 
63 		// TCP and UDP packets need the source
64 		// and dest IP addresses to calc their
65 		// checksums. So we pass it over here
66 		// where it is already transformed.
67 
68 		if (nextPacket->getProtocol() == Packet::PROTO_TCP) {
69 			((TcpPacket*)nextPacket)->setIpAddresses (getSourceaddr(), getDestaddr());
70 		} else if (nextPacket->getProtocol() == Packet::PROTO_UDP) {
71 			((UdpPacket*)nextPacket)->setIpAddresses (getSourceaddr(), getDestaddr());
72 		}
73 
74 		nextPacket->assemblePacket ();
75 	}
76 
77 	int thissize = sizeof (IPV6_HEADER);
78 	int nextsize = nextPacket != NULL ? nextPacket->getSize() : 0;
79 
80 	setSize (thissize + nextsize);
81 
82 	if (nextPacket != NULL)
83 		memcpy (buffer + thissize, nextPacket->getBuffer(), nextsize);
84 
85 	setPayloadlen (nextsize);
86 
87 	header.version_trafficclass_flowlabel	= swap32 (header.version_trafficclass_flowlabel);
88 	header.payloadlen			= swap16 (header.payloadlen);
89 
90 	memcpy (buffer, &header, sizeof (IPV6_HEADER));
91 
92 	header.version_trafficclass_flowlabel	= swap32 (header.version_trafficclass_flowlabel);
93 	header.payloadlen			= swap16 (header.payloadlen);
94 }
95 
toString()96 string Ipv6Packet::toString ()
97 {
98 	ostringstream out;
99 
100 	out << "IPv6 packet"			<< std::endl
101 		<< "\tVersion: \t"		<< (int)getVersion()		<< std::endl
102 		<< "\tTrafficclass: \t0x"	<< std::hex << std::setw(2)	<< std::setfill ('0') << (int) getTrafficclass() << std::endl << std::dec
103 		<< "\tFlowlabel: \t0x"		<< std::hex << std::setw(5)	<< std::setfill ('0') << getFlowlabel() << std::endl << std::dec
104 		<< "\tPayloadlen: \t"		<< getPayloadlen()		<< std::endl
105 		<< "\tNextheader: \t0x"		<< std::hex << std::setw(2)	<< std::setfill ('0') << (int) getNextheader()	<< std::endl << std::dec
106 		<< "\tHoplimit: \t"		<< (int)getHoplimit()		<< std::endl
107 		<< "\tSourceaddr: \t"		<< getSourceaddr().toString()	<< std::endl
108 		<< "\tDestaddr: \t"		<< getDestaddr().toString();
109 
110 	return out.str ();
111 }
112 
getMinProtocolSize()113 uint32_t Ipv6Packet::getMinProtocolSize ()
114 {
115 	return sizeof (IPV6_HEADER);
116 }
117 
getVersion()118 uint8_t Ipv6Packet::getVersion ()
119 {
120 	return IPV6_VERSION (header.version_trafficclass_flowlabel);
121 }
122 
getTrafficclass()123 uint8_t Ipv6Packet::getTrafficclass ()
124 {
125 	return IPV6_TRAFFICCLASS (header.version_trafficclass_flowlabel);
126 }
127 
getFlowlabel()128 uint32_t Ipv6Packet::getFlowlabel ()
129 {
130 	return IPV6_FLOWLABEL (header.version_trafficclass_flowlabel);
131 }
132 
getPayloadlen()133 uint16_t Ipv6Packet::getPayloadlen ()
134 {
135 	return header.payloadlen;
136 }
137 
getNextheader()138 uint8_t Ipv6Packet::getNextheader ()
139 {
140 	return header.nextheader;
141 }
142 
getHoplimit()143 uint8_t Ipv6Packet::getHoplimit ()
144 {
145 	return header.hoplimit;
146 }
147 
getSourceaddr()148 IPV6_ADDR Ipv6Packet::getSourceaddr ()
149 {
150 	return header.sourceaddr;
151 }
152 
getDestaddr()153 IPV6_ADDR Ipv6Packet::getDestaddr ()
154 {
155 	return header.destaddr;
156 }
157 
setVersion(uint8_t version)158 void Ipv6Packet::setVersion (uint8_t version)
159 {
160 	header.version_trafficclass_flowlabel = (((uint32_t)version & 0xF) << 28) | (header.version_trafficclass_flowlabel & 0x0FFFFFFF);
161 }
162 
setTrafficclass(uint8_t trafficclass)163 void Ipv6Packet::setTrafficclass (uint8_t trafficclass)
164 {
165 	header.version_trafficclass_flowlabel = ((uint32_t)trafficclass << 20) | (header.version_trafficclass_flowlabel & 0xF00FFFFF);
166 }
167 
setFlowlabel(uint32_t flowlabel)168 void Ipv6Packet::setFlowlabel (uint32_t flowlabel)
169 {
170 	header.version_trafficclass_flowlabel = (flowlabel & 0x000FFFFF) | (header.version_trafficclass_flowlabel & 0xFFF00000);
171 }
172 
setPayloadlen(uint16_t payloadlen)173 void Ipv6Packet::setPayloadlen (uint16_t payloadlen)
174 {
175 	header.payloadlen = payloadlen;
176 }
177 
setNextheader(uint8_t nextheader)178 void Ipv6Packet::setNextheader (uint8_t nextheader)
179 {
180 	header.nextheader = nextheader;
181 }
182 
setHoplimit(uint8_t hoplimit)183 void Ipv6Packet::setHoplimit (uint8_t hoplimit)
184 {
185 	header.hoplimit = hoplimit;
186 }
187 
setSourceaddr(IPV6_ADDR sourceaddr)188 void Ipv6Packet::setSourceaddr (IPV6_ADDR sourceaddr)
189 {
190 	header.sourceaddr = sourceaddr;
191 }
192 
setDestaddr(IPV6_ADDR destaddr)193 void Ipv6Packet::setDestaddr (IPV6_ADDR destaddr)
194 {
195 	header.destaddr = destaddr;
196 }
197