Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef ICMP_HEADER_HPP
00012 #define ICMP_HEADER_HPP
00013
00014 #include <istream>
00015 #include <ostream>
00016 #include <algorithm>
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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