root/usr/src/cmd/krb5/slave/utils.c
/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#include <k5-int.h>
#include <socket-utils.h>
#include <inet/ip.h>

/*
 * convert a sockaddr_storage address to a krb5_address
 * Returns address of krbap if success, NULL if error.
 */

krb5_address *
cvtkaddr(struct sockaddr_storage *ss, krb5_address *krbap)
{
        switch (ss->ss_family) {
                case AF_INET:
                        krbap->contents = (krb5_octet *)
                                    malloc(sizeof (ss2sin(ss)->sin_addr));
                        if (krbap->contents == NULL)
                                return (NULL);
                        memcpy((char *)krbap->contents,
                                        (char *)&(ss2sin(ss)->sin_addr),
                                        sizeof (ss2sin(ss)->sin_addr));
                        krbap->addrtype = ADDRTYPE_INET;
                        krbap->length = sizeof (ss2sin(ss)->sin_addr);
                        return (krbap);
                case AF_INET6:
                        if (IN6_IS_ADDR_V4MAPPED(&ss2sin6(ss)->sin6_addr)) {
                                /* coerce to IPv4 address */
                                krbap->contents = (krb5_octet *)
                                        malloc(IPV4_ADDR_LEN);
                                if (krbap->contents == NULL)
                                        return (NULL);
                                IN6_V4MAPPED_TO_IPADDR(
                                        &(ss2sin6(ss)->sin6_addr),
                                        *(ipaddr_t *)(krbap->contents));
                                krbap->addrtype = ADDRTYPE_INET;
                                krbap->length = IPV4_ADDR_LEN;
                        } else {
                                krbap->contents = (krb5_octet *)
                                        malloc(sizeof (ss2sin6(ss)->sin6_addr));
                                if (krbap->contents == NULL)
                                        return (NULL);
                                memcpy((char *)krbap->contents,
                                        (char *)&ss2sin6(ss)->sin6_addr,
                                        sizeof (ss2sin6(ss)->sin6_addr));
                                krbap->addrtype = ADDRTYPE_INET6;
                                krbap->length = sizeof (ss2sin6(ss)->sin6_addr);
                        }
                        return (krbap);
                default:
                        return (NULL);
        }
}