diff options
Diffstat (limited to 'drivers/interceptor/sshinet.h')
-rw-r--r-- | drivers/interceptor/sshinet.h | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/drivers/interceptor/sshinet.h b/drivers/interceptor/sshinet.h new file mode 100644 index 0000000..ac18c53 --- /dev/null +++ b/drivers/interceptor/sshinet.h @@ -0,0 +1,233 @@ +/* Netfilter Driver for IPSec VPN Client + * + * Copyright(c) 2012 Samsung Electronics + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * sshinet.h + * + * Inet API. + * + */ + +#ifndef SSHINET_H +#define SSHINET_H + +#include "sshgetput.h" + +/*************************** Ethernet definitions ***************************/ + +/* Etherenet header things we need */ +#define SSH_ETHERH_HDRLEN 14 +#define SSH_ETHERH_OFS_DST 0 +#define SSH_ETHERH_OFS_SRC 6 +#define SSH_ETHERH_OFS_TYPE 12 +#define SSH_ETHERH_ADDRLEN 6 + +/* Known values for the ethernet type field. The same values are used for + both ethernet (rfc894) and IEEE 802 encapsulation (the type will just + be in a different position in the header). */ +#define SSH_ETHERTYPE_IP 0x0800 /* IPv4, as per rfc894 */ +#define SSH_ETHERTYPE_ARP 0x0806 /* ARP, as per rfc826 */ +#define SSH_ETHERTYPE_IPv6 0x86dd /* IPv6, as per rfc1972 */ + + +/***************************** SshIpAddr stuff ******************************/ + +typedef enum { + SSH_IP_TYPE_NONE = 0, + SSH_IP_TYPE_IPV4 = 1, + SSH_IP_TYPE_IPV6 = 2 +} SshIpAddrType; + +#if defined(WITH_IPV6) +/* An IPv6 link-local address scope ID. */ +struct SshScopeIdRec +{ + union + { + SshUInt32 ui32; + } scope_id_union; +}; + +typedef struct SshScopeIdRec SshScopeIdStruct; +typedef struct SshScopeIdRec *SshScopeId; + +#endif /* WITH_IPV6 */ + +#if !defined(WITH_IPV6) +#define SSH_IP_ADDR_SIZE 4 +#define SSH_IP_ADDR_STRING_SIZE 32 +#else /* WITH_IPV6 */ +#define SSH_IP_ADDR_SIZE 16 +#define SSH_IP_ADDR_STRING_SIZE 64 +#endif /* !WITH_IPV6 */ + +typedef struct SshIpAddrRec +{ + /* Note: All fields of this data structure are private, and should + not be accessed except using the macros and functions defined in + this header. They should never be accessed directly; the + internal definition of this structure is subject to change + without notice. */ + SshUInt8 type; /* KEEP type first if changing rest of the contents */ + SshUInt8 mask_len; + + /* There is a hole of 16 bits here */ + + /* For optimised mask comparison routine _addr_data has to be 32-bit + aligned so it can be read as words on machines requiring + alignment */ + union { + unsigned char _addr_data[SSH_IP_ADDR_SIZE]; + SshUInt32 _addr_align; + } addr_union; + +#define addr_data addr_union._addr_data + +#if defined(WITH_IPV6) + SshScopeIdStruct scope_id; +#endif /* WITH_IPV6 */ + +} *SshIpAddr, SshIpAddrStruct; + +#define SSH_IP_DEFINED(ip_addr) ((ip_addr)->type != SSH_IP_TYPE_NONE) +#define SSH_IP_IS4(ip_addr) ((ip_addr)->type == SSH_IP_TYPE_IPV4) +#define SSH_IP_IS6(ip_addr) ((ip_addr)->type == SSH_IP_TYPE_IPV6) + +#define SSH_IP_ADDR_LEN(ip_addr) \ + (SSH_PREDICT_TRUE(SSH_IP_IS4(ip_addr))\ + ? (4) \ + : (SSH_IP_IS6(ip_addr) \ + ? (16) \ + : 0)) + +/* Make given IP address undefined. */ +#define SSH_IP_UNDEFINE(IPADDR) \ +do { \ + (IPADDR)->type = SSH_IP_TYPE_NONE; \ +} while (0) + + +#if defined(WITH_IPV6) +/* Decode, that is fill given 'ipaddr', with given 'type', 'bytes' and + 'masklen' information. */ +#define __SSH_IP_MASK_DECODE(IPADDR,TYPE,BYTES,BYTELEN,MASKLEN) \ + do { \ + (IPADDR)->type = (TYPE); \ + memmove((IPADDR)->addr_data, (BYTES), (BYTELEN)); \ + memset(&(IPADDR)->scope_id, 0, sizeof((IPADDR)->scope_id)); \ + (IPADDR)->mask_len = (MASKLEN); \ + } while (0) +#else /* WITH_IPV6 */ +#define __SSH_IP_MASK_DECODE(IPADDR,TYPE,BYTES,BYTELEN,MASKLEN) \ + do { \ + (IPADDR)->type = (TYPE); \ + memmove((IPADDR)->addr_data, (BYTES), (BYTELEN)); \ + (IPADDR)->mask_len = (MASKLEN); \ + } while (0) +#endif /* WITH_IPV6 */ + +/* Encode, that is copy from 'ipaddr' into 'bytes' and 'maskptr'. The + input 'ipaddr' needs to be of given 'type'. It is an fatal error + to call this for invalid address type. */ +#define __SSH_IP_MASK_ENCODE(IPADDR,TYPE,BYTES,BYTELEN,MASKPTR) \ + do { \ + SSH_VERIFY((IPADDR)->type == (TYPE)); \ + memmove((BYTES), (IPADDR)->addr_data, (BYTELEN)); \ + if (SSH_PREDICT_FALSE(MASKPTR)) \ + *((SshUInt32 *) (MASKPTR)) = (IPADDR)->mask_len; \ + } while (0) + +/* IPv4 Address manipulation */ +#define SSH_IP4_ENCODE(ip_addr,bytes) \ + __SSH_IP_MASK_ENCODE(ip_addr,SSH_IP_TYPE_IPV4,bytes,4,NULL) +#define SSH_IP4_DECODE(ip_addr,bytes) \ + __SSH_IP_MASK_DECODE(ip_addr,SSH_IP_TYPE_IPV4,bytes,4,32) + +/* IPv6 address manipulation */ +#define SSH_IP6_ENCODE(ip_addr,bytes) \ + __SSH_IP_MASK_ENCODE(ip_addr,SSH_IP_TYPE_IPV6,bytes,16,NULL) + +#if !defined(WITH_IPV6) +#define SSH_IP6_DECODE(ip_addr,bytes) SSH_IP_UNDEFINE(ip_addr) +#else /* WITH_IPV6 */ +#define SSH_IP6_DECODE(ip_addr,bytes) \ + __SSH_IP_MASK_DECODE(ip_addr,SSH_IP_TYPE_IPV6,bytes,16,128) +#endif /* !WITH_IPV6 */ + +#define SSH_IP_MASK_LEN(ip_addr) ((ip_addr)->mask_len) + +#if defined(WITH_IPV6) +#define SSH_IP6_SCOPE_ID(ip_addr) ((ip_addr)->scope_id.scope_id_union.ui32) +#endif /* WITH_IPV6 */ + +/*********************** Definitions for IPv4 packets ***********************/ + + +/* IPv4 header lengths. */ +#define SSH_IPH4_HDRLEN 20 +#define SSH_IPH4_HLEN(ucp) SSH_GET_4BIT_LOW(ucp) +#define SSH_IPH4_LEN(ucp) SSH_GET_16BIT((ucp) + 2) +#define SSH_IPH4_SRC(ipaddr, ucp) SSH_IP4_DECODE((ipaddr), (ucp) + 12) + +/*********************** Definitions for IPv6 packets ***********************/ + +/* IPv6 header length. Extension headers are not counted in IPv6 + header */ +#define SSH_IPH6_HDRLEN 40 + +#define SSH_IPH6_OFS_LEN 4 +#define SSH_IPH6_OFS_NH 6 + +#define SSH_IPH6_ADDRLEN 16 +#define SSH_IPH6_OFS_SRC 8 + +#define SSH_IP6_WORD0_TO_INT(ip_addr) SSH_GET_32BIT((ip_addr)->addr_data) +#define SSH_IP6_WORD1_TO_INT(ip_addr) SSH_GET_32BIT((ip_addr)->addr_data + 4) +#define SSH_IP6_WORD2_TO_INT(ip_addr) SSH_GET_32BIT((ip_addr)->addr_data + 8) +#define SSH_IP6_WORD3_TO_INT(ip_addr) SSH_GET_32BIT((ip_addr)->addr_data + 12) + +#define SSH_IPH6_LEN(ucp) SSH_GET_16BIT((ucp) + SSH_IPH6_OFS_LEN) +#define SSH_IPH6_NH(ucp) SSH_GET_8BIT((ucp) + SSH_IPH6_OFS_NH) +#define SSH_IPH6_SRC(ipaddr, ucp) SSH_IP6_DECODE((ipaddr), \ + (ucp) + SSH_IPH6_OFS_SRC) + +/****************** Definitions for IPv6 extension headers ******************/ + +#define SSH_IP6_EXT_COMMON_NH(ucp) SSH_GET_8BIT((ucp)) +#define SSH_IP6_EXT_COMMON_LEN(ucp) SSH_GET_8BIT((ucp) + 1) +#define SSH_IP6_EXT_COMMON_LENB(ucp) \ + ((SSH_IP6_EXT_COMMON_LEN((ucp)) + 1) << 3) + +/*************************** Link definitions *******************************/ + +/* Reserved value for invalid interface index. */ +#define SSH_INVALID_IFNUM 0xffffffff + +/***************************** Helper functions *****************************/ + +/* Sets all rightmost bits after keeping `keep_bits' bits on the left + to the value specified by `value'. */ +void ssh_ipaddr_set_bits(SshIpAddr result, SshIpAddr ip, + unsigned int keep_bits, unsigned int value); + +/* Prints the IP address into the buffer in string format. If the buffer + is too short, the address is truncated. This returns `buf'. */ +unsigned char *ssh_ipaddr_print(const SshIpAddr ip, unsigned char *buf, + size_t buflen); + +/* Prints the IP address into the buffer in string format. If the buffer + is too short, the address is truncated. This returns `buf'. */ +void ssh_ipaddr_ipv4_print(const unsigned char *data, + unsigned char *buf, size_t buflen); +void ssh_ipaddr_ipv6_print(const unsigned char *data, + unsigned char *buf, size_t buflen, + SshUInt32 scope); + +#endif /* SSHINET_H */ |