#include #include #include #include static gchar *_omvs_net_dev; static gchar *_omvs_output = "omvs_out.txt"; static gint _omvs_jobs = 1; static gint _omvs_sleep = 1000; static gint _omvs_timeout = 10000; static GOptionEntry _omvs_entries[] = { { "interface", 'i', 0, G_OPTION_ARG_STRING, &_omvs_net_dev, "Network device interface", "dev" }, { "jobs", 'j', 0, G_OPTION_ARG_INT, &_omvs_jobs, "Number of jobs", "jobs" }, { "output", 'o', 0, G_OPTION_ARG_FILENAME, &_omvs_output, "Output filename", "filename" }, { "sleep", 's', 0, G_OPTION_ARG_INT, &_omvs_sleep, "Sleep time(milliseconds) between scans", "ms" }, { "timeout", 't', 0, G_OPTION_ARG_INT, &_omvs_timeout, "Timeout time(milliseconds) in each scan", "ms" }, { NULL } }; typedef struct _OMVSPort { gint port; gint type; } OMVSPort; typedef struct _OMVSIPAddr { guint32 addr; OMVSPort *ports; gint num_ports; } OMVSIPAddr; typedef struct _OMVSScanner { OMVSIPAddr *ipaddrs; gint num_ipaddrs; } OMVSScanner; static gint _omvs_start_scan(OMVSScanner *scanner); static gint _omvs_start_scan(OMVSScanner *scanner) { gint i; for (i = 0; i < scanner->num_ipaddrs; i++) { g_print("%08x\n", scanner->ipaddrs[i].addr); } return 0; } int main(int argc, char *argv[]) { GError *error = NULL; GOptionContext *context; int ret = 0; gint i; gint num_ipaddrs; gint idx_ipaddr; OMVSScanner omvs_scanner; context = g_option_context_new(""); g_option_context_set_summary(context, "omvs scans to find free video streaming multicast ip addresses." ); g_option_context_set_description(context, "Oh! Multicast Video Scanner " OMVS_VERSION " is" " Written by Taeho Oh .\n" "http://ohhara.sarang.net"); g_option_context_add_main_entries(context, _omvs_entries, NULL); g_option_context_add_group(context, gst_init_get_option_group()); if (!g_option_context_parse(context, &argc, &argv, &error)) { g_print("option parsing failed: %s\n", error->message); ret = -1; goto finish_return; } if (argc < 2) { gchar *help_msg; help_msg = g_option_context_get_help(context, TRUE, NULL); g_print("%s", help_msg); g_free(help_msg); ret = -2; goto finish_return; } num_ipaddrs = 0; for (i = 1; i < argc; i++) { GInetAddressMask *mask; GInetAddress *addr; guint len; mask = g_inet_address_mask_new_from_string(argv[i], &error); if (!mask) { g_print("%s parsing failed: %s\n", argv[i], error->message); ret = -3; goto finish_return; } if (g_inet_address_mask_get_family(mask) != G_SOCKET_FAMILY_IPV4) { g_print("%s is not ipv4 ip address\n", argv[i]); g_object_unref(mask); ret = -4; goto finish_return; } addr = g_inet_address_mask_get_address(mask); if (!g_inet_address_get_is_multicast(addr)) { g_print("%s is not multicast ip address\n", argv[i]); g_object_unref(mask); ret = -4; goto finish_return; } len = g_inet_address_mask_get_length(mask); if (len) { num_ipaddrs += (1 << (32 - len)); } else { num_ipaddrs++; } g_object_unref(mask); } memset(&omvs_scanner, 0, sizeof(OMVSScanner)); omvs_scanner.ipaddrs = g_malloc0(num_ipaddrs * sizeof(OMVSIPAddr)); omvs_scanner.num_ipaddrs = num_ipaddrs; idx_ipaddr = 0; for (i = 1; i < argc; i++) { GInetAddressMask *mask; GInetAddress *addr; guint len; guint32 start_ipaddr; const guint8 *addr_bytes; mask = g_inet_address_mask_new_from_string(argv[i], &error); addr = g_inet_address_mask_get_address(mask); len = g_inet_address_mask_get_length(mask); addr_bytes = g_inet_address_to_bytes(addr); start_ipaddr = (((guint32)addr_bytes[0]) << 24) | (((guint32)addr_bytes[1]) << 16) | (((guint32)addr_bytes[2]) << 8) | (((guint32)addr_bytes[3]) << 0); if (len) { guint n; guint j; n = (1 << (32 - len)); for (j = 0; j < n; j++) { omvs_scanner.ipaddrs[idx_ipaddr].addr = start_ipaddr; idx_ipaddr++; start_ipaddr++; } } else { omvs_scanner.ipaddrs[idx_ipaddr].addr = start_ipaddr; idx_ipaddr++; } } _omvs_start_scan(&omvs_scanner); g_free(omvs_scanner.ipaddrs); finish_return: g_option_context_free(context); return ret; }