1 /*
2 ** sockaddr.h - Generic sockaddr_gen to handle multiple protocols
3 **
4 ** Copyright (c) 1999 Casper Dik <Casper.Dik@Holland.Sun.COM>
5 ** Copyright (c) 2000 Peter Eriksson <pen@lysator.liu.se>
6 **
7 ** This program is free software; you can redistribute it and/or
8 ** modify it as you wish - as long as you don't claim that you wrote
9 ** it.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 */
15 
16 #ifndef PLIB_SOCKADDR_H
17 #define PLIB_SOCKADDR_H
18 
19 #include "plib/config.h"
20 
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 
25 #ifdef HAVE_IPV6
26 
27 
28 /* XXX: Uuuhhh.. Maybe. Check this macros for portability! */
29 #ifndef IN6_V4MAPPED_TO_IPADDR
30 #define	IN6_V4MAPPED_TO_IPADDR(v6, v4) \
31 	(* ((unsigned long *) &(v4)) = ((unsigned long *) (v6))[3])
32 #endif
33 
34 
35 struct sockaddr_gen
36 {
37     union {
38 	struct sockaddr         _sg_sa;
39 	struct sockaddr_in      _sg_sin;
40 	struct sockaddr_in6     _sg_sin6;
41     } sg_addr;
42 };
43 
44 #define sg_sa           sg_addr._sg_sa
45 #define sg_sin          sg_addr._sg_sin
46 #define sg_family       sg_sa.sa_family
47 #define sg_sin6         sg_addr._sg_sin6
48 
49 #define SGFAM(sag)	((sag).sg_family)
50 #define SGSIZE(sag)	(SGFAM(sag) == AF_INET6 ? \
51 			    sizeof (struct in6_addr) : \
52 			    sizeof (struct in_addr))
53 #define SGSOCKSIZE(sag)	(SGFAM(sag) == AF_INET6 ? \
54 			    sizeof (struct sockaddr_in6) : \
55 			    sizeof (struct sockaddr_in))
56 #define SGPORT(sag)	(*(SGFAM(sag) == AF_INET6 ? \
57                             &(sag).sg_sin6.sin6_port : \
58 			    &(sag).sg_sin.sin_port))
59 #define SGADDRP(sag)	(SGFAM(sag) == AF_INET6 ? \
60                             (char *) &(sag).sg_sin6.sin6_addr : \
61 			    (char *) &(sag).sg_sin.sin_addr)
62 
63 #define SGINIT(sag)	(memset(&(sag), 0, sizeof((sag))), \
64 			((sag).sg_family = AF_INET6))
65 
66 
67 /* Some helper macros found on Solaris 2 */
68 #ifndef IN6_V4MAPPED_TO_INADDR
69 #define	IN6_V4MAPPED_TO_INADDR(v6, v4) \
70 	((v4)->s_addr = ((uint32_t *) (v6))[3])
71 #endif
72 
73 #ifndef IN6_V4MAPPED_TO_IPADDR
74 #define	IN6_V4MAPPED_TO_IPADDR(v6, v4) \
75 	((v4) = ((uint32_t *) (v6))[3])
76 #endif
77 
78 #else /* !HAVE_IPV6 */
79 
80 #define	sockaddr_gen	sockaddr_in
81 
82 #define SGFAM(sag)	((sag).sin_family)
83 #define SGSIZE(sag)	sizeof(struct in_addr)
84 #define SGSOCKSIZE(sag)	sizeof(struct sockaddr_in)
85 #define SGPORT(sag)	((sag).sin_port)
86 #define SGADDRP(sag)	((char *) &(sag).sin_addr)
87 
88 #define SGINIT(sag)	(memset(&(sag), 0, sizeof((sag))), \
89 			((sag).sin_family = AF_INET))
90 
91 #endif /* HAVE_IPV6 */
92 #endif
93