icmp_header.hpp
Go to the documentation of this file.
00001 //
00002 // icmp_header.hpp
00003 // ~~~~~~~~~~~~~~~
00004 //
00005 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
00006 //
00007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
00008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00009 //
00010 
00011 #ifndef ICMP_HEADER_HPP
00012 #define ICMP_HEADER_HPP
00013 
00014 #include <istream>
00015 #include <ostream>
00016 #include <algorithm>
00017 
00018 // ICMP header for both IPv4 and IPv6.
00019 //
00020 // The wire format of an ICMP header is:
00021 // 
00022 // 0               8               16                             31
00023 // +---------------+---------------+------------------------------+      ---
00024 // |               |               |                              |       ^
00025 // |     type      |     code      |          checksum            |       |
00026 // |               |               |                              |       |
00027 // +---------------+---------------+------------------------------+    8 bytes
00028 // |                               |                              |       |
00029 // |          identifier           |       sequence number        |       |
00030 // |                               |                              |       v
00031 // +-------------------------------+------------------------------+      ---
00032 
00033 class icmp_header
00034 {
00035 public:
00036     enum { echo_reply = 0, destination_unreachable = 3, source_quench = 4,
00037            redirect = 5, echo_request = 8, time_exceeded = 11, parameter_problem = 12,
00038            timestamp_request = 13, timestamp_reply = 14, info_request = 15,
00039            info_reply = 16, address_request = 17, address_reply = 18 };
00040 
00041     icmp_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }
00042 
00043     unsigned char type() const { return rep_[0]; }
00044     unsigned char code() const { return rep_[1]; }
00045     unsigned short checksum() const { return decode(2, 3); }
00046     unsigned short identifier() const { return decode(4, 5); }
00047     unsigned short sequence_number() const { return decode(6, 7); }
00048 
00049     void type(unsigned char n) { rep_[0] = n; }
00050     void code(unsigned char n) { rep_[1] = n; }
00051     void checksum(unsigned short n) { encode(2, 3, n); }
00052     void identifier(unsigned short n) { encode(4, 5, n); }
00053     void sequence_number(unsigned short n) { encode(6, 7, n); }
00054 
00055     friend std::istream& operator>>(std::istream& is, icmp_header& header)
00056     { return is.read(reinterpret_cast<char*>(header.rep_), 8); }
00057 
00058     friend std::ostream& operator<<(std::ostream& os, const icmp_header& header)
00059     { return os.write(reinterpret_cast<const char*>(header.rep_), 8); }
00060 
00061 private:
00062     unsigned short decode(int a, int b) const
00063     { return (rep_[a] << 8) + rep_[b]; }
00064 
00065     void encode(int a, int b, unsigned short n)
00066     {
00067         rep_[a] = static_cast<unsigned char>(n >> 8);
00068         rep_[b] = static_cast<unsigned char>(n & 0xFF);
00069     }
00070 
00071     unsigned char rep_[8];
00072 };
00073 
00074 template <typename Iterator>
00075 void compute_checksum(icmp_header& header,
00076                       Iterator body_begin, Iterator body_end)
00077 {
00078     unsigned int sum = (header.type() << 8) + header.code()
00079         + header.identifier() + header.sequence_number();
00080 
00081     Iterator body_iter = body_begin;
00082     while (body_iter != body_end)
00083         {
00084             sum += (static_cast<unsigned char>(*body_iter++) << 8);
00085             if (body_iter != body_end)
00086                 sum += static_cast<unsigned char>(*body_iter++);
00087         }
00088 
00089     sum = (sum >> 16) + (sum & 0xFFFF);
00090     sum += (sum >> 16);
00091     header.checksum(static_cast<unsigned short>(~sum));
00092 }
00093 
00094 #endif // ICMP_HEADER_HPP
00095 


rosping
Author(s): Kei Okada
autogenerated on Mon Oct 6 2014 11:00:33