home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1998 The Santa Cruz Operation, Inc.. All Rights Reserved.
- *
- * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF THE
- * SANTA CRUZ OPERATION INC.
- *
- * The copyright notice above does not evidence any actual or intended
- * publication of such source code.
- */
-
- #ifndef _CONVSA_H_
- #define _CONVSA_H_
-
- #ident "@(#)convsa.h 1.11"
- #ident "$Header: $"
-
- /*
- * WARNING:
- * Everything within this file is private, belonging to the networking
- * subsystem. The only garuantee about this file is that using it will
- * spell disaster, since it and it's contents may change or disappear
- * at whim. You have been warned.
- */
-
- /*
- * Must be included always, as it is where __NEW_SOCKADDR__ is either defined
- * or undefined.
- */
- #include <sys/convsa.h>
-
- #ifdef __SOCKADDR_CONVERSION__
-
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/cdefs.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
- #include <memory.h>
-
- /*
- * Maximum entries in _convsa_t
- */
- #define MAXOFFSA 16
-
- /*
- * flags for convert_sockaddr()
- */
- #define CONVERT_TO_SOCKADDR 0x01 /* make new style sockaddr */
- #define CONVERT_TO_OLD_SOCKADDR 0x02 /* make old style sockaddr */
- #define CONVERT_CHECK 0x04 /* only count for conversions */
- #define CONVERT_SET_SALEN 0x08 /* force set sa_len to correct value */
- /*
- * copy arguments to _sockaddr_convert()
- */
- #define COPY_NONE 0 /* do not make a copy */
- #define COPY_ON_STACK 1 /* allocate a copy on stack first */
- #define COPY_BY_MALLOC 2 /* allocate a copy in memory first */
-
- /*
- * _offsa_t type values
- */
- #define OST_SOCKADDR 0 /* an actual sockaddr */
- #define OST_SUBSTRUCT 1 /* another convsa_t pointer */
- #define OST_SUBSTRUCT_ARRAY 2 /* another convsa_t pointer in an
- * array, size is the offset from
- * the structure start of an int
- * specifying the size of the array
- */
-
- /*
- * Describes an offset, type and size of a structure member
- */
- typedef struct _offsa {
- size_t offset; /* offset of member */
- int type; /* type of member */
- size_t size; /* the size of the member */
- struct _convsa *substruct; /* sub-structure definition */
- } _offsa_t;
-
- /*
- * Describes a structure containing sockaddrs.
- */
- typedef struct _convsa {
- char * name; /* the name of the structure */
- size_t size; /* the size of the structure */
- size_t minsize; /* the minimum size of the structure */
- int noffsa; /* number of members described */
- _offsa_t offsa[MAXOFFSA];/* member offset */
- } _convsa_t;
-
- /*
- * Short hand for defining structures.
- */
- #define _CONVSA_DEFINE_0(sname) \
- _convsa_t _convsa_##sname = { #sname, sizeof(struct sname), \
- sizeof(struct sname), 1, \
- { { 0, OST_SOCKADDR, sizeof(struct sname) } } }
-
- #define _CONVSA_DEFINE_0_MIN(sname, lastmem) \
- _convsa_t _convsa_##sname = { #sname, sizeof(struct sname), \
- offsetof(struct sname, lastmem) + \
- sizeof(((struct sname *)0)->lastmem), \
- 1, \
- { { 0, OST_SOCKADDR, offsetof(struct sname, \
- lastmem) \
- + sizeof(((struct sname *)0)->lastmem) } } }
-
- #define _CONVSA_DEFINE_1(sname, f1t, f1n) \
- _convsa_t _convsa_##sname = { #sname, sizeof(struct sname), \
- sizeof(struct sname), 1, \
- { { offsetof(struct sname, f1n), OST_SOCKADDR,\
- sizeof(struct f1t) } } }
-
- #define _CONVSA_DEFINE_2(sname, f1t, f1n, f2t, f2n) \
- _convsa_t _convsa_##sname = { #sname, sizeof(struct sname), \
- sizeof(struct sname), 2, \
- { { offsetof(struct sname, f1n), OST_SOCKADDR,\
- sizeof(struct f1t) }, \
- { offsetof(struct sname, f2n), OST_SOCKADDR,\
- sizeof(struct f2t) } } }
-
- #define _CONVSA_DEFINE_3(sname, f1t, f1n, f2t, f2n, f3t, f3n) \
- _convsa_t _convsa_##sname = { #sname, sizeof(struct sname), \
- sizeof(struct sname), 3, \
- { { offsetof(struct sname, f1n), OST_SOCKADDR,\
- sizeof(struct f1t) }, \
- { offsetof(struct sname, f2n), OST_SOCKADDR,\
- sizeof(struct f2t) }, \
- { offsetof(struct sname, f3n), OST_SOCKADDR,\
- sizeof(struct f3t) } } }
- /*
- * Short hand for definition structure arrays.
- *
- * sname The name of the structure
- * lastmem The last member of this structure that must appear
- * a1lenn The name of the array length integer member
- * a1t The struct type of the array
- * a1m The name of the struct array member
- */
- #define _CONVSA_DEFINE_1_SA(sname, lastmem, a1lenn, a1t, a1n) \
- _convsa_t _convsa_##sname = { #sname, sizeof(struct sname), \
- offsetof(struct sname, lastmem) + \
- sizeof(((struct sname *)0)->lastmem), \
- 1, \
- { { offsetof(struct sname, a1n), \
- OST_SUBSTRUCT_ARRAY, \
- offsetof(struct sname, a1lenn), \
- &_convsa_##a1t } } }
-
- __BEGIN_DECLS
-
- /*
- * Standard definitions
- */
- extern _convsa_t _convsa_sockaddr;
- extern _convsa_t _convsa_sockaddr_in;
- extern _convsa_t _convsa_sockaddr_un;
- extern _convsa_t _convsa_sockaddr_in6;
- extern _convsa_t _convsa_sockaddr_dl;
- extern _convsa_t _convsa_sockaddr_inarp;
- extern _convsa_t _convsa_ifreq;
- extern _convsa_t _convsa_ifaliasreq;
- extern _convsa_t _convsa_ortentry;
- extern _convsa_t _convsa_arpreq;
- extern _convsa_t _convsa_all_addrs;
- extern _convsa_t _convsa_ifreq_all;
-
- /*
- * Support conversion functions
- */
- extern size_t _sockaddr_size __P((const struct sockaddr *, size_t));
- extern int _sockaddr_convert __P((void *, size_t, const _convsa_t *,
- int, int));
-
- __END_DECLS
-
- #ifndef MAX
- #define MAX(a,b) ((a) > (b) ? (a) : (b))
- #endif
- #ifndef MIN
- #define MIN(a,b) ((a) < (b) ? (a) : (b))
- #endif
-
- /*
- * These help write macro which can be included correctly wherever a statement
- * can be.
- */
- #define _MACRO_(CODE) if(1) { CODE } else
-
- /*
- * See _sockaddr_convert(). This macro must be used such that COPY_ON_STACK
- * works correctly. FAIL must be a statement which never returns such as
- * return -1, or { error("failed"); goto failure_code; }.
- *
- * When doing a COPY_ON_STACK or COPY_BY_MALLOC we allocate one byte more
- * than we need; this is because for AF_UNIX sockaddr_un, many applications
- * forget to include the zero terminating byte count in the length. This
- * saves us from that problem by always having the spare position to place
- * the terminating zero byte back in (done by the socket library code, not
- * the conversion routines).
- *
- * NOTE: This macro, and derived macros require a version of alloca. One
- * can be provided inline using the exceedingly delightful and obscure
- * flag -W0,-2A1 to cc(1). Failure to do this will result in linker errors
- * on alloca not being defined.
- */
- #ifdef __CONVSA_DEBUG__
- extern const char * _sockaddr_convert_file;
- extern int _sockaddr_convert_line;
- extern int _sockaddr_convert_version;
- #define _CALL_SOCKADDR_CONVERT(a1,a2,a3,a4,a5) \
- (_sockaddr_convert_file = __FILE__, \
- _sockaddr_convert_line = __LINE__, \
- _sockaddr_convert_version = __version__, \
- _sockaddr_convert((a1),(a2),(a3),(a4),(a5)))
- #else
- #define _CALL_SOCKADDR_CONVERT(a1,a2,a3,a4,a5) \
- _sockaddr_convert((a1),(a2),(a3),(a4),(a5))
- #endif
-
- #define _SOCKADDR_CONVERT(ptr, size, def, flags, type, FAIL) \
- if (ptr) { \
- void *__sc_ptrcopy = (void *)(ptr); \
- size_t __sc_asize = MAX((def)->minsize, (size)); \
- \
- if ((type) == COPY_ON_STACK) { \
- __sc_ptrcopy = (void *)alloca(__sc_asize + 1); \
- (ptr) = memcpy(__sc_ptrcopy, (void *)(ptr), (__sc_asize)); \
- ((char *)__sc_ptrcopy)[__sc_asize] = 0; \
- } else if ((type) == COPY_BY_MALLOC) { \
- if ((__sc_ptrcopy = malloc(__sc_asize + 1)) == NULL) \
- _MACRO_(FAIL); \
- (ptr) = memcpy(__sc_ptrcopy, (void *)(ptr), (__sc_asize)); \
- ((char *)__sc_ptrcopy)[__sc_asize] = 0; \
- } \
- if (_CALL_SOCKADDR_CONVERT((void *)(ptr), (__sc_asize), (def), \
- (flags), (type)) == -1) \
- _MACRO_(FAIL); \
- } else
-
- /*
- * Make sure `s', which is `slen' long and has definition `def', contains
- * valid new style sockaddrs. Only if we are not using new sockaddrs.
- *
- * If `type' is; COPY_NONE this macro may modify the contents of `s',
- * COPY_ON_STACK a copy is made on the stack, and `s' is
- * modified to point to this.
- * COPY_BY_MALLOC a copy is made using malloc, and `s' is
- * modified to point to this.
- *
- * Note: For this macro, the length fields are set to the correct value if
- * already running with new style sockaddrs.
- */
- #define FORCE_TO_SOCKADDRS(s, slen, def, type, FAIL) \
- _SOCKADDR_CONVERT((s), (slen), (def), CONVERT_TO_SOCKADDR| \
- CONVERT_SET_SALEN, (type), FAIL)
-
-
- /*
- * Make sure `s', which is `slen' long and has definition `def', contains
- * valid old style sockaddrs. Only if we are using new sockaddrs.
- */
- #define FORCE_TO_OLD_SOCKADDRS(s, slen, def, type, FAIL) \
- _MACRO_( \
- if (__USE_NEW_SOCKADDR__()) { \
- _SOCKADDR_CONVERT((s), (slen), (def), \
- CONVERT_TO_OLD_SOCKADDR, (type), FAIL); \
- } \
- )
-
- /*
- * Make sure `s', which is `slen' long and has definition `def', contains
- * the currently used style of sockaddr, given that it currently is a new
- * style sockaddr.
- */
- #define FORCE_FROM_SOCKADDRS(s, slen, def, type, FAIL) \
- _MACRO_( \
- if (!__USE_NEW_SOCKADDR__()) { \
- _SOCKADDR_CONVERT((s), (slen), (def), \
- CONVERT_TO_OLD_SOCKADDR, (type), FAIL); \
- } \
- )
-
- /*
- * Make sure `s', which is `slen' long and has definition `def', contains
- * the currently used style of sockaddr, given that it currently is an old
- * style sockaddr.
- */
- #define FORCE_FROM_OLD_SOCKADDRS(s, slen, def, type, FAIL) \
- _MACRO_( \
- if (__USE_NEW_SOCKADDR__()) { \
- _SOCKADDR_CONVERT((s), (slen), (def), CONVERT_TO_SOCKADDR, \
- (type), FAIL); \
- } \
- )
-
- #else /* !__SOCKADDR_CONVERSION__ */
-
- #define _SOCKADDR_CONVERT(ptr, size, def, flags, type, FAIL) ((void)0)
-
- #define FORCE_TO_SOCKADDRS(s, slen, def, type, FAIL) ((void)0)
- #define FORCE_TO_OLD_SOCKADDRS(s, slen, def, type, FAIL) ((void)0)
- #define FORCE_FROM_SOCKADDRS(s, slen, def, type, FAIL) ((void)0)
- #define FORCE_FROM_OLD_SOCKADDRS(s, slen, def, type, FAIL) ((void)0)
-
- #endif /* __SOCKADDR_CONVERSION__ */
-
- /*
- * Short hand macros for taking or returning given structures which contain
- * sockaddrs. These functions will convert to or from the application's
- * style of sockaddr to the kernel/libraries idea of a sockaddr.
- */
- #if !defined(GEMINI_ON_OSR5) && !defined(GEMINI_ON_UW2)
- #define RETURNED_STRUCT(sname, s, slen, type) \
- FORCE_FROM_SOCKADDRS((s), (slen), \
- &_convsa_##sname, (type), return -1;)
-
- #define TAKE_STRUCT(sname, s, slen, type) \
- FORCE_TO_SOCKADDRS((s), (slen), \
- &_convsa_##sname, (type), return -1;)
-
- #define RETURNED_STRUCT_FAIL(sname, s, slen, type, FAIL) \
- FORCE_FROM_SOCKADDRS((s), (slen), \
- &_convsa_##sname, (type), FAIL)
-
- #define TAKE_STRUCT_FAIL(sname, s, slen, type, FAIL) \
- FORCE_TO_SOCKADDRS((s), (slen), \
- &_convsa_##sname, (type), FAIL)
- #else /* defined(GEMINI_ON_OSR5) || defined(GEMINI_ON_UW2) */
- #define RETURNED_STRUCT(sname, s, slen, type) \
- FORCE_FROM_OLD_SOCKADDRS((s), (slen), \
- &_convsa_##sname, (type), return -1;)
-
- #define TAKE_STRUCT(sname, s, slen, type) \
- FORCE_TO_OLD_SOCKADDRS((s), (slen), \
- &_convsa_##sname, (type), return -1;)
-
- #define RETURNED_STRUCT_FAIL(sname, s, slen, type, FAIL) \
- FORCE_FROM_OLD_SOCKADDRS((s), (slen), \
- &_convsa_##sname, (type), FAIL)
-
- #define TAKE_STRUCT_FAIL(sname, s, slen, type, FAIL) \
- FORCE_TO_OLD_SOCKADDRS((s), (slen), \
- &_convsa_##sname, (type), FAIL)
- #endif /* !defined(GEMINI_ON_OSR5) && !defined(GEMINI_ON_UW2) */
-
- #endif /* _CONVSA_H_ */
-