00001 //--------------------------------------------------------------------------
00002 // Copyright (C) 2014-2017 Cisco and/or its affiliates. All rights reserved.
00003 //
00004 // This program is free software; you can redistribute it and/or modify it
00005 // under the terms of the GNU General Public License Version 2 as published
00006 // by the Free Software Foundation. You may not use, modify or distribute
00007 // this program under any other version of the GNU General Public License.
00008 //
00009 // This program is distributed in the hope that it will be useful, but
00010 // WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License along
00015 // with this program; if not, write to the Free Software Foundation, Inc.,
00016 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017 //--------------------------------------------------------------------------
00018 // ipv4.h author Josh Rosenbaum <jrosenba@cisco.com>
00019
00020 #ifndef PROTOCOLS_IPV4_H
00021 #define PROTOCOLS_IPV4_H
00022
00023 #include <arpa/inet.h>
00024
00025 #include "protocols/protocol_ids.h" // include ipv4 protocol numbers
00026
00027 #define ETHERNET_TYPE_IP 0x0800
00028
00029 #ifndef IP_MAXPACKET
00030 #define IP_MAXPACKET 65535 /* maximum packet size */
00031 #endif
00032
00033 namespace ip
00034 {
00035 constexpr uint32_t IP4_BROADCAST = 0xffffffff;
00036 constexpr uint8_t IP4_HEADER_LEN = 20;
00037 constexpr uint8_t IP4_THIS_NET = 0x00; // msb
00038 constexpr uint8_t IP4_MULTICAST = 0x0E; // ms nibble
00039 constexpr uint8_t IP4_RESERVED = 0x0F; // ms nibble
00040 constexpr uint8_t IP4_LOOPBACK = 0x7F; // msb
00041
00042 // This must be a standard layer struct!
00043 struct IP4Hdr
00044 {
00045 uint8_t ip_verhl; /* version & header length */
00046 uint8_t ip_tos; /* type of service */
00047 uint16_t ip_len; /* datagram length */
00048 uint16_t ip_id; /* identification */
00049 uint16_t ip_off; /* fragment offset */
00050 uint8_t ip_ttl; /* time to live field */
00051 IpProtocol ip_proto; /* datagram protocol */
00052 uint16_t ip_csum; /* checksum */
00053 uint32_t ip_src; /* source IP */
00054 uint32_t ip_dst; /* dest IP */
00055
00056 /* getters */
00057 inline uint8_t hlen() const
00058 { return (uint8_t)((ip_verhl & 0x0f) << 2); }
00059
00060 inline uint8_t ver() const
00061 { return (ip_verhl >> 4); }
00062
00063 inline uint8_t tos() const
00064 { return ip_tos; }
00065
00066 inline uint16_t len() const
00067 { return ntohs(ip_len); }
00068
00069 inline uint8_t ttl() const
00070 { return ip_ttl; }
00071
00072 inline IpProtocol proto() const
00073 { return ip_proto; }
00074
00075 inline uint16_t off_w_flags() const
00076 { return ntohs(ip_off); }
00077
00078 inline uint16_t rb() const
00079 { return ntohs(ip_off) & 0x8000; }
00080
00081 inline uint16_t df() const
00082 { return ntohs(ip_off) & 0x4000; }
00083
00084 inline uint16_t mf() const
00085 { return ntohs(ip_off) & 0x2000; }
00086
00087 inline uint16_t off() const
00088 { return (uint16_t)((ntohs(ip_off) & 0x1FFF) << 3); }
00089
00090 inline uint16_t id() const
00091 { return ntohs(ip_id); }
00092
00093 inline uint8_t get_opt_len() const
00094 { return hlen() - IP4_HEADER_LEN; }
00095
00096 inline uint16_t csum() const
00097 { return ntohs(ip_csum); }
00098
00099 /* booleans */
00100 inline bool is_src_broadcast() const
00101 { return ip_src == IP4_BROADCAST; }
00102
00103 inline bool is_dst_broadcast() const
00104 { return ip_dst == IP4_BROADCAST; }
00105
00106 inline bool has_options() const
00107 { return hlen() > 20; }
00108
00109 /* Access raw data */
00110 inline uint16_t raw_len() const
00111 { return ip_len; }
00112
00113 inline uint16_t raw_id() const
00114 { return ip_id; }
00115
00116 inline uint16_t raw_off() const
00117 { return ip_off; }
00118
00119 inline uint16_t raw_csum() const
00120 { return ip_csum; }
00121
00122 inline uint32_t get_src() const
00123 { return ip_src; }
00124
00125 inline uint32_t get_dst() const
00126 { return ip_dst; }
00127
00128 /* setters */
00129 inline void set_hlen(uint8_t value)
00130 { ip_verhl = (ip_verhl & 0xf0) | (value & 0x0f); }
00131
00132 inline void set_proto(IpProtocol prot)
00133 { ip_proto = prot; }
00134
00135 inline void set_ip_len(uint16_t new_len)
00136 { ip_len = htons(new_len); }
00137 };
00138
00139 inline bool isPrivateIP(uint32_t addr)
00140 {
00141 addr = ntohl(addr);
00142 switch (addr & 0xFF000000)
00143 {
00144 case 0x0A000000: // 10.0.0.0/8
00145 return true;
00146 case 0xA9000000: // 169.254.0.0/16
00147 return (addr & 0x00FF0000) == 0x00FE0000;
00148 case 0xAC000000: // 172.16.0.0/12
00149 return (addr & 0x00F00000) == 0x00100000;
00150 case 0xC0000000: // 192.168.0.0/16
00151 return (addr & 0x00FF0000) == 0x00A80000;
00152 }
00153 return false;
00154 }
00155 } /* namespace ip */
00156
00157 /* tcpdump shows us the way to cross platform compatibility */
00158
00159 /* we need to change them as well as get them */
00160 // TYPEDEF WHICH NEED TO BE DELETED
00161 typedef ip::IP4Hdr IP4Hdr;
00162
00163 /* #define IP_HEADER_LEN ip::ip4_hdr_len() */
00164
00165 #endif
00166
END OF CODE