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); }