mirror of
https://bitbucket.org/ohhara/ohmulticastvideoscanner.git
synced 2025-06-10 09:26:11 +00:00
163 lines
4.4 KiB
C
163 lines
4.4 KiB
C
#include <string.h>
|
|
#include <pcap.h>
|
|
#include <gio/gio.h>
|
|
#include <gst/gst.h>
|
|
|
|
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("<multicast ip address or net ... [#N]>");
|
|
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 <ohhara@postech.edu>.\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;
|
|
}
|