summaryrefslogtreecommitdiffstats
path: root/src/utl_ip.h
diff options
context:
space:
mode:
authorIdo Barnea <ibarnea@cisco.com>2016-11-15 16:27:08 +0200
committerIdo Barnea <ibarnea@cisco.com>2016-11-21 12:56:28 +0200
commitbf83f301e4fdbf333240af7f316735e35634c5fd (patch)
tree667c001d36a1b1a95b0f6da82d9919977543746c /src/utl_ip.h
parentc39cdf89bee7999ba714eb31e8ec4bc8b5d52a60 (diff)
client config ARP resolve working. Still missing IPv6 support.
Signed-off-by: Ido Barnea <ibarnea@cisco.com>
Diffstat (limited to 'src/utl_ip.h')
-rw-r--r--src/utl_ip.h216
1 files changed, 216 insertions, 0 deletions
diff --git a/src/utl_ip.h b/src/utl_ip.h
new file mode 100644
index 00000000..c5ca9d5b
--- /dev/null
+++ b/src/utl_ip.h
@@ -0,0 +1,216 @@
+#ifndef UTL_IP_H
+#define UTL_IP_H
+/*
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2016-2016 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include <map>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "common/basic_utils.h"
+#include "common/Network/Packet/CPktCmn.h"
+#include "common/Network/Packet/MacAddress.h"
+
+/* IP address, last 32-bits of IPv6 remaps IPv4 */
+typedef struct {
+ uint16_t v6[6]; /* First 96-bits of IPv6 */
+ uint32_t v4; /* Last 32-bits IPv6 overloads v4 */
+} ipaddr_t;
+
+// Routine to create IPv4 address string
+inline int ip_to_str(uint32_t ip,char * str) {
+ uint32_t ipv4 = PKT_HTONL(ip);
+ inet_ntop(AF_INET, (const char *)&ipv4, str, INET_ADDRSTRLEN);
+ return(strlen(str));
+}
+
+inline std::string ip_to_str(uint32_t ip) {
+ char tmp[INET_ADDRSTRLEN];
+ ip_to_str(ip, tmp);
+ return tmp;
+}
+
+// Routine to create IPv6 address string
+inline int ipv6_to_str(ipaddr_t *ip, char * str) {
+ int idx=0;
+ uint16_t ipv6[8];
+ for (uint8_t i=0; i<6; i++) {
+ ipv6[i] = PKT_HTONS(ip->v6[i]);
+ }
+ uint32_t ipv4 = PKT_HTONL(ip->v4);
+ ipv6[6] = ipv4 & 0xffff;
+ ipv6[7] = ipv4 >> 16;
+
+ str[idx++] = '[';
+ inet_ntop(AF_INET6, (const char *)&ipv6, &str[1], INET6_ADDRSTRLEN);
+ idx = strlen(str);
+ str[idx++] = ']';
+ str[idx] = 0;
+ return(idx);
+}
+
+inline std::string ip_to_str(uint8_t *ip) {
+ char tmp[INET6_ADDRSTRLEN];
+ ipv6_to_str((ipaddr_t *)ip, tmp);
+ return tmp;
+}
+
+class COneIPInfo {
+ public:
+ enum {
+ IP4_VER=4,
+ IP6_VER=6,
+ } COneIPInfo_ip_types;
+
+ public:
+ virtual void get_mac(uint8_t *mac) const {
+ m_mac.copyToArray(mac);
+ }
+ virtual void set_mac(uint8_t *mac) {
+ m_mac.set(mac);
+ }
+ uint16_t get_vlan() const {return m_vlan;}
+ uint16_t get_port() const {return m_port;}
+ virtual void dump(FILE *fd) const {
+ dump(fd, "");
+ }
+ virtual void dump(FILE *fd, const char *offset) const;
+ virtual uint8_t ip_ver() const {return 0;}
+ virtual uint32_t get_arp_req_len() const=0;
+ virtual uint32_t get_grat_arp_len() const=0;
+ virtual void fill_arp_req_buf(uint8_t *p, uint16_t port_id, COneIPInfo *sip)=0;
+ virtual void fill_grat_arp_buf(uint8_t *p)=0;
+ virtual bool resolve_needed() const;
+
+ protected:
+ COneIPInfo(uint16_t vlan, MacAddress mac, uint8_t port) : m_mac(mac) {
+ m_vlan = vlan;
+ m_port = port;
+ }
+ COneIPInfo(uint16_t vlan, MacAddress mac) : COneIPInfo(vlan, mac, UINT8_MAX) {
+ }
+ virtual const void get_ip_str(char str[100]) const {
+ snprintf(str, 4, "Bad");
+ }
+
+ protected:
+ uint8_t m_port;
+ uint16_t m_vlan;
+ MacAddress m_mac;
+};
+
+class COneIPv4Info : public COneIPInfo {
+ friend bool operator== (const COneIPv4Info& lhs, const COneIPv4Info& rhs);
+
+ public:
+ COneIPv4Info(uint32_t ip, uint16_t vlan, MacAddress mac) : COneIPInfo(vlan, mac) {
+ m_ip = ip;
+ }
+ COneIPv4Info(uint32_t ip, uint16_t vlan) : COneIPv4Info (ip, vlan, MacAddress()) {
+ }
+ COneIPv4Info(uint32_t ip, uint16_t vlan, MacAddress mac, uint8_t port) : COneIPInfo(vlan, mac, port) {
+ m_ip = ip;
+ }
+ uint32_t get_ip() {return m_ip;}
+ virtual uint8_t ip_ver() const {return IP4_VER;}
+ virtual uint32_t get_arp_req_len() const {return 60;}
+ virtual uint32_t get_grat_arp_len() const {return 60;}
+ virtual void fill_arp_req_buf(uint8_t *p, uint16_t port_id, COneIPInfo *sip);
+ virtual void fill_grat_arp_buf(uint8_t *p);
+
+ private:
+ virtual const void get_ip_str(char str[100]) const {
+ ip_to_str(m_ip, str);
+ };
+ uint32_t m_ip;
+};
+
+inline bool operator== (const COneIPv4Info& lhs, const COneIPv4Info& rhs) {
+ if (lhs.m_vlan != rhs.m_vlan)
+ return false;
+
+ if (lhs.m_ip != rhs.m_ip)
+ return false;
+
+ return true;
+}
+
+inline bool operator!= (const COneIPv4Info& lhs, const COneIPv4Info& rhs){ return !(lhs == rhs); }
+
+class COneIPv6Info : public COneIPInfo {
+ friend bool operator== (const COneIPv6Info& lhs, const COneIPv6Info& rhs);
+
+ public:
+ COneIPv6Info(uint16_t ip[8], uint16_t vlan, MacAddress mac) : COneIPInfo(vlan, mac) {
+ memcpy(m_ip, ip, sizeof(m_ip));
+ }
+
+ COneIPv6Info(uint16_t ip[8], uint16_t vlan) : COneIPv6Info(ip, vlan, MacAddress()){
+ }
+
+ COneIPv6Info(uint16_t ip[8], uint16_t vlan, MacAddress mac, uint8_t port) : COneIPInfo(vlan, mac, port) {
+ memcpy(m_ip, ip, sizeof(m_ip));
+ }
+
+ const uint8_t *get_ipv6() {return (uint8_t *)m_ip;}
+ virtual uint8_t ip_ver() const {return IP6_VER;}
+ virtual uint32_t get_arp_req_len() const {return 100; /* ??? put correct number for ipv6*/}
+ virtual uint32_t get_grat_arp_len() const {return 100; /* ??? put correct number for ipv6*/}
+ virtual void fill_arp_req_buf(uint8_t *p, uint16_t port_id, COneIPInfo *sip);
+ virtual void fill_grat_arp_buf(uint8_t *p);
+
+ private:
+ virtual const void get_ip_str(char str[100]) {
+ ipv6_to_str((ipaddr_t *)m_ip, str);
+ }
+ uint16_t m_ip[8];
+};
+
+inline bool operator== (const COneIPv6Info& lhs, const COneIPv6Info& rhs) {
+ if (lhs.m_vlan != rhs.m_vlan)
+ return false;
+
+ if (memcmp(&lhs.m_ip, &rhs.m_ip, sizeof(rhs.m_ip)))
+ return false;
+
+ return true;
+}
+
+inline bool operator!= (const COneIPv6Info& lhs, const COneIPv6Info& rhs){ return !(lhs == rhs); }
+
+class CManyIPInfo {
+ public:
+ CManyIPInfo () {
+ m_iter_initiated = false;
+ }
+ void insert(COneIPv4Info &ip_info);
+ bool lookup(uint32_t ip, uint16_t vlan, MacAddress &ret_mac);
+ void dump(FILE *fd);
+ uint32_t size() { return m_ipv4_resolve.size() + m_ipv6_resolve.size();}
+ const COneIPInfo *get_first();
+ const COneIPInfo *get_next();
+ private:
+ std::map<std::pair<uint32_t, uint16_t>, COneIPv4Info> m_ipv4_resolve;
+ std::map<std::pair<uint16_t[8], uint16_t>, COneIPv6Info> m_ipv6_resolve;
+ std::map<std::pair<uint32_t, uint16_t>, COneIPv4Info>::iterator m_ipv4_iter;
+ bool m_iter_initiated;
+
+};
+
+#endif