diff --git a/omvs_main.c b/omvs_main.c index 20ad371..1fb380f 100644 --- a/omvs_main.c +++ b/omvs_main.c @@ -3,17 +3,24 @@ #include #include -static gchar *_omvs_net_dev; +static gint _omvs_net_dev_idx; +static gboolean _omvs_list_devs; static gchar *_omvs_output = "omvs_out.txt"; static gint _omvs_jobs = 1; static gint _omvs_sleep = 1000; static gint _omvs_timeout = 10000; static gboolean _omvs_verbose; +static gchar **_omvs_net_dev_names; +static gchar **_omvs_net_dev_descs; +static gint _omvs_num_net_devs; + static GOptionEntry _omvs_entries[] = { - { "interface", 'i', 0, G_OPTION_ARG_STRING, &_omvs_net_dev, - "Network device interface", "dev" }, + { "interface", 'i', 0, G_OPTION_ARG_INT, &_omvs_net_dev_idx, + "Network device interface index", "dev_idx" }, + { "list-inteface", 'l', 0, G_OPTION_ARG_NONE, &_omvs_list_devs, + "List network device interfaces", NULL }, { "jobs", 'j', 0, G_OPTION_ARG_INT, &_omvs_jobs, "Number of jobs", "jobs" }, { "output", 'o', 0, G_OPTION_ARG_FILENAME, &_omvs_output, @@ -43,9 +50,63 @@ typedef struct _OMVSScanner { gint num_ipaddrs; } OMVSScanner; +static gint _omvs_init_net_devs_info(void); +static gint _omvs_print_net_devs_info(void); +static gint _omvs_deinit_net_devs_info(void); static gint _omvs_start_scan(OMVSScanner *scanner); static gpointer _omvs_start_scan_job(gpointer data); +static gint _omvs_init_net_devs_info(void) { + gchar errbuf[PCAP_ERRBUF_SIZE]; + pcap_if_t *alldevs; + pcap_if_t *dev; + gint i; + + if (pcap_findalldevs(&alldevs, errbuf) != 0) { + g_print("pcap_findalldevs() fail: %s", errbuf); + return -1; + } + dev = alldevs; + while (dev) { + _omvs_num_net_devs++; + dev = dev->next; + } + _omvs_net_dev_names = g_malloc(sizeof(gchar *) * _omvs_num_net_devs); + _omvs_net_dev_descs = g_malloc(sizeof(gchar *) * _omvs_num_net_devs); + + for (i = 0, dev = alldevs; dev; i++, dev = dev->next) { + _omvs_net_dev_names[i] = g_strdup(dev->name); + _omvs_net_dev_descs[i] = g_strdup(dev->description); + } + pcap_freealldevs(alldevs); + + return 0; +} + +static gint _omvs_print_net_devs_info(void) { + gint i; + + for (i = 0; i < _omvs_num_net_devs; i++) { + g_print("dev_idx(%d) dev_name(%s) dev_desc(%s)\n", + i, _omvs_net_dev_names[i], _omvs_net_dev_descs[i]); + } + + return 0; +} + +static gint _omvs_deinit_net_devs_info(void) { + gint i; + + for (i = 0; i < _omvs_num_net_devs; i++) { + g_free(_omvs_net_dev_names[i]); + g_free(_omvs_net_dev_descs[i]); + } + g_free(_omvs_net_dev_names); + g_free(_omvs_net_dev_descs); + + return 0; +} + static gpointer _omvs_start_scan_job(gpointer data) { OMVSScanner *scanner; GError *error; @@ -90,8 +151,8 @@ static gpointer _omvs_start_scan_job(gpointer data) { g_print("[%p] start scanning %s\n", (void *)g_thread_self(), addr_str); } group_address = g_inet_address_new_from_string(addr_str); - if (!g_socket_join_multicast_group( - socket, group_address, FALSE, _omvs_net_dev, &error)) { + if (!g_socket_join_multicast_group(socket, group_address, FALSE, + _omvs_net_dev_names[_omvs_net_dev_idx], &error)) { g_printerr("[%p] can't join %s: %s\n", (void *)g_thread_self(), addr_str, error->message); } @@ -101,8 +162,8 @@ static gpointer _omvs_start_scan_job(gpointer data) { if (_omvs_verbose) { g_print("[%p] finish scanning %s\n", (void *)g_thread_self(), addr_str); } - if (!g_socket_leave_multicast_group( - socket, group_address, FALSE, _omvs_net_dev, &error)) { + if (!g_socket_leave_multicast_group(socket, group_address, FALSE, + _omvs_net_dev_names[_omvs_net_dev_idx], &error)) { g_printerr("[%p] can't leave %s: %s\n", (void *)g_thread_self(), addr_str, error->message); } @@ -163,6 +224,11 @@ int main(int argc, char *argv[]) { gint idx_ipaddr; OMVSScanner omvs_scanner; + if (_omvs_init_net_devs_info() != 0) { + ret = -5; + goto finish_return2; + } + context = g_option_context_new(""); g_option_context_set_summary(context, "omvs scans to find free video streaming multicast ip addresses." @@ -180,6 +246,12 @@ int main(int argc, char *argv[]) { goto finish_return; } + if (_omvs_list_devs) { + _omvs_print_net_devs_info(); + ret = 0; + goto finish_return; + } + if (argc < 2) { gchar *help_msg; help_msg = g_option_context_get_help(context, TRUE, NULL); @@ -263,6 +335,8 @@ int main(int argc, char *argv[]) { finish_return: g_option_context_free(context); + _omvs_deinit_net_devs_info(); +finish_return2: return ret; }