1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/ip4_hdr.h Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,580 @@
1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// ip4_hdr.h - IPv4 header structure
1.18 +// Defines the basic classes for accessing the header
1.19 +// structures within IPv4 packets.
1.20 +//
1.21 +
1.22 +
1.23 +
1.24 +/**
1.25 + @file ip4_hdr.h
1.26 + @ingroup ip_packet_formats
1.27 + @publishedAll
1.28 + @released
1.29 +*/
1.30 +
1.31 +#ifndef __IP4_HDR_H__
1.32 +#define __IP4_HDR_H__
1.33 +
1.34 +#include "in_hdr.h"
1.35 +#include "es_sock.h" // for ByteOrder only!!!
1.36 +
1.37 +/**
1.38 +* @addtogroup ip_packet_formats
1.39 +* @{
1.40 +*/
1.41 +
1.42 +/**
1.43 +* @name IP v4 constants
1.44 +* @since v7.0
1.45 +* @publishedAll
1.46 +* @released
1.47 +*/
1.48 +///@{
1.49 +const TUint8 KInet4IP_DF = 0x40; ///< Don't Fragment flag
1.50 +const TUint8 KInet4IP_MF = 0x20; ///< More Fragments flag
1.51 +const TInt KInetMinMtu = 68; ///< Minimum MTU as defined in RFC-791
1.52 +///@}
1.53 +
1.54 +class TInet6HeaderIP4
1.55 +/**
1.56 +* Encapsulates an IPv4 IP header.
1.57 +*
1.58 +@verbatim
1.59 + ************************
1.60 + Extract from the RFC-791
1.61 + ************************
1.62 + 0 1 2 3
1.63 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1.64 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.65 + |Version| IHL |Type of Service| Total Length |
1.66 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.67 + | Identification |Flags| Fragment Offset |
1.68 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.69 + | Time to Live | Protocol | Header Checksum |
1.70 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.71 + | Source Address |
1.72 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.73 + | Destination Address |
1.74 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.75 + | Options | Padding |
1.76 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1.77 +
1.78 + Version: 4 bits = 4
1.79 + IHL: 4 bits
1.80 +
1.81 + Internet Header Length is the length of the internet header in 32
1.82 + bit words, and thus points to the beginning of the data. Note that
1.83 + the minimum value for a correct header is 5
1.84 +
1.85 + Type of Service: 8 bits
1.86 + Bits 0-2: Precedence.
1.87 + Bit 3: 0 = Normal Delay, 1 = Low Delay.
1.88 + Bits 4: 0 = Normal Throughput, 1 = High Throughput.
1.89 + Bits 5: 0 = Normal Relibility, 1 = High Relibility.
1.90 + Bit 6-7: Reserved for Future Use.
1.91 +
1.92 + Precedence
1.93 +
1.94 + 111 - Network Control
1.95 + 110 - Internetwork Control
1.96 + 101 - CRITIC/ECP
1.97 + 100 - Flash Override
1.98 + 011 - Flash
1.99 + 010 - Immediate
1.100 + 001 - Priority
1.101 + 000 - Routine
1.102 + Total Length: 16 bits
1.103 + Total Length is the length of the datagram, measured in octets,
1.104 + including internet header and data.
1.105 +
1.106 + Identification: 16 bits
1.107 + An identifying value assigned by the sender to aid in assembling the
1.108 + fragments of a datagram.
1.109 +
1.110 + Flags: 3 bits
1.111 + Various Control Flags.
1.112 +
1.113 + Bit 0: reserved, must be zero
1.114 + Bit 1: (DF) 0 = May Fragment, 1 = Don't Fragment.
1.115 + Bit 2: (MF) 0 = Last Fragment, 1 = More Fragments.
1.116 +
1.117 + Fragment Offset: 13 bits
1.118 +
1.119 + This field indicates where in the datagram this fragment belongs.
1.120 + The fragment offset is measured in units of 8 octets (64 bits). The
1.121 + first fragment has offset zero.
1.122 +
1.123 + Time to Live: 8 bits
1.124 + Protocol: 8 bits
1.125 + Header Checksum: 16 bits
1.126 + Source Address: 32 bits
1.127 + Destination Address: 32 bits
1.128 +@endverbatim
1.129 +
1.130 +@publishedAll
1.131 +@released
1.132 +@since v7.0
1.133 +*/
1.134 + {
1.135 +public:
1.136 + //
1.137 + // Basic
1.138 + //
1.139 + /**
1.140 + * Gets the minimum header length.
1.141 + * @return Minimum header length (= 20)
1.142 + * @since v7.0
1.143 + */
1.144 + inline static TInt MinHeaderLength() {return 4*5; }
1.145 + /**
1.146 + * Gets the maximum header length.
1.147 + * @return Maximum header length (= 60)
1.148 + * @since v7.0
1.149 + */
1.150 + inline static TInt MaxHeaderLength() {return 4*15; }
1.151 + /**
1.152 + * Gets a pointer to the byte following the header.
1.153 + * @return Pointer to the byte following the header
1.154 + * @since v7.0
1.155 + */
1.156 + inline TUint8 *EndPtr() {return i + HeaderLength();}
1.157 +
1.158 + enum TOffsets
1.159 + {
1.160 + O_TotalLength = 2,
1.161 + O_FragmentOffset = 6,
1.162 + O_TTL = 8,
1.163 + O_Protocol = 9
1.164 + };
1.165 + inline TInt Version() const
1.166 + /**
1.167 + * Gets the IP version from the header.
1.168 + * @return IP version (should be 4 for IPv4)
1.169 + */
1.170 + {
1.171 + return (i[0] >> 4) & 0xf;
1.172 + }
1.173 + inline TInt HeaderLength() const
1.174 + /**
1.175 + * Gets the header length.
1.176 + * @return Header length in bytes (based on IHL field)
1.177 + */
1.178 + {
1.179 + return (i[0] & 0x0f) * 4; // Note: Returns bytes length!
1.180 + }
1.181 + inline TInt TOS() const
1.182 + /**
1.183 + * Gets the TOS from the header.
1.184 + * @return TOS
1.185 + */
1.186 + {
1.187 + return i[1];
1.188 + }
1.189 + inline TBool EcnIsCongestion()
1.190 + /**
1.191 + * Gets ECN congestion status.
1.192 + *
1.193 + * see RFC-3168 for details.
1.194 + *
1.195 + * @return True, if CE bit is set on an ECN capable packet.
1.196 + */
1.197 + {
1.198 + return ((TOS() & 3) == 3);
1.199 + }
1.200 + inline TInt TotalLength() const
1.201 + /**
1.202 + * Gets the Total Length from the header.
1.203 + * @return Total Length (includes IP header and payload)
1.204 + */
1.205 + {
1.206 + return (i[2] << 8) | i[3];
1.207 + }
1.208 + inline TInt Identification() const
1.209 + /**
1.210 + * Gets the Identification from the header.
1.211 + * @return Identification [0..65535]
1.212 + */
1.213 + {
1.214 + return (i[4] << 8) | i[5];
1.215 + }
1.216 + inline TInt Flags() const
1.217 + /**
1.218 + * Gets the Flags from the header.
1.219 + * @note returns flags byte as is, may include bits of fragment offset!
1.220 + * @return Flags
1.221 + */
1.222 + {
1.223 + return i[6];
1.224 + }
1.225 + inline TInt DF() const
1.226 + /**
1.227 + * Gets the DF flag from the header.
1.228 + * @return DF flag (= KInet4IP_DF, if set and zero otherwise)
1.229 + */
1.230 + {
1.231 + return i[6] & KInet4IP_DF;
1.232 + }
1.233 + inline TInt MF() const
1.234 + /**
1.235 + * Gets the MF flag from the header.
1.236 + * @return MF flag (= KInet4IP_MF, if set and zero otherwise)
1.237 + */
1.238 + {
1.239 + return i[6] & KInet4IP_MF;
1.240 + }
1.241 + inline TInt FragmentOffset() const
1.242 + /**
1.243 + * Gets the Fragment Offset from the header.
1.244 + * @return Fragment Offset (raw 8 octet units, not a bytes offset!)
1.245 + */
1.246 + {
1.247 + return ((i[6] & 0x1f) << 8) | i[7];
1.248 + }
1.249 + inline TInt Ttl() const
1.250 + /**
1.251 + * Gets the Time to Live from the header.
1.252 + * @return Time to Live [0..255]
1.253 + */
1.254 + {
1.255 + return i[8];
1.256 + }
1.257 + inline TInt Protocol() const
1.258 + /**
1.259 + * Gets the Protocol from the header.
1.260 + * @return Protocol [0..255]
1.261 + */
1.262 + {
1.263 + return i[9];
1.264 + }
1.265 + inline TInt Checksum() const
1.266 + /**
1.267 + * Gets the Header Checksum from the header.
1.268 + * @return Header Checksum (in NETWORK byte order)
1.269 + */
1.270 + {
1.271 + // Checksum is used in network byte order
1.272 + return *((TUint16 *)&i[10]);
1.273 + }
1.274 + inline TUint32 SrcAddr() const
1.275 + /**
1.276 + * Gets the source address from the header.
1.277 + * @return Source address (in host byte order)
1.278 + */
1.279 + {
1.280 + return (i[12] << 24) | (i[13] << 16) | (i[14] << 8) | i[15];
1.281 + }
1.282 + inline TUint32 DstAddr() const
1.283 + /**
1.284 + * Gets the destination address from the header.
1.285 + * @return Destination address (in host byte order)
1.286 + */
1.287 + {
1.288 + return (i[16] << 24) | (i[17] << 16) | (i[18] << 8) | i[19];
1.289 + }
1.290 + inline TUint32 &SrcAddrRef() const
1.291 + /**
1.292 + * Gets a raw reference to the source address in network byte order.
1.293 + * @return Raw reference to the source address
1.294 + */
1.295 + {
1.296 + return (TUint32 &)i[12];
1.297 + }
1.298 + inline TUint32 &DstAddrRef() const
1.299 + /**
1.300 + * Gets a raw reference to the destination address in network byte order.
1.301 + * @return Raw reference to the destination address
1.302 + */
1.303 + {
1.304 + return (TUint32 &)i[16];
1.305 + }
1.306 + inline TPtrC8 Options() const
1.307 + /**
1.308 + * Gets the Options from the header (const overload).
1.309 + * @return Options
1.310 + *
1.311 + * @note
1.312 + * This relies on correct value of IHL! Must not be used with
1.313 + * corrupt headers (will panic if IHL < 5!).
1.314 + */
1.315 + {
1.316 + // *NOTE* This includes the padding bytes, or can be empty!
1.317 + return TPtrC8((TUint8 *)&i[20], HeaderLength() - 20);
1.318 + }
1.319 + inline TPtr8 Options()
1.320 + /**
1.321 + * Gets the Options from the header.
1.322 + * @return Options
1.323 + *
1.324 + * @note
1.325 + * This relies on correct value of IHL! Must not be used with
1.326 + * corrupt headers (will panic if IHL < 5!).
1.327 + */
1.328 + {
1.329 + // It is yet unclear what will be the best way to build
1.330 + // the options into the header. For the time being this
1.331 + // method returns a modifiable Ptr8 to the the available
1.332 + // option space. For this to work, the application must
1.333 + // have used the SetHeaderLength() to fix the current
1.334 + // available length.
1.335 + return TPtr8((TUint8 *)&i[20], HeaderLength() - 20);
1.336 + }
1.337 +
1.338 + inline void Init(TInt aTOS = 0)
1.339 + /**
1.340 + * Initialises the IPv4 header to basic initial values.
1.341 + *
1.342 + * @li Version = 4
1.343 + * @li IHL = 5
1.344 + * @li Total Length = 20
1.345 + * @li Identification = 0
1.346 + * @li Fragment Offset = 0
1.347 + * @li Flags = 0
1.348 + * @li TTL = 0
1.349 + * @li Checksum = 0
1.350 + * @li TOS = aTOS (optional parameter, default = 0)
1.351 + *
1.352 + * However, address fields are not touched, because
1.353 + * they are most often set separately in any case.
1.354 + *
1.355 + * @param aTOS initial value for TOS (= 0)
1.356 + */
1.357 + {
1.358 + i[0] = 0x45; // Version=4, IHL=5 (= 20 bytes)
1.359 + i[1] = (TUint8)aTOS; // TOS
1.360 + i[2] = 0;
1.361 + i[3] = 20; // Total length = 20
1.362 + *((TInt32 *)&i[4]) = 0; // Identification = 0, flags=0, Fragment offset = 0;
1.363 + *((TInt32 *)&i[8]) = 0; // TTL=0,Protocol=0,Checksum=0
1.364 + }
1.365 + //
1.366 + // Build, set IP header field values into the packet
1.367 + //
1.368 +
1.369 + inline void SetVersion(TInt aVersion)
1.370 + /**
1.371 + * Sets the IP version in the header.
1.372 + * @param aVersion the value to be set [0..15]
1.373 + */
1.374 + {
1.375 + i[0] = (TUint8)((i[0] & 0x0f) | ((aVersion << 4) & 0xf0));
1.376 + }
1.377 + inline void SetHeaderLength(TInt aLength)
1.378 + /**
1.379 + * Sets the header length (IHL).
1.380 + *
1.381 + * @param aLength
1.382 + * the length of the IPv4 header in BYTES. The
1.383 + * IHL is computed from this, without any sanity
1.384 + * checks. The valid range is [20..60].
1.385 + */
1.386 + {
1.387 + i[0] = (TUint8)((i[0] & 0xf0) | ((aLength >> 2) & 0x0f));
1.388 + }
1.389 + inline void SetTOS(TInt aTos)
1.390 + /**
1.391 + * Sets the TOS in the header.
1.392 + * @param aTos The TOS value to set [0..255]
1.393 + */
1.394 + {
1.395 + i[1] = (TUint8)aTos;
1.396 + }
1.397 + inline void SetTotalLength(TInt aLength)
1.398 + /**
1.399 + * Sets the Total Length in the header.
1.400 + *
1.401 + * @param aLength the length of combined header and
1.402 + * payload in bytes (no sanity checks, but the
1.403 + * value should be in range [20..65535]). Only
1.404 + * 16 least significant bits used.
1.405 + */
1.406 + {
1.407 + i[3] = (TUint8)aLength;
1.408 + i[2] = (TUint8)(aLength >> 8);
1.409 + }
1.410 + inline void SetIdentification(TInt aId)
1.411 + /**
1.412 + * Sets the Identification in the header.
1.413 + *
1.414 + * @param aId the value to be set (only 16 least significant
1.415 + * bits are used, rest is ignored).
1.416 + */
1.417 + {
1.418 + i[5] = (TUint8)aId;
1.419 + i[4] = (TUint8)(aId >> 8);
1.420 + }
1.421 +
1.422 + inline void SetFlags(TUint8 aFlags)
1.423 + /**
1.424 + * Sets the Flags in the header.
1.425 + *
1.426 + * Flags are assumed to be in the three most significant bits
1.427 + * of aFlags, in their proper positions.
1.428 + * (No individual settings provided, if you need to set a flag
1.429 + * without affecting others, use Flags() to get old values,
1.430 + * update and store the result with SetFlags()).
1.431 + *
1.432 + * @param aFlags contains the new flags
1.433 + */
1.434 + {
1.435 + i[6] = (TUint8)((i[6] & 0x1f) | (aFlags & 0xe0));
1.436 + }
1.437 + inline void SetFragmentOffset(TUint16 aOffset)
1.438 + /**
1.439 + * Sets the Fragment Offset in the header.
1.440 + * @param aOffset Fragment Offset (8 octet units, not in bytes)
1.441 + */
1.442 + {
1.443 + i[6] = (TUint8)((i[6] & 0xe0) | ((aOffset >> 8) & 0x1f));
1.444 + i[7] = (TUint8)aOffset;
1.445 + }
1.446 + inline void SetTtl(TInt aTTL)
1.447 + /**
1.448 + * Sets the Time to Live in the header.
1.449 + * @param aTTL Time to Live [0..255]
1.450 + */
1.451 + {
1.452 + i[8] = (TUint8)aTTL;
1.453 + }
1.454 + inline void SetProtocol(TInt aProtocol)
1.455 + /**
1.456 + * Sets the Protocol in the header.
1.457 + * @param aProtocol Protocol [0..255]
1.458 + */
1.459 + {
1.460 + i[9] = (TUint8)aProtocol;
1.461 + }
1.462 + inline void SetChecksum(TInt aSum)
1.463 + /**
1.464 + * Sets the Header Checksum in the header.
1.465 + * @param aSum Header Checksum [0..65535]
1.466 + * (16 least significant bits stored
1.467 + * as is (assumed to be in NETWORK byte order).
1.468 + */
1.469 + {
1.470 + // Checksum is used in network byte order
1.471 + *((TUint16 *)&i[10]) = (TUint16)aSum;
1.472 + }
1.473 +
1.474 + inline void SetSrcAddr(TUint32 aAddr)
1.475 + /**
1.476 + * Sets the source address in the header.
1.477 + * @param aAddr Source address (IPv4, 32 bit integer in host byte order)
1.478 + */
1.479 + {
1.480 + i[15] = (TUint8)aAddr;
1.481 + i[14] = (TUint8)(aAddr >> 8);
1.482 + i[13] = (TUint8)(aAddr >> 16);
1.483 + i[12] = (TUint8)(aAddr >> 24);
1.484 + }
1.485 +
1.486 + inline void SetDstAddr(TUint32 aAddr)
1.487 + /**
1.488 + * Sets the destination address in the header.
1.489 + * @param aAddr Destination IPv4 address (32 bit integer) in host byte order
1.490 + */
1.491 + {
1.492 + i[19] = (TUint8)aAddr;
1.493 + i[18] = (TUint8)(aAddr >> 8);
1.494 + i[17] = (TUint8)(aAddr >> 16);
1.495 + i[16] = (TUint8)(aAddr >> 24);
1.496 + }
1.497 +
1.498 + //
1.499 + // The old IPv4 stack leaves IP header in packet when passing it upwards,
1.500 + // but this header is swapped into host order. As upper layers really don't
1.501 + // need this stuff much, only few "compatibility" methods is defined here
1.502 + //
1.503 +
1.504 + inline TInt HostHeaderLength() const
1.505 + {
1.506 + /**
1.507 + * Gets the Header Length from a header that is in Host byte order.
1.508 + * @return Header Length
1.509 + *
1.510 + * @deprecated There is no reason to use swapped headers
1.511 + */
1.512 + return (i[3] & 0x0f) * 4;
1.513 + }
1.514 + inline TInt HostProtocol() const
1.515 + /**
1.516 + * Gets the Protocol from a header that is in Host byte order.
1.517 + * @return Protocol
1.518 + * @deprecated There is no reason to use swapped headers
1.519 + */
1.520 + {
1.521 + return i[10];
1.522 + }
1.523 +
1.524 + inline void Swap()
1.525 + /**
1.526 + * Swaps the byte order in the header.
1.527 + * @deprecated There is no reason to use swapped headers
1.528 + */
1.529 + {
1.530 + *(TUint32 *)(&i[0]) = ByteOrder::Swap32(*(TUint32 *)(&i[0]));
1.531 + *(TUint32 *)(&i[4]) = ByteOrder::Swap32(*(TUint32 *)(&i[4]));
1.532 + *(TUint32 *)(&i[8]) = ByteOrder::Swap32(*(TUint32 *)(&i[8]));
1.533 + *(TUint32 *)(&i[12]) = ByteOrder::Swap32(*(TUint32 *)(&i[12]));
1.534 + *(TUint32 *)(&i[16]) = ByteOrder::Swap32(*(TUint32 *)(&i[16]));
1.535 + }
1.536 +
1.537 +private:
1.538 + union
1.539 + {
1.540 + TUint8 i[4*15]; ///< This allocates maximum length (60 bytes)
1.541 + TUint32 iAlign; ///< A dummy member to force the 4 byte alignment
1.542 + };
1.543 + };
1.544 +
1.545 +/**
1.546 +* @name IP v4 Option constants
1.547 +* @since v7.0
1.548 +* @publishedAll
1.549 +* @released
1.550 +*/
1.551 +///@{
1.552 +const TUint8 KInet4Option_End = 0x00;
1.553 +const TUint8 KInet4Option_Nop = 0x01;
1.554 +
1.555 +const TUint8 KInet4OptionFlag_Copy = 0x80;
1.556 +///@}
1.557 +
1.558 +//
1.559 +// ICMP v4 constants
1.560 +// =================
1.561 +//
1.562 +/**
1.563 +* @name ICMP v4 constants
1.564 +* @since v7.0
1.565 +* @publishedAll
1.566 +* @released
1.567 +*/
1.568 +///@{
1.569 +/** Echo Reply. See TInet6HeaderICMP_Echo (IPv4 and IPv6 use the same format). */
1.570 +const TUint8 KInet4ICMP_EchoReply = 0;
1.571 +const TUint8 KInet4ICMP_Unreachable = 3;
1.572 +const TUint8 KInet4ICMP_SourceQuench = 4;
1.573 +const TUint8 KInet4ICMP_Redirect = 5;
1.574 +/** Echo Request. See TInet6HeaderICMP_Echo (IPv4 and IPv6 use the same format). */
1.575 +const TUint8 KInet4ICMP_Echo = 8;
1.576 +const TUint8 KInet4ICMP_TimeExceeded = 11;
1.577 +const TUint8 KInet4ICMP_ParameterProblem = 12;
1.578 +const TUint8 KInet4ICMP_TimeStamp = 13;
1.579 +const TUint8 KInet4ICMP_TimeStampReply = 14;
1.580 +///@}
1.581 +
1.582 +///@}
1.583 +#endif