Signed-off-by: Robbie King <[email protected]>
---
 example/ipsec/odp_ipsec_misc.h |  321 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 321 insertions(+), 0 deletions(-)
 create mode 100644 example/ipsec/odp_ipsec_misc.h

diff --git a/example/ipsec/odp_ipsec_misc.h b/example/ipsec/odp_ipsec_misc.h
new file mode 100644
index 0000000..e5db950
--- /dev/null
+++ b/example/ipsec/odp_ipsec_misc.h
@@ -0,0 +1,321 @@
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#ifndef ODP_IPSEC_MISC_H_
+#define ODP_IPSEC_MISC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp.h>
+#include <helper/odp_ip.h>
+#include <helper/odp_ipsec.h>
+
+#define TRUE  1
+#define FALSE 0
+
+#define MAX_DB          32   /**< maximum number of data base entries */
+#define MAX_LOOPBACK    10   /**< maximum number of loop back interfaces */
+
+/** IPv4 helpers for data length and uint8t pointer */
+#define ipv4_data_len(ip) (odp_be_to_cpu_16(ip->tot_len) - 
sizeof(odp_ipv4hdr_t))
+#define ipv4_data_p(ip) ((uint8_t *)((odp_ipv4hdr_t *)ip + 1))
+
+/** Helper for calculating encode length using data length and block size */
+#define ESP_ENCODE_LEN(x, b) ((((x) + (b - 1)) / b) * b)
+
+/** Get rid of path in filename - only for unix-type paths using '/' */
+#define NO_PATH(file_name) (strrchr((file_name), '/') ?                 \
+                           strrchr((file_name), '/') + 1 : (file_name))
+
+/**
+ * IPsec key
+ */
+typedef struct {
+       uint8_t  data[32];  /**< Key data */
+       uint8_t  length;    /**< Key length */
+} ipsec_key_t;
+
+/**
+ * IPsec algorithm
+ */
+typedef struct {
+       bool cipher;
+       union {
+               enum odp_cipher_alg cipher;
+               enum odp_auth_alg   auth;
+       } u;
+} ipsec_alg_t;
+
+/**
+ * IP address range (subnet)
+ */
+typedef struct ip_addr_range_s {
+       uint32_t  addr;     /**< IP address */
+       uint32_t  mask;     /**< mask, 1 indicates bits are valid */
+} ip_addr_range_t;
+
+/**
+ * Parse text string representing a key into ODP key structure
+ *
+ * @param keystring  Pointer to key string to convert
+ * @param key        Pointer to ODP key structure to populate
+ * @param alg        Cipher/authentication algorithm associated with the key
+ *
+ * @return 0 if successful else -1
+ */
+static inline
+int parse_key_string(char *keystring,
+                    ipsec_key_t *key,
+                    ipsec_alg_t *alg)
+{
+       int idx;
+       char temp[3];
+
+       if (alg->cipher && (alg->u.cipher == ODP_CIPHER_ALG_3DES_CBC))
+               if (48 == strlen(keystring))
+                       key->length = 24;
+
+       if (!alg->cipher && (alg->u.auth == ODP_AUTH_ALG_MD5_96))
+               if (32 == strlen(keystring))
+                       key->length = 16;
+
+       for (idx = 0; idx < key->length; idx++) {
+               temp[0] = *keystring++;
+               temp[1] = *keystring++;
+               temp[2] = 0;
+               key->data[idx] = strtol(temp, NULL, 16);
+       }
+
+       return key->length ? 0 : -1;
+}
+
+/**
+ * Check IPv4 address against a range/subnet
+ *
+ * @param addr  IPv4 address to check
+ * @param range Pointer to address range to check against
+ *
+ * @return 1 if match else 0
+ */
+static inline
+int match_ip_range(uint32_t addr, ip_addr_range_t *range)
+{
+       return (range->addr == (addr & range->mask));
+}
+
+/**
+ * Generate text string representing IPv4 address
+ *
+ * @param b    Pointer to buffer to store string
+ * @param addr IPv4 address
+ *
+ * @return Pointer to supplied buffer
+ */
+static inline
+char *ipv4_addr_str(char *b, uint32_t addr)
+{
+       sprintf(b, "%03d.%03d.%03d.%03d",
+               0xFF & ((addr) >> 24),
+               0xFF & ((addr) >> 16),
+               0xFF & ((addr) >>  8),
+               0xFF & ((addr) >>  0));
+       return b;
+}
+
+/**
+ * Parse text string representing an IPv4 address or subnet
+ *
+ * String is of the format "XXX.XXX.XXX.XXX(/W)" where
+ * "XXX" is decimal value and "/W" is optional subnet length
+ *
+ * @param ipaddress  Pointer to IP address/subnet string to convert
+ * @param addr       Pointer to return IPv4 address
+ * @param mask       Pointer (optional) to return IPv4 mask
+ *
+ * @return 0 if successful else -1
+ */
+static inline
+int parse_ipv4_string(char *ipaddress, uint32_t *addr, uint32_t *mask)
+{
+       int b[4];
+       int qualifier = 32;
+       int converted;
+
+       if (strchr(ipaddress, '/')) {
+               converted = sscanf(ipaddress, "%d.%d.%d.%d/%d",
+                                  &b[3], &b[2], &b[1], &b[0],
+                                  &qualifier);
+               if (5 != converted)
+                       return -1;
+       } else {
+               converted = sscanf(ipaddress, "%d.%d.%d.%d",
+                                  &b[3], &b[2], &b[1], &b[0]);
+               if (4 != converted)
+                       return -1;
+       }
+
+       if ((b[0] > 255) || (b[1] > 255) || (b[2] > 255) || (b[3] > 255))
+               return -1;
+       if (!qualifier || (qualifier > 32))
+               return -1;
+
+       *addr = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
+       if (mask)
+               *mask = ~(0xFFFFFFFF & ((1ULL << (32 - qualifier)) - 1));
+
+       return 0;
+}
+
+/**
+ * Generate text string representing IPv4 range/subnet, output
+ * in "XXX.XXX.XXX.XXX/W" format
+ *
+ * @param b     Pointer to buffer to store string
+ * @param range Pointer to IPv4 address range
+ *
+ * @return Pointer to supplied buffer
+ */
+static inline
+char *ipv4_subnet_str(char *b, ip_addr_range_t *range)
+{
+       int idx;
+       int len;
+
+       for (idx = 0; idx < 32; idx++)
+               if (range->mask & (1 << idx))
+                       break;
+       len = 32 - idx;
+
+       sprintf(b, "%03d.%03d.%03d.%03d/%d",
+               0xFF & ((range->addr) >> 24),
+               0xFF & ((range->addr) >> 16),
+               0xFF & ((range->addr) >>  8),
+               0xFF & ((range->addr) >>  0),
+               len);
+       return b;
+}
+
+/**
+ * Generate text string representing MAC address
+ *
+ * @param b     Pointer to buffer to store string
+ * @param mac   Pointer to MAC address
+ *
+ * @return Pointer to supplied buffer
+ */
+static inline
+char *mac_addr_str(char *b, uint8_t *mac)
+{
+       sprintf(b, "%02X.%02X.%02X.%02X.%02X.%02X",
+               mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+       return b;
+}
+
+/**
+ * Parse text string representing a MAC address into byte araray
+ *
+ * String is of the format "XX.XX.XX.XX.XX.XX" where XX is hexadecimal
+ *
+ * @param macaddress  Pointer to MAC address string to convert
+ * @param mac         Pointer to MAC address byte array to populate
+ *
+ * @return 0 if successful else -1
+ */
+static inline
+int parse_mac_string(char *macaddress, uint8_t *mac)
+{
+       int macwords[6];
+       int converted;
+
+       converted = sscanf(macaddress,
+                          "%x.%x.%x.%x.%x.%x",
+                          &macwords[0], &macwords[1], &macwords[2],
+                          &macwords[3], &macwords[4], &macwords[5]);
+       if (6 != converted)
+               return -1;
+
+       mac[0] = macwords[0];
+       mac[1] = macwords[1];
+       mac[2] = macwords[2];
+       mac[3] = macwords[3];
+       mac[4] = macwords[4];
+       mac[5] = macwords[5];
+
+       return 0;
+}
+
+/**
+ * Locate IPsec headers (AH and/or ESP) in packet
+ *
+ * @param ip     Pointer to packets IPv4 header
+ * @param ah_p   Pointer to location to return AH header pointer
+ * @param esp_p  Pointer to location to return ESP header pointer
+ *
+ * @return length of IPsec headers found
+ */
+static inline
+int locate_ipsec_headers(odp_ipv4hdr_t *ip,
+                        odp_ahhdr_t **ah_p,
+                        odp_esphdr_t **esp_p)
+{
+       uint8_t *in = ipv4_data_p(ip);
+       odp_ahhdr_t *ah = NULL;
+       odp_esphdr_t *esp = NULL;
+
+       if (ODP_IPPROTO_AH == ip->proto) {
+               ah = (odp_ahhdr_t *)in;
+               in += ((ah)->ah_len + 2) * 4;
+               if (ODP_IPPROTO_ESP == ah->next_header) {
+                       esp = (odp_esphdr_t *)in;
+                       in += sizeof(odp_esphdr_t);
+               }
+       } else if (ODP_IPPROTO_ESP == ip->proto) {
+               esp = (odp_esphdr_t *)in;
+               in += sizeof(odp_esphdr_t);
+       }
+
+       *ah_p = ah;
+       *esp_p = esp;
+       return in - (ipv4_data_p(ip));
+}
+
+/**
+ * Adjust IPv4 length
+ *
+ * @param ip   Pointer to IPv4 header
+ * @param adj  Signed adjustment value
+ */
+static inline
+void ipv4_adjust_len(odp_ipv4hdr_t *ip, int adj)
+{
+       ip->tot_len = odp_cpu_to_be_16(odp_be_to_cpu_16(ip->tot_len) + adj);
+}
+
+/**
+ * Verify crypto operation completed successfully
+ *
+ * @param status  Pointer to cryto completion structure
+ *
+ * @return TRUE if all OK else FALSE
+ */
+static inline
+bool is_crypto_compl_status_ok(odp_crypto_compl_status_t *status)
+{
+       if (status->alg_err != ODP_CRYPTO_ALG_ERR_NONE)
+               return FALSE;
+       if (status->hw_err != ODP_CRYPTO_HW_ERR_NONE)
+               return FALSE;
+       return TRUE;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
-- 
1.7.7.6


_______________________________________________
lng-odp mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to