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