Exemple #1
0
static int
S_get_v6_packet(mach_port_t server, int argc, char * argv[])
{
    inline_data_t 		data;
    unsigned int 		data_len = sizeof(data);
    DHCPv6OptionErrorString 	err;
    kern_return_t		kret;
    if_name_t			name;
    DHCPv6OptionListRef		options;
    int				ret;
    ipconfig_status_t		status;

    ret = 1;
    strlcpy(name, argv[0], sizeof(name));
    kret = ipconfig_get_v6_packet(server, name, data, &data_len, &status);
    if (kret != KERN_SUCCESS) {
	fprintf(stderr, "ipconfig_get_v6_packet failed, %s\n", 
		mach_error_string(kret));
	goto done;
    }
    if (status != ipconfig_status_success_e) {
	goto done;
    }
    DHCPv6PacketFPrint(stdout, (DHCPv6PacketRef)data, data_len);
    options = DHCPv6OptionListCreateWithPacket((DHCPv6PacketRef)data,
					       data_len, &err);
    if (options != NULL) {
	DHCPv6OptionListFPrint(stdout, options);
	DHCPv6OptionListRelease(&options);
    }
    ret = 0;

 done:
    return (ret);
}
static void
DHCPv6SocketDemux(int if_index, const DHCPv6PacketRef pkt, int pkt_len)
{
    DHCPv6SocketReceiveData	data;
    DHCPv6OptionErrorString 	err;
    int 			i;

    if (pkt_len < DHCPV6_PACKET_HEADER_LENGTH) {
	return;
    }
    data.pkt = pkt;
    data.pkt_len = pkt_len;
    data.options = DHCPv6OptionListCreateWithPacket(pkt, pkt_len, &err);
    if (data.options == NULL) {
	my_log(LOG_NOTICE, "DHCPv6Socket: options parse failed, %s",
	       err.str);
	return;
    }
    for (i = 0; i < dynarray_count(&S_globals->sockets); i++) {
	DHCPv6SocketRef	client;

	client = dynarray_element(&S_globals->sockets, i);
	if (if_index != if_link_index(DHCPv6SocketGetInterface(client))) {
	    continue;
	}
	if (S_verbose) {
	    CFMutableStringRef	str;
	    
	    str = CFStringCreateMutable(NULL, 0);
	    DHCPv6PacketPrintToString(str, pkt, pkt_len);
	    if (data.options != NULL) {
		DHCPv6OptionListPrintToString(str, data.options);
	    }
	    my_log(-LOG_DEBUG, "[%s] Receive %@", 
		   if_name(DHCPv6SocketGetInterface(client)), str);
	    CFRelease(str);
	}
	if (client->receive_func != NULL) {
	    (*client->receive_func)(client->receive_arg1, client->receive_arg2,
				    &data);
	}
    }
    DHCPv6OptionListRelease(&data.options);
    return;
}
int
DHCPv6SocketTransmit(DHCPv6SocketRef sock,
		     DHCPv6PacketRef pkt, int pkt_len)
{
    DHCPv6OptionErrorString	err;
    int				ret;
    boolean_t			needs_close = FALSE;

    if (sock->fd_open == FALSE) {
	/* open the DHCPv6 socket in case it's needed */
	if (DHCPv6SocketOpenSocket(sock) == FALSE) {
	    my_log(LOG_ERR, "DHCPv6Socket: failed to open socket");
	    return (FALSE);
	}
	needs_close = TRUE;
    }
    if (S_verbose) {
	DHCPv6OptionListRef	options;
	CFMutableStringRef	str;
	
	str = CFStringCreateMutable(NULL, 0);
	DHCPv6PacketPrintToString(str, pkt, pkt_len);
	options = DHCPv6OptionListCreateWithPacket(pkt, pkt_len, &err);
	if (options == NULL) {
	    my_log_fl(LOG_DEBUG, "parse options failed, %s",
		      err.str);
	}
	else {
	    DHCPv6OptionListPrintToString(str, options);
	    DHCPv6OptionListRelease(&options);
	}
	my_log(-LOG_DEBUG,"[%s] Transmit %@", if_name(sock->if_p), str);
	CFRelease(str);
    }
    ret = S_send_packet(FDCalloutGetFD(S_globals->read_fd),
			if_link_index(sock->if_p), pkt, pkt_len);
    if (needs_close) {
	DHCPv6SocketCloseSocket(sock);
    }
    return (ret);
}