Пример #1
0
STATIC int
RTADVSocketInitTXBuf(RTADVSocketRef sock, uint32_t * txbuf, bool lladdr_ok)
{
    interface_t *		if_p = RTADVSocketGetInterface(sock);
    struct nd_router_solicit *	ndrs;
    int				txbuf_used;

    ndrs = (struct nd_router_solicit *)txbuf;
    ndrs->nd_rs_type = ND_ROUTER_SOLICIT;
    ndrs->nd_rs_code = 0;
    ndrs->nd_rs_cksum = 0;
    ndrs->nd_rs_reserved = 0;
    txbuf_used = sizeof(struct nd_router_solicit);

    /* if it's OK to include [RFC 4429], add source link-layer address option */
    if (lladdr_ok && if_link_type(if_p) == IFT_ETHER) {
	int			opt_len;
	struct nd_opt_hdr *	ndopt;

	opt_len = roundup(if_link_length(if_p) + sizeof(*ndopt), ND_OPT_ALIGN);
	ndopt = (struct nd_opt_hdr *)(ndrs + 1);
	ndopt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
	ndopt->nd_opt_len = (opt_len / ND_OPT_ALIGN);
	bcopy(if_link_address(if_p), (ndopt + 1), if_link_length(if_p));
	txbuf_used += opt_len;
    }
    return (txbuf_used);
}
STATIC CFDataRef
make_DUID_LL_data(interface_t * if_p)
{
    CFMutableDataRef	data;
    int			duid_len;
    DHCPDUID_LLRef	ll_p;

    duid_len = offsetof(DHCPDUID_LL, linklayer_address) + if_link_length(if_p);
    data = CFDataCreateMutable(NULL, duid_len);
    CFDataSetLength(data, duid_len);
    ll_p = (DHCPDUID_LLRef)CFDataGetMutableBytePtr(data);
    DHCPDUIDSetType((DHCPDUIDRef)ll_p, kDHCPDUIDTypeLL);
    DHCPDUID_LLSetHardwareType(ll_p, if_link_arptype(if_p));
    bcopy(if_link_address(if_p), ll_p->linklayer_address,
	  if_link_length(if_p));
    return (data);
}
PRIVATE_EXTERN CFDataRef
DHCPDUIDGet(interface_list_t * interfaces)
{
    interface_t *		if_p;
    interface_t *	       	if_with_linkaddr_p = NULL;

    if (S_DUID != NULL) {
	goto done;
    }
    /* try to load the DUID from filesystem */
    if (G_is_netboot == FALSE && load_DUID_info()) {
	goto done;
    }
    if (interfaces == NULL) {
	goto done;
    }
    if_p = ifl_find_name(interfaces, "en0");
    if (if_p == NULL) {
	int		count;
	int		i;

	count = ifl_count(interfaces);
	for (i = 0; i < count; i++) {
	    interface_t *	scan = ifl_at_index(interfaces, i);

	    switch (if_ift_type(scan)) {
	    case IFT_ETHER:
	    case IFT_IEEE1394:
		break;
	    default:
		if (if_with_linkaddr_p == NULL
		    && if_link_length(scan) > 0) {
		    if_with_linkaddr_p = scan;
		}
		continue;
	    }
	    if (if_p == NULL) {
		if_p = scan;
	    }
	    else if (strcmp(if_name(scan), if_name(if_p)) < 0) {
		/* pick "lowest" named interface */
		if_p = scan;
	    }
	}
    }
    if (if_p == NULL) {
	if (G_dhcp_duid_type == kDHCPDUIDTypeLL || if_with_linkaddr_p == NULL) {
	    my_log(LOG_ERR,
		   "DHCPv6Client: can't determine interface for DUID");
	    goto done;
	}
	if_p = if_with_linkaddr_p;
    }
    if (G_IPConfiguration_verbose) {
	my_log(LOG_DEBUG, "DHCPv6Client: chose %s for DUID",
	       if_name(if_p));
    }
    if (G_dhcp_duid_type == kDHCPDUIDTypeLL || G_is_netboot) {
	S_DUID = make_DUID_LL_data(if_p);
    }
    else {
	S_DUID = make_DUID_LLT_data(if_p);
    }
    save_DUID_info();

 done:
    return (S_DUID);
}