aboutsummaryrefslogtreecommitdiffstats
path: root/test/packetdrill/ip_address.h
diff options
context:
space:
mode:
Diffstat (limited to 'test/packetdrill/ip_address.h')
-rw-r--r--test/packetdrill/ip_address.h131
1 files changed, 131 insertions, 0 deletions
diff --git a/test/packetdrill/ip_address.h b/test/packetdrill/ip_address.h
new file mode 100644
index 0000000..6ee586b
--- /dev/null
+++ b/test/packetdrill/ip_address.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+/*
+ * Author: ncardwell@google.com (Neal Cardwell)
+ *
+ * Types and operations for IPv4 and IPv6 addresses.
+ */
+
+#ifndef __IP_ADDRESS_H__
+#define __IP_ADDRESS_H__
+
+#include "types.h"
+
+#include <netinet/in.h>
+
+/* IPv4 or IPv6 address. */
+struct ip_address {
+ int address_family; /* AF_INET or AF_INET6 */
+ union {
+ struct in_addr v4;
+ struct in6_addr v6;
+ u8 bytes[16];
+ } ip; /* IP address (network order) */
+};
+
+static inline void ip_reset(struct ip_address *ip)
+{
+ memset(ip, 0, sizeof(*ip));
+}
+
+/* Fill in an ip_address using the given family-specific struct. */
+extern void ip_from_ipv4(const struct in_addr *ipv4, struct ip_address *ip);
+extern void ip_from_ipv6(const struct in6_addr *ipv6, struct ip_address *ip);
+
+/* Fill in the given family-specific struct using the given ip_address. */
+extern void ip_to_ipv4(const struct ip_address *ip, struct in_addr *ipv4);
+extern void ip_to_ipv6(const struct ip_address *ip, struct in6_addr *ipv6);
+
+/* Return the number of bytes in the on-the-wire representation of
+ * addresses of the given family.
+ */
+extern int ip_address_length(int address_family);
+
+/* Return the number of bytes in sockaddr of the given family. */
+extern int sockaddr_length(int address_family);
+
+/* Return true iff the two addresses are the same. */
+static inline bool is_equal_ip(const struct ip_address *a,
+ const struct ip_address *b)
+{
+ return ((a->address_family == b->address_family) &&
+ !memcmp(&a->ip, &b->ip, ip_address_length(a->address_family)));
+}
+
+/* Parse a human-readable IPv4 address and return it. Print an error
+ * to stderr and exit if there is an error parsing the address.
+ */
+extern struct ip_address ipv4_parse(const char *ip_string);
+
+/* Parse a human-readable IPv6 address and return it. Print an error
+ * to stderr and exit if there is an error parsing the address.
+ */
+extern struct ip_address ipv6_parse(const char *ip_string);
+
+/* Print a human-readable representation of the given IP address in the
+ * given buffer, which must be at least ADDR_STR_LEN bytes long.
+ * Returns a pointer to the given buffer.
+ */
+extern const char *ip_to_string(const struct ip_address *ip, char *buffer);
+
+/* Create an IPv4-mapped IPv6 address. */
+extern struct ip_address ipv6_map_from_ipv4(const struct ip_address ipv4);
+
+/* Deconstruct an IPv4-mapped IPv6 address and fill in *ipv4 with the
+ * IPv4 address that was mapped into IPv6 space. Return STATUS_OK on
+ * success, or STATUS_ERR on failure (meaning the input ipv6 was not
+ * actually an IPv4-mapped IPv6 address).
+ */
+extern int ipv6_map_to_ipv4(const struct ip_address ipv6,
+ struct ip_address *ipv4);
+
+/* Fill in a sockaddr struct and socklen_t using the given IP and port.
+ * The IP address may be IPv4 or IPv6.
+ */
+extern void ip_to_sockaddr(const struct ip_address *ip, u16 port,
+ struct sockaddr *address, socklen_t *length);
+
+/* Fill in an IP address and port by parsing a sockaddr struct and
+ * socklen_t using the given IP and port. The IP address may be IPv4
+ * or IPv6. Exits with an error message if the address family is other
+ * than AF_INET or AF_INET6.
+ */
+extern void ip_from_sockaddr(const struct sockaddr *address, socklen_t length,
+ struct ip_address *ip, u16 *port);
+
+/* Return true iff the address is that of a local interface. */
+/* Note: this should return bool, but that doesn't compile on NetBSD. */
+extern int is_ip_local(const struct ip_address *ip);
+
+/* Fill in the name of the device configured with the given IP, if
+ * any. The dev_name buffer should be at least IFNAMSIZ bytes.
+ * Return true iff the IP is found on a local device.
+ */
+/* Note: this should return bool, but that doesn't compile on NetBSD. */
+extern int get_ip_device(const struct ip_address *ip, char *dev_name);
+
+/* Convert dotted decimal netmask to equivalent CIDR prefix length */
+extern int netmask_to_prefix(const char *netmask);
+
+void generate_random_ipv4_addr(char *result, const char *base,
+ const char *netmask);
+
+void generate_random_ipv6_addr(char *result, const char *base, int prefixlen);
+
+#endif /* __IP_ADDRESS_H__ */