Home | History | Annotate | Line # | Download | only in xdm
      1 /*
      2 
      3 Copyright 1991, 1998  The Open Group
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included
     12 in all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 OTHER DEALINGS IN THE SOFTWARE.
     21 
     22 Except as contained in this notice, the name of The Open Group shall
     23 not be used in advertising or otherwise to promote the sale, use or
     24 other dealings in this Software without prior written authorization
     25 from The Open Group.
     26 
     27 */
     28 
     29 /*
     30  * xdm - X display manager
     31  *
     32  * netaddr.c - Interpretation of XdmcpNetaddr object.
     33  */
     34 
     35 #include "dm.h"
     36 #include "dm_error.h"
     37 
     38 #include <X11/X.h>		/* FamilyInternet, etc. */
     39 
     40 #ifdef XDMCP
     41 
     42 # include "dm_socket.h"
     43 
     44 # ifdef IPv6
     45 #  include        <arpa/inet.h>
     46 # endif
     47 
     48 # ifdef UNIXCONN
     49 #  include <sys/un.h>		/* struct sockaddr_un */
     50 # endif
     51 
     52 /* given an XdmcpNetaddr, returns the socket protocol family used,
     53    e.g., AF_INET */
     54 
     55 int NetaddrFamily(XdmcpNetaddr netaddrp)
     56 {
     57     return ((struct sockaddr *)netaddrp)->sa_family;
     58 }
     59 
     60 
     61 /* given an XdmcpNetaddr, returns a pointer to the TCP/UDP port used
     62    and sets *lenp to the length of the address
     63    or 0 if not using TCP or UDP. */
     64 
     65 char * NetaddrPort(XdmcpNetaddr netaddrp, int *lenp)
     66 {
     67     switch (NetaddrFamily(netaddrp))
     68     {
     69     case AF_INET:
     70 	*lenp = 2;
     71 	return (char *)&(((struct sockaddr_in *)netaddrp)->sin_port);
     72 # ifdef IPv6
     73     case AF_INET6:
     74 	*lenp = 2;
     75 	return (char *)&(((struct sockaddr_in6 *)netaddrp)->sin6_port);
     76 # endif
     77     default:
     78 	*lenp = 0;
     79 	return NULL;
     80     }
     81 }
     82 
     83 
     84 /* given an XdmcpNetaddr, returns a pointer to the network address
     85    and sets *lenp to the length of the address */
     86 
     87 char * NetaddrAddress(XdmcpNetaddr netaddrp, int *lenp)
     88 {
     89     switch (NetaddrFamily(netaddrp)) {
     90 # ifdef UNIXCONN
     91     case AF_UNIX:
     92 	*lenp = strlen(((struct sockaddr_un *)netaddrp)->sun_path);
     93         return (char *) (((struct sockaddr_un *)netaddrp)->sun_path);
     94 # endif
     95 # ifdef TCPCONN
     96     case AF_INET:
     97         *lenp = sizeof (struct in_addr);
     98         return (char *) &(((struct sockaddr_in *)netaddrp)->sin_addr);
     99 #  ifdef IPv6
    100     case AF_INET6:
    101     {
    102 	struct in6_addr *a = &(((struct sockaddr_in6 *)netaddrp)->sin6_addr);
    103 	if (IN6_IS_ADDR_V4MAPPED(a)) {
    104 	    *lenp = sizeof (struct in_addr);
    105 	    return ((char *) &(a->s6_addr))+12;
    106 	} else {
    107 	    *lenp = sizeof (struct in6_addr);
    108 	    return (char *) &(a->s6_addr);
    109 	}
    110     }
    111 #  endif
    112 # endif
    113     default:
    114 	*lenp = 0;
    115 	return NULL;
    116     }
    117 }
    118 
    119 
    120 /* given an XdmcpNetaddr, sets *addr to the network address used and
    121    sets *len to the number of bytes in addr.
    122    Returns the X protocol family used, e.g., FamilyInternet */
    123 
    124 int ConvertAddr (XdmcpNetaddr saddr, int *len, char **addr)
    125 {
    126     int retval;
    127 
    128     if ((len == NULL) || (saddr == NULL))
    129         return -1;
    130     *addr = NetaddrAddress(saddr, len);
    131     switch (NetaddrFamily(saddr))
    132     {
    133 # ifdef AF_UNSPEC
    134       case AF_UNSPEC:
    135 	retval = FamilyLocal;
    136 	break;
    137 # endif
    138 # ifdef AF_UNIX
    139       case AF_UNIX:
    140         retval = FamilyLocal;
    141 	break;
    142 # endif
    143 # ifdef TCPCONN
    144       case AF_INET:
    145         retval = FamilyInternet;
    146 	break;
    147 #  ifdef IPv6
    148       case AF_INET6:
    149 	if (*len == sizeof(struct in_addr))
    150 	    retval = FamilyInternet;
    151 	else
    152 	    retval = FamilyInternet6;
    153 	break;
    154 #  endif
    155 # endif
    156       default:
    157 	retval = -1;
    158         break;
    159     }
    160     Debug ("ConvertAddr returning %d for family %d\n", retval,
    161 	   NetaddrFamily(saddr));
    162     return retval;
    163 }
    164 
    165 int
    166 addressEqual (XdmcpNetaddr a1, int len1, XdmcpNetaddr a2, int len2)
    167 {
    168     int partlen1, partlen2;
    169     char *part1, *part2;
    170 
    171     if (len1 != len2)
    172     {
    173 	return FALSE;
    174     }
    175     if (NetaddrFamily(a1) != NetaddrFamily(a2))
    176     {
    177 	return FALSE;
    178     }
    179     part1 = NetaddrPort(a1, &partlen1);
    180     part2 = NetaddrPort(a2, &partlen2);
    181     if (partlen1 != partlen2 || memcmp(part1, part2, partlen1) != 0)
    182     {
    183 	return FALSE;
    184     }
    185     part1 = NetaddrAddress(a1, &partlen1);
    186     part2 = NetaddrAddress(a2, &partlen2);
    187     if (partlen1 != partlen2 || memcmp(part1, part2, partlen1) != 0)
    188     {
    189 	return FALSE;
    190     }
    191     return TRUE;
    192 }
    193 
    194 # ifdef DEBUG
    195 /*ARGSUSED*/
    196 void
    197 PrintSockAddr (struct sockaddr *a, int len)
    198 {
    199     unsigned char    *t, *p;
    200 
    201     Debug ("family %d, ", a->sa_family);
    202     switch (a->sa_family) {
    203 #  ifdef AF_INET
    204     case AF_INET:
    205 
    206 	p = (unsigned char *) &((struct sockaddr_in *) a)->sin_port;
    207 	t = (unsigned char *) &((struct sockaddr_in *) a)->sin_addr;
    208 
    209 	Debug ("port %d, host %d.%d.%d.%d\n",
    210 		(p[0] << 8) + p[1], t[0], t[1], t[2], t[3]);
    211 	break;
    212 #  endif
    213 #  ifdef IPv6
    214     case AF_INET6:
    215     {
    216 	char astr[INET6_ADDRSTRLEN] = "";
    217 
    218 	inet_ntop(a->sa_family, &((struct sockaddr_in6 *) a)->sin6_addr,
    219 	  astr, sizeof(astr));
    220 	p = (unsigned char *) &((struct sockaddr_in6 *) a)->sin6_port;
    221 
    222 	Debug ("port %d, host %s\n", (p[0] << 8) + p[1], astr);
    223 	break;
    224     }
    225 #  endif
    226     }
    227 }
    228 # endif
    229 
    230 #endif /* XDMCP */
    231