home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 March B / SCO_CASTOR4RRT.iso / update701 / root.18 / usr / include / convsa.h / convsa.h
Encoding:
C/C++ Source or Header  |  1998-08-18  |  11.8 KB  |  349 lines

  1. /*
  2.  * Copyright (c) 1998 The Santa Cruz Operation, Inc.. All Rights Reserved. 
  3.  *                                                                         
  4.  *        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF THE               
  5.  *                   SANTA CRUZ OPERATION INC.                             
  6.  *                                                                         
  7.  *   The copyright notice above does not evidence any actual or intended   
  8.  *   publication of such source code.                                      
  9.  */
  10.  
  11. #ifndef _CONVSA_H_
  12. #define _CONVSA_H_
  13.  
  14. #ident    "@(#)convsa.h    1.11"
  15. #ident    "$Header: $"
  16.  
  17. /*
  18.  * WARNING:
  19.  * Everything within this file is private, belonging to the networking
  20.  * subsystem.   The only garuantee about this file is that using it will
  21.  * spell disaster, since it and it's contents may change or disappear
  22.  * at whim.  You have been warned.
  23.  */
  24.  
  25. /*
  26.  * Must be included always, as it is where __NEW_SOCKADDR__ is either defined
  27.  * or undefined.
  28.  */
  29. #include <sys/convsa.h>
  30.  
  31. #ifdef __SOCKADDR_CONVERSION__
  32.  
  33. #include <sys/types.h>
  34. #include <sys/socket.h>
  35. #include <sys/cdefs.h>
  36. #include <stddef.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <memory.h>
  40.  
  41. /*
  42.  * Maximum entries in _convsa_t
  43.  */
  44. #define MAXOFFSA        16
  45.  
  46. /*
  47.  * flags for convert_sockaddr()
  48.  */
  49. #define CONVERT_TO_SOCKADDR    0x01    /* make new style sockaddr */
  50. #define CONVERT_TO_OLD_SOCKADDR    0x02    /* make old style sockaddr */
  51. #define CONVERT_CHECK        0x04    /* only count for conversions */
  52. #define CONVERT_SET_SALEN    0x08    /* force set sa_len to correct value */
  53. /*
  54.  * copy arguments to _sockaddr_convert()
  55.  */
  56. #define COPY_NONE        0    /* do not make a copy */
  57. #define COPY_ON_STACK        1    /* allocate a copy on stack first */
  58. #define COPY_BY_MALLOC        2    /* allocate a copy in memory first */
  59.  
  60. /*
  61.  * _offsa_t type values
  62.  */
  63. #define OST_SOCKADDR        0    /* an actual sockaddr */
  64. #define OST_SUBSTRUCT        1    /* another convsa_t pointer */
  65. #define OST_SUBSTRUCT_ARRAY    2    /* another convsa_t pointer in an
  66.                      * array, size is the offset from
  67.                      * the structure start of an int
  68.                      * specifying the size of the array
  69.                      */
  70.  
  71. /*
  72.  * Describes an offset, type and size of a structure member
  73.  */
  74. typedef struct _offsa {
  75.     size_t        offset;        /* offset of member */
  76.     int        type;        /* type of member */
  77.     size_t        size;         /* the size of the member */
  78.     struct _convsa *substruct;    /* sub-structure definition */
  79. } _offsa_t;
  80.  
  81. /*
  82.  * Describes a structure containing sockaddrs.
  83.  */
  84. typedef struct _convsa {
  85.     char *        name;        /* the name of the structure */
  86.     size_t        size;        /* the size of the structure */
  87.     size_t        minsize;    /* the minimum size of the structure */
  88.     int        noffsa;        /* number of members described */
  89.     _offsa_t    offsa[MAXOFFSA];/* member offset */
  90. } _convsa_t;
  91.  
  92. /*
  93.  * Short hand for defining structures.
  94.  */
  95. #define _CONVSA_DEFINE_0(sname) \
  96. _convsa_t _convsa_##sname = { #sname, sizeof(struct sname),            \
  97.                   sizeof(struct sname), 1,                \
  98.                   { { 0, OST_SOCKADDR, sizeof(struct sname) } } }
  99.  
  100. #define _CONVSA_DEFINE_0_MIN(sname, lastmem) \
  101. _convsa_t _convsa_##sname = { #sname, sizeof(struct sname),            \
  102.                   offsetof(struct sname, lastmem) +            \
  103.                   sizeof(((struct sname *)0)->lastmem),        \
  104.                   1,                        \
  105.                   { { 0, OST_SOCKADDR, offsetof(struct sname,   \
  106.                                 lastmem)        \
  107.                   + sizeof(((struct sname *)0)->lastmem) } } }
  108.  
  109. #define _CONVSA_DEFINE_1(sname, f1t, f1n) \
  110. _convsa_t _convsa_##sname = { #sname, sizeof(struct sname),            \
  111.                   sizeof(struct sname), 1,                \
  112.                   { { offsetof(struct sname, f1n), OST_SOCKADDR,\
  113.                   sizeof(struct f1t) } } }
  114.  
  115. #define _CONVSA_DEFINE_2(sname, f1t, f1n, f2t, f2n) \
  116. _convsa_t _convsa_##sname = { #sname, sizeof(struct sname),            \
  117.                   sizeof(struct sname), 2,                \
  118.                   { { offsetof(struct sname, f1n), OST_SOCKADDR,\
  119.                   sizeof(struct f1t) },                \
  120.                 { offsetof(struct sname, f2n), OST_SOCKADDR,\
  121.                   sizeof(struct f2t) } } }
  122.  
  123. #define _CONVSA_DEFINE_3(sname, f1t, f1n, f2t, f2n, f3t, f3n) \
  124. _convsa_t _convsa_##sname = { #sname, sizeof(struct sname),            \
  125.                   sizeof(struct sname), 3,                \
  126.                   { { offsetof(struct sname, f1n), OST_SOCKADDR,\
  127.                   sizeof(struct f1t) },                \
  128.                 { offsetof(struct sname, f2n), OST_SOCKADDR,\
  129.                   sizeof(struct f2t) },                \
  130.                 { offsetof(struct sname, f3n), OST_SOCKADDR,\
  131.                   sizeof(struct f3t) } } }
  132. /*
  133.  * Short hand for definition structure arrays.
  134.  * 
  135.  * sname    The name of the structure
  136.  * lastmem    The last member of this structure that must appear
  137.  * a1lenn    The name of the array length integer member
  138.  * a1t        The struct type of the array
  139.  * a1m        The name of the struct array member
  140.  */
  141. #define _CONVSA_DEFINE_1_SA(sname, lastmem, a1lenn, a1t, a1n) \
  142. _convsa_t _convsa_##sname = { #sname, sizeof(struct sname),            \
  143.                   offsetof(struct sname, lastmem) +            \
  144.                   sizeof(((struct sname *)0)->lastmem),        \
  145.                   1,                        \
  146.                   { { offsetof(struct sname, a1n),            \
  147.                   OST_SUBSTRUCT_ARRAY,                \
  148.                   offsetof(struct sname, a1lenn),        \
  149.                   &_convsa_##a1t } } }
  150.  
  151. __BEGIN_DECLS
  152.  
  153. /*
  154.  * Standard definitions
  155.  */
  156. extern _convsa_t    _convsa_sockaddr;
  157. extern _convsa_t    _convsa_sockaddr_in;
  158. extern _convsa_t    _convsa_sockaddr_un;
  159. extern _convsa_t    _convsa_sockaddr_in6;
  160. extern _convsa_t    _convsa_sockaddr_dl;
  161. extern _convsa_t    _convsa_sockaddr_inarp;
  162. extern _convsa_t    _convsa_ifreq;
  163. extern _convsa_t    _convsa_ifaliasreq;
  164. extern _convsa_t    _convsa_ortentry;
  165. extern _convsa_t    _convsa_arpreq;
  166. extern _convsa_t    _convsa_all_addrs;
  167. extern _convsa_t    _convsa_ifreq_all;
  168.  
  169. /*
  170.  * Support conversion functions
  171.  */
  172. extern size_t    _sockaddr_size __P((const struct sockaddr *, size_t));
  173. extern int    _sockaddr_convert __P((void *, size_t, const _convsa_t *,
  174.                        int, int));
  175.  
  176. __END_DECLS
  177.  
  178. #ifndef MAX
  179. #define MAX(a,b)    ((a) > (b) ? (a) : (b))
  180. #endif
  181. #ifndef MIN
  182. #define MIN(a,b)    ((a) < (b) ? (a) : (b))
  183. #endif
  184.  
  185. /*
  186.  * These help write macro which can be included correctly wherever a statement
  187.  * can be.
  188.  */
  189. #define _MACRO_(CODE) if(1) { CODE } else
  190.  
  191. /*
  192.  * See _sockaddr_convert().  This macro must be used such that COPY_ON_STACK
  193.  * works correctly.  FAIL must be a statement which never returns such as
  194.  * return -1, or { error("failed"); goto failure_code; }.
  195.  * 
  196.  * When doing a COPY_ON_STACK or COPY_BY_MALLOC we allocate one byte more
  197.  * than we need; this is because for AF_UNIX sockaddr_un, many applications
  198.  * forget to include the zero terminating byte count in the length.  This
  199.  * saves us from that problem by always having the spare position to place
  200.  * the terminating zero byte back in (done by the socket library code, not
  201.  * the conversion routines).
  202.  * 
  203.  * NOTE:  This macro, and derived macros require a version of alloca.  One
  204.  * can be provided inline using the exceedingly delightful and obscure
  205.  * flag -W0,-2A1 to cc(1).  Failure to do this will result in linker errors
  206.  * on alloca not being defined.
  207.  */
  208. #ifdef __CONVSA_DEBUG__
  209. extern const char *    _sockaddr_convert_file;
  210. extern int        _sockaddr_convert_line;
  211. extern int        _sockaddr_convert_version;
  212. #define _CALL_SOCKADDR_CONVERT(a1,a2,a3,a4,a5) \
  213.     (_sockaddr_convert_file = __FILE__, \
  214.      _sockaddr_convert_line = __LINE__, \
  215.      _sockaddr_convert_version = __version__, \
  216.      _sockaddr_convert((a1),(a2),(a3),(a4),(a5)))
  217. #else
  218. #define _CALL_SOCKADDR_CONVERT(a1,a2,a3,a4,a5) \
  219.     _sockaddr_convert((a1),(a2),(a3),(a4),(a5))
  220. #endif
  221.  
  222. #define _SOCKADDR_CONVERT(ptr, size, def, flags, type, FAIL) \
  223. if (ptr) {                                    \
  224.     void *__sc_ptrcopy = (void *)(ptr);                    \
  225.     size_t __sc_asize = MAX((def)->minsize, (size));            \
  226.                                         \
  227.     if ((type) == COPY_ON_STACK) {                        \
  228.         __sc_ptrcopy = (void *)alloca(__sc_asize + 1);            \
  229.         (ptr) = memcpy(__sc_ptrcopy, (void *)(ptr), (__sc_asize));  \
  230.         ((char *)__sc_ptrcopy)[__sc_asize] = 0;                \
  231.     } else if ((type) == COPY_BY_MALLOC) {                    \
  232.         if ((__sc_ptrcopy = malloc(__sc_asize + 1)) == NULL)        \
  233.             _MACRO_(FAIL);                        \
  234.         (ptr) = memcpy(__sc_ptrcopy, (void *)(ptr), (__sc_asize));  \
  235.         ((char *)__sc_ptrcopy)[__sc_asize] = 0;                \
  236.     }                                    \
  237.     if (_CALL_SOCKADDR_CONVERT((void *)(ptr), (__sc_asize), (def),        \
  238.                    (flags), (type)) == -1)            \
  239.         _MACRO_(FAIL);                            \
  240. } else
  241.  
  242. /*
  243.  * Make sure `s', which is `slen' long and has definition `def', contains
  244.  * valid new style sockaddrs.  Only if we are not using new sockaddrs.
  245.  *
  246.  * If `type' is; COPY_NONE this macro may modify the contents of `s',
  247.  *         COPY_ON_STACK a copy is made on the stack, and `s' is
  248.  *            modified to point to this.
  249.  *         COPY_BY_MALLOC a copy is made using malloc, and `s' is
  250.  *             modified to point to this.
  251.  *            
  252.  * Note: For this macro, the length fields are set to the correct value if
  253.  *       already running with new style sockaddrs.
  254.  */
  255. #define FORCE_TO_SOCKADDRS(s, slen, def, type, FAIL) \
  256.     _SOCKADDR_CONVERT((s), (slen), (def), CONVERT_TO_SOCKADDR|        \
  257.               CONVERT_SET_SALEN, (type), FAIL)
  258.  
  259.  
  260. /*
  261.  * Make sure `s', which is `slen' long and has definition `def', contains
  262.  * valid old style sockaddrs.  Only if we are using new sockaddrs.
  263.  */
  264. #define FORCE_TO_OLD_SOCKADDRS(s, slen, def, type, FAIL) \
  265. _MACRO_(                                    \
  266.     if (__USE_NEW_SOCKADDR__()) {                        \
  267.         _SOCKADDR_CONVERT((s), (slen), (def),                \
  268.                   CONVERT_TO_OLD_SOCKADDR, (type), FAIL);   \
  269.     }                                    \
  270. )
  271.  
  272. /*
  273.  * Make sure `s', which is `slen' long and has definition `def', contains
  274.  * the currently used style of sockaddr, given that it currently is a new
  275.  * style sockaddr.
  276.  */
  277. #define FORCE_FROM_SOCKADDRS(s, slen, def, type, FAIL) \
  278. _MACRO_(                                    \
  279.     if (!__USE_NEW_SOCKADDR__()) {                        \
  280.         _SOCKADDR_CONVERT((s), (slen), (def),                \
  281.                   CONVERT_TO_OLD_SOCKADDR, (type), FAIL);   \
  282.     }                                    \
  283. )
  284.  
  285. /*
  286.  * Make sure `s', which is `slen' long and has definition `def', contains
  287.  * the currently used style of sockaddr, given that it currently is an old 
  288.  * style sockaddr.
  289.  */
  290. #define FORCE_FROM_OLD_SOCKADDRS(s, slen, def, type, FAIL) \
  291. _MACRO_(                                    \
  292.     if (__USE_NEW_SOCKADDR__()) {                        \
  293.         _SOCKADDR_CONVERT((s), (slen), (def), CONVERT_TO_SOCKADDR,  \
  294.                  (type), FAIL);                    \
  295.     }                                    \
  296. )
  297.  
  298. #else /* !__SOCKADDR_CONVERSION__ */
  299.  
  300. #define _SOCKADDR_CONVERT(ptr, size, def, flags, type, FAIL) ((void)0)
  301.  
  302. #define FORCE_TO_SOCKADDRS(s, slen, def, type, FAIL) ((void)0)
  303. #define FORCE_TO_OLD_SOCKADDRS(s, slen, def, type, FAIL) ((void)0)
  304. #define FORCE_FROM_SOCKADDRS(s, slen, def, type, FAIL) ((void)0)
  305. #define FORCE_FROM_OLD_SOCKADDRS(s, slen, def, type, FAIL) ((void)0)
  306.  
  307. #endif /* __SOCKADDR_CONVERSION__ */
  308.  
  309. /*
  310.  * Short hand macros for taking or returning given structures which contain
  311.  * sockaddrs.  These functions will convert to or from the application's
  312.  * style of sockaddr to the kernel/libraries idea of a sockaddr.
  313.  */
  314. #if !defined(GEMINI_ON_OSR5) && !defined(GEMINI_ON_UW2)
  315. #define RETURNED_STRUCT(sname, s, slen, type) \
  316.     FORCE_FROM_SOCKADDRS((s), (slen), \
  317.                  &_convsa_##sname, (type), return -1;)
  318.  
  319. #define TAKE_STRUCT(sname, s, slen, type) \
  320.     FORCE_TO_SOCKADDRS((s), (slen), \
  321.                &_convsa_##sname, (type), return -1;)
  322.  
  323. #define RETURNED_STRUCT_FAIL(sname, s, slen, type, FAIL) \
  324.     FORCE_FROM_SOCKADDRS((s), (slen), \
  325.                  &_convsa_##sname, (type), FAIL)
  326.  
  327. #define TAKE_STRUCT_FAIL(sname, s, slen, type, FAIL) \
  328.     FORCE_TO_SOCKADDRS((s), (slen), \
  329.                &_convsa_##sname, (type), FAIL)
  330. #else /* defined(GEMINI_ON_OSR5) || defined(GEMINI_ON_UW2) */
  331. #define RETURNED_STRUCT(sname, s, slen, type) \
  332.     FORCE_FROM_OLD_SOCKADDRS((s), (slen), \
  333.                  &_convsa_##sname, (type), return -1;)
  334.  
  335. #define TAKE_STRUCT(sname, s, slen, type) \
  336.     FORCE_TO_OLD_SOCKADDRS((s), (slen), \
  337.                    &_convsa_##sname, (type), return -1;)
  338.  
  339. #define RETURNED_STRUCT_FAIL(sname, s, slen, type, FAIL) \
  340.     FORCE_FROM_OLD_SOCKADDRS((s), (slen), \
  341.                  &_convsa_##sname, (type), FAIL)
  342.  
  343. #define TAKE_STRUCT_FAIL(sname, s, slen, type, FAIL) \
  344.     FORCE_TO_OLD_SOCKADDRS((s), (slen), \
  345.                    &_convsa_##sname, (type), FAIL)
  346. #endif /* !defined(GEMINI_ON_OSR5) && !defined(GEMINI_ON_UW2) */
  347.  
  348. #endif /* _CONVSA_H_ */
  349.