int tool_cmd_scan(int argc, char *argv[]) { int ret = 0; int c; int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000; DBusConnection* connection = NULL; DBusMessage *message = NULL; DBusMessage *reply = NULL; DBusPendingCall *pending = NULL; DBusError error; int32_t scan_period = 0; uint32_t channel_mask = 0; dbus_error_init(&error); while (1) { static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"timeout", required_argument, 0, 't'}, {"channel", required_argument, 0, 'c'}, {0, 0, 0, 0} }; int option_index = 0; c = getopt_long(argc, argv, "hc:t:", long_options, &option_index); if (c == -1) break; switch (c) { case 'h': print_arg_list_help(scan_option_list, argv[0], scan_cmd_syntax); ret = ERRORCODE_HELP; goto bail; case 't': timeout = strtol(optarg, NULL, 0); break; case 'c': channel_mask = strtomask_uint32(optarg); break; } } if (optind < argc) { if (scan_period == 0) { scan_period = strtol(argv[optind], NULL, 0); optind++; } } if (optind < argc) { fprintf(stderr, "%s: error: Unexpected extra argument: \"%s\"\n", argv[0], argv[optind]); ret = ERRORCODE_BADARG; goto bail; } if (gInterfaceName[0] == 0) { fprintf(stderr, "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n", argv[0]); ret = ERRORCODE_BADARG; goto bail; } connection = dbus_bus_get(DBUS_BUS_STARTER, &error); if (!connection) { dbus_error_free(&error); dbus_error_init(&error); connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); } require_string(connection != NULL, bail, error.message); dbus_bus_add_match(connection, gDBusObjectManagerMatchString, &error); require_string(error.name == NULL, bail, error.message); dbus_connection_add_filter(connection, &dbus_beacon_handler, NULL, NULL); { char path[DBUS_MAXIMUM_NAME_LENGTH+1]; char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1]; DBusMessageIter iter; ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName); if (ret != 0) { goto bail; } snprintf( path, sizeof(path), "%s/%s", WPANTUND_DBUS_PATH, gInterfaceName ); message = dbus_message_new_method_call( interface_dbus_name, path, WPANTUND_DBUS_APIv1_INTERFACE, WPANTUND_IF_CMD_NET_SCAN_START ); dbus_message_append_args( message, DBUS_TYPE_UINT32, &channel_mask, DBUS_TYPE_INVALID ); print_scan_header(); gScannedNetworkCount = 0; if(!dbus_connection_send_with_reply( connection, message, &pending, timeout )) { fprintf(stderr, "%s: error: IPC failure\n", argv[0]); ret = ERRORCODE_UNKNOWN; goto bail; } while ((dbus_connection_get_dispatch_status(connection) == DBUS_DISPATCH_DATA_REMAINS) || dbus_connection_has_messages_to_send(connection) || !dbus_pending_call_get_completed(pending) ) { dbus_connection_read_write_dispatch(connection, 5000 /*ms*/); } reply = dbus_pending_call_steal_reply(pending); require(reply!=NULL, bail); dbus_message_iter_init(reply, &iter); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) { fprintf(stderr, "%s: error: Server returned a bad response ('%c')\n", argv[0], dbus_message_iter_get_arg_type(&iter)); ret = ERRORCODE_UNKNOWN; goto bail; } // Get return code dbus_message_iter_get_basic(&iter, &ret); if (ret) { fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret)); print_error_diagnosis(ret); goto bail; } } bail: if (reply) { dbus_message_unref(reply); } if (pending != NULL) { dbus_pending_call_unref(pending); } if (message) { dbus_message_unref(message); } if (connection) { dbus_bus_remove_match(connection, gDBusObjectManagerMatchString, NULL); dbus_connection_remove_filter(connection,&dbus_beacon_handler,NULL); dbus_connection_unref(connection); } dbus_error_free(&error); return ret; }
int tool_cmd_peek(int argc, char* argv[]) { int ret = 0; int c; int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000; DBusConnection* connection = NULL; DBusMessage *message = NULL; DBusMessage *reply = NULL; DBusError error; uint32_t address = 0; uint16_t count = 32; bool simple_data_format = false; dbus_error_init(&error); while (1) { static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"timeout", required_argument, 0, 't'}, {"count", required_argument, 0, 'c'}, {"data", no_argument, 0, 'd'}, {0, 0, 0, 0} }; int option_index = 0; c = getopt_long(argc, argv, "ht:c:d", long_options, &option_index); if (c == -1) { break; } switch (c) { case 'h': print_arg_list_help(peek_option_list, argv[0], peek_cmd_syntax); ret = ERRORCODE_HELP; goto bail; case 't': timeout = strtol(optarg, NULL, 0); break; case 'c': count = strtol(optarg, NULL, 0); break; case 'd': simple_data_format = true; break; } } if (optind < argc) { address = strtol(argv[optind], NULL, 0); optind++; } else { fprintf(stderr, "%s: error: Missing required address parameter\n", argv[0]); ret = ERRORCODE_BADARG; goto bail; } if (optind < argc) { fprintf(stderr, "%s: error: Unexpected extra argument: \"%s\"\n", argv[0], argv[optind]); ret = ERRORCODE_BADARG; goto bail; } if (gInterfaceName[0] == 0) { fprintf( stderr, "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n", argv[0] ); ret = ERRORCODE_BADARG; goto bail; } connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); require_string(connection != NULL, bail, error.message); { char path[DBUS_MAXIMUM_NAME_LENGTH+1]; char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1]; bool did_succeed; uint8_t *data_ptr = NULL; int data_len = 0; uint16_t i; ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName); if (ret != 0) { print_error_diagnosis(ret); goto bail; } snprintf(path, sizeof(path), "%s/%s", WPANTUND_DBUS_PATH, gInterfaceName); message = dbus_message_new_method_call( interface_dbus_name, path, WPANTUND_DBUS_APIv1_INTERFACE, WPANTUND_IF_CMD_PEEK ); fprintf(stdout, "Peeking at address 0x%x (%d) for %d bytes\n", address, address, count); dbus_message_append_args( message, DBUS_TYPE_UINT32, &address, DBUS_TYPE_UINT16, &count, DBUS_TYPE_INVALID ); reply = dbus_connection_send_with_reply_and_block( connection, message, timeout, &error ); if (!reply) { fprintf(stderr, "%s: error: %s\n", argv[0], error.message); ret = ERRORCODE_TIMEOUT; goto bail; } did_succeed = dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &ret, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data_ptr, &data_len, DBUS_TYPE_INVALID ); if (!did_succeed) { did_succeed = dbus_message_get_args(reply, NULL, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID ); } if (!did_succeed || ret != 0) { fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret)); print_error_diagnosis(ret); goto bail; } if (simple_data_format) { for (i = 0; i < data_len; i++) { fprintf(stdout, "%02X ", *data_ptr++); if (i % 32 == 31) { fprintf(stdout, "\n"); } } fprintf(stdout, "\n"); } else { dump_data(data_ptr, data_len); } } bail: if (connection) { dbus_connection_unref(connection); } if (message) { dbus_message_unref(message); } if (reply) { dbus_message_unref(reply); } dbus_error_free(&error); return ret; }
int tool_cmd_reset(int argc, char *argv[]) { int ret = 0; int c; int timeout = 10 * 1000; DBusConnection* connection = NULL; DBusMessage *message = NULL; DBusMessage *reply = NULL; DBusError error; dbus_error_init(&error); while (1) { static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"timeout", required_argument, 0, 't'}, {0, 0, 0, 0} }; int option_index = 0; c = getopt_long(argc, argv, "ht:", long_options, &option_index); if (c == -1) break; switch (c) { case 'h': print_arg_list_help(reset_option_list, argv[0], reset_cmd_syntax); ret = ERRORCODE_HELP; goto bail; case 't': timeout = strtol(optarg, NULL, 0); break; } } if (optind < argc) { fprintf(stderr, "%s: error: Unexpected extra argument: \"%s\"\n", argv[0], argv[optind]); ret = ERRORCODE_BADARG; goto bail; } if (gInterfaceName[0] == 0) { fprintf(stderr, "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n", argv[0]); ret = ERRORCODE_BADARG; goto bail; } connection = dbus_bus_get(DBUS_BUS_STARTER, &error); if (!connection) { dbus_error_free(&error); dbus_error_init(&error); connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); } require_string(connection != NULL, bail, error.message); { DBusMessageIter iter; DBusMessageIter list_iter; char path[DBUS_MAXIMUM_NAME_LENGTH+1]; char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1]; ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName); if (ret != 0) { goto bail; } snprintf(path, sizeof(path), "%s/%s", WPANTUND_DBUS_PATH, gInterfaceName); message = dbus_message_new_method_call( interface_dbus_name, path, WPANTUND_DBUS_APIv1_INTERFACE, WPANTUND_IF_CMD_RESET ); fprintf(stderr, "Resetting NCP. . .\n"); reply = dbus_connection_send_with_reply_and_block( connection, message, timeout, &error ); if (!reply) { fprintf(stderr, "%s: error: %s\n", argv[0], error.message); ret = ERRORCODE_TIMEOUT; goto bail; } dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID ); if (ret == 6) ret = 0; } bail: if (connection) dbus_connection_unref(connection); if (message) dbus_message_unref(message); if (reply) dbus_message_unref(reply); dbus_error_free(&error); return ret; }
int tool_cmd_begin_net_wake(int argc, char *argv[]) { int ret = 0; int c; int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000; DBusConnection* connection = NULL; DBusMessage *message = NULL; DBusMessage *reply = NULL; DBusError error; bool has_net_wake_data = false; uint8_t net_wake_data = 0; uint32_t net_wake_flags = -1; dbus_error_init(&error); while (1) { static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"timeout", required_argument, 0, 't'}, {0, 0, 0, 0} }; int option_index = 0; c = getopt_long(argc, argv, "ht:", long_options, &option_index); if (c == -1) break; switch (c) { case 'h': print_arg_list_help(begin_net_wake_option_list, argv[0], begin_net_wake_cmd_syntax); ret = ERRORCODE_HELP; goto bail; case 't': timeout = strtol(optarg, NULL, 0); break; } } if (optind < argc) { if (!has_net_wake_data) { net_wake_data = strtol(argv[optind], NULL, 0); has_net_wake_data = true; optind++; } } if (optind < argc) { fprintf(stderr, "%s: error: Unexpected extra argument: \"%s\"\n", argv[0], argv[optind]); ret = ERRORCODE_BADARG; goto bail; } if (gInterfaceName[0] == 0) { fprintf(stderr, "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n", argv[0]); ret = ERRORCODE_BADARG; goto bail; } connection = dbus_bus_get(DBUS_BUS_STARTER, &error); if (!connection) { dbus_error_free(&error); dbus_error_init(&error); connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); } require_string(connection != NULL, bail, error.message); { DBusMessageIter iter; DBusMessageIter list_iter; char path[DBUS_MAXIMUM_NAME_LENGTH+1]; char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1]; ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName); if (ret != 0) { goto bail; } snprintf(path, sizeof(path), "%s/%s", WPAN_TUNNEL_DBUS_PATH, gInterfaceName); message = dbus_message_new_method_call( interface_dbus_name, path, WPAN_TUNNEL_DBUS_INTERFACE, WPAN_IFACE_CMD_BEGIN_NET_WAKE ); dbus_message_append_args( message, DBUS_TYPE_BYTE, &net_wake_data, DBUS_TYPE_UINT32, &net_wake_flags, DBUS_TYPE_INVALID ); fprintf(stderr, "Begin Net Wake, data = 0x%02X\n", net_wake_data); reply = dbus_connection_send_with_reply_and_block( connection, message, timeout, &error ); if (!reply) { fprintf(stderr, "%s: error: %s\n", argv[0], error.message); ret = ERRORCODE_TIMEOUT; goto bail; } dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID ); if (ret) { fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, (ret<0)?strerror(-ret):""); print_error_diagnosis(ret); } } bail: if (connection) dbus_connection_unref(connection); if (message) dbus_message_unref(message); if (reply) dbus_message_unref(reply); dbus_error_free(&error); return ret; }
int tool_cmd_form(int argc, char* argv[]) { int ret = 0; int c; int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000; DBusConnection* connection = NULL; DBusMessage *message = NULL; DBusMessage *reply = NULL; DBusError error; const char* network_name = NULL; const char* ula_prefix = NULL; uint16_t node_type = WPAN_IFACE_ROLE_ROUTER; // Default to router for form uint32_t channel_mask = 0; dbus_error_init(&error); while (1) { static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"timeout", required_argument, 0, 't'}, {"channel", required_argument, 0, 'c'}, {"ula-prefix", required_argument, 0, 'u'}, {"mesh-local-prefix", required_argument, 0, 'M'}, {"legacy-prefix", required_argument, 0, 'L'}, {"type", required_argument, 0, 'T'}, {0, 0, 0, 0} }; int option_index = 0; c = getopt_long(argc, argv, "hc:t:T:u:", long_options, &option_index); if (c == -1) break; switch (c) { case 'h': print_arg_list_help(form_option_list, argv[0], form_cmd_syntax); ret = ERRORCODE_HELP; goto bail; case 't': timeout = strtol(optarg, NULL, 0); break; case 'c': channel_mask = (1 << strtol(optarg, NULL, 0)); break; case 'M': fprintf(stderr, "%s: error: Setting the mesh local address at the command line isn't yet implemented. Set it as a property instead.\n", argv[0]); ret = ERRORCODE_BADARG; goto bail; break; case 'L': case 'u': ula_prefix = optarg; break; case 'T': node_type = node_type_str2int(optarg); break; } } if (optind < argc) { if (!network_name) { network_name = argv[optind]; optind++; } } if (optind < argc) { fprintf(stderr, "%s: error: Unexpected extra argument: \"%s\"\n", argv[0], argv[optind]); ret = ERRORCODE_BADARG; goto bail; } if (!network_name) { fprintf(stderr, "%s: error: Missing network name.\n", argv[0]); ret = ERRORCODE_BADARG; goto bail; } if (gInterfaceName[0] == 0) { fprintf(stderr, "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n", argv[0]); ret = ERRORCODE_BADARG; goto bail; } connection = dbus_bus_get(DBUS_BUS_STARTER, &error); if (!connection) { dbus_error_free(&error); dbus_error_init(&error); connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); } require_string(connection != NULL, bail, error.message); { DBusMessageIter iter; DBusMessageIter list_iter; char path[DBUS_MAXIMUM_NAME_LENGTH+1]; char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1]; ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName); if (ret != 0) { goto bail; } snprintf(path, sizeof(path), "%s/%s", WPAN_TUNNEL_DBUS_PATH, gInterfaceName); message = dbus_message_new_method_call( interface_dbus_name, path, WPAN_TUNNEL_DBUS_INTERFACE, WPAN_IFACE_CMD_FORM ); dbus_message_append_args( message, DBUS_TYPE_STRING, &network_name, DBUS_TYPE_INT16, &node_type, DBUS_TYPE_UINT32, &channel_mask, DBUS_TYPE_INVALID ); if(ula_prefix) { uint8_t ula_bytes[16] = {}; // So the ULA prefix could either be // specified like an IPv6 address, or // specified as a bunch of hex numbers. // We use the presence of a colon (':') // to differentiate. if(strstr(ula_prefix,":")) { // Address-style int bits = inet_pton(AF_INET6,ula_prefix,ula_bytes); if(bits<0) { fprintf(stderr, "Bad ULA \"%s\", errno=%d (%s)\n", ula_prefix, errno, strerror(errno)); goto bail; } else if(!bits) { fprintf(stderr, "Bad ULA \"%s\"\n", ula_prefix); goto bail; } } else { // DATA-style int length = parse_string_into_data(ula_bytes, 8, ula_prefix); if(length<=0) { fprintf(stderr, "Bad ULA \"%s\"\n", ula_prefix); goto bail; } } fprintf(stderr, "Using ULA prefix \"%s\"\n", ula_prefix); uint8_t *addr = ula_bytes; dbus_message_append_args( message, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &addr, 8, DBUS_TYPE_INVALID ); } fprintf(stderr, "Forming WPAN \"%s\" as node type %d\n", network_name, node_type); reply = dbus_connection_send_with_reply_and_block( connection, message, timeout, &error ); if (!reply) { fprintf(stderr, "%s: error: %s\n", argv[0], error.message); ret = ERRORCODE_TIMEOUT; goto bail; } dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID ); if (!ret) { fprintf(stderr, "Successfully formed!\n"); } else { fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret)); print_error_diagnosis(ret); } } bail: if (connection) dbus_connection_unref(connection); if (message) dbus_message_unref(message); if (reply) dbus_message_unref(reply); dbus_error_free(&error); return ret; }
static int do_pcap_to_fd(int fd, int timeout, DBusError *error) { int ret = ERRORCODE_UNKNOWN; DBusConnection *connection = NULL; DBusMessage *message = NULL; DBusMessage *reply = NULL; char path[DBUS_MAXIMUM_NAME_LENGTH+1]; char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1]; connection = dbus_bus_get(DBUS_BUS_STARTER, error); if (connection == NULL) { if (error != NULL) { dbus_error_free(error); dbus_error_init(error); } connection = dbus_bus_get(DBUS_BUS_SYSTEM, error); } require(connection != NULL, bail); ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName); require_noerr(ret, bail); snprintf( path, sizeof(path), "%s/%s", WPANTUND_DBUS_PATH, gInterfaceName ); message = dbus_message_new_method_call( interface_dbus_name, path, WPANTUND_DBUS_APIv1_INTERFACE, WPANTUND_IF_CMD_PCAP_TO_FD ); dbus_message_append_args( message, DBUS_TYPE_UNIX_FD, &fd, DBUS_TYPE_INVALID ); ret = ERRORCODE_TIMEOUT; reply = dbus_connection_send_with_reply_and_block( connection, message, timeout, error ); require(reply != NULL, bail); dbus_message_get_args( reply, error, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID ); bail: if (connection) { dbus_connection_unref(connection); } if (message) { dbus_message_unref(message); } if (reply) { dbus_message_unref(reply); } return ret; }