mirror of
https://bitbucket.org/ohhara/ohmulticastvideoscanner.git
synced 2025-08-27 02:31:19 +00:00
Add Waiting for multicast packet mode.
This commit is contained in:
parent
59f4f8653f
commit
3c969575fd
160
omvs_main.c
160
omvs_main.c
@ -17,6 +17,7 @@ static gint _omvs_jobs = 1;
|
|||||||
static gint _omvs_sleep = 1000;
|
static gint _omvs_sleep = 1000;
|
||||||
static gint _omvs_timeout = 10000;
|
static gint _omvs_timeout = 10000;
|
||||||
static gboolean _omvs_quiet;
|
static gboolean _omvs_quiet;
|
||||||
|
static gboolean _omvs_wait;
|
||||||
|
|
||||||
static gchar **_omvs_net_dev_names;
|
static gchar **_omvs_net_dev_names;
|
||||||
static gchar **_omvs_net_dev_descs;
|
static gchar **_omvs_net_dev_descs;
|
||||||
@ -38,6 +39,8 @@ static GOptionEntry _omvs_entries[] =
|
|||||||
"Timeout time(milliseconds) in each scan", "ms" },
|
"Timeout time(milliseconds) in each scan", "ms" },
|
||||||
{ "quiet", 'q', 0, G_OPTION_ARG_NONE, &_omvs_quiet,
|
{ "quiet", 'q', 0, G_OPTION_ARG_NONE, &_omvs_quiet,
|
||||||
"Print no log except for errors", NULL },
|
"Print no log except for errors", NULL },
|
||||||
|
{ "wait", 'w', 0, G_OPTION_ARG_NONE, &_omvs_wait,
|
||||||
|
"Wait for multicast packet", NULL },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -84,6 +87,7 @@ static gint _omvs_print_net_devs_info(void);
|
|||||||
static gint _omvs_deinit_net_devs_info(void);
|
static gint _omvs_deinit_net_devs_info(void);
|
||||||
static gint _omvs_start_scan(OMVSScanner *scanner);
|
static gint _omvs_start_scan(OMVSScanner *scanner);
|
||||||
static gpointer _omvs_start_scan_job(gpointer data);
|
static gpointer _omvs_start_scan_job(gpointer data);
|
||||||
|
static gint _omvs_wait_for_multicast_packet(void);
|
||||||
|
|
||||||
static gint _omvs_init_net_devs_info(void) {
|
static gint _omvs_init_net_devs_info(void) {
|
||||||
gchar errbuf[PCAP_ERRBUF_SIZE];
|
gchar errbuf[PCAP_ERRBUF_SIZE];
|
||||||
@ -198,7 +202,7 @@ static gpointer _omvs_start_scan_job(gpointer data) {
|
|||||||
addr[3] = (guint8)((o_ipaddr->addr >> 0) & 0xff);
|
addr[3] = (guint8)((o_ipaddr->addr >> 0) & 0xff);
|
||||||
|
|
||||||
addr_str =
|
addr_str =
|
||||||
g_strdup_printf("%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
|
g_strdup_printf("%u.%u.%u.%u", addr[0], addr[1], addr[2], addr[3]);
|
||||||
|
|
||||||
if (!_omvs_quiet) {
|
if (!_omvs_quiet) {
|
||||||
g_print("[%p] start scanning %s\n", (void *)g_thread_self(), addr_str);
|
g_print("[%p] start scanning %s\n", (void *)g_thread_self(), addr_str);
|
||||||
@ -392,6 +396,153 @@ static gint _omvs_start_scan(OMVSScanner *scanner) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint _omvs_wait_for_multicast_packet(void) {
|
||||||
|
pcap_t *pcap;
|
||||||
|
gchar errbuf[PCAP_ERRBUF_SIZE];
|
||||||
|
const guint8 *packet;
|
||||||
|
struct pcap_pkthdr *header;
|
||||||
|
GHashTable *urihashtable;
|
||||||
|
gint64 time1, time2;
|
||||||
|
OMVSGst gst;
|
||||||
|
gchar *cur_uri;
|
||||||
|
|
||||||
|
pcap = pcap_open_live(_omvs_net_dev_names[_omvs_net_dev_idx],
|
||||||
|
sizeof(OMVSEthHdr) + sizeof(OMVSIPHdr) + sizeof(OMVSUDPHdr),
|
||||||
|
TRUE, 500, errbuf);
|
||||||
|
if (pcap == NULL) {
|
||||||
|
g_printerr("[%p] can't open pcap: %s\n", (void *)g_thread_self(), errbuf);
|
||||||
|
goto finish_return2;
|
||||||
|
}
|
||||||
|
if (pcap_datalink(pcap) != DLT_EN10MB) {
|
||||||
|
g_printerr("[%p] %s is not ethernet\n", (void *)g_thread_self(),
|
||||||
|
_omvs_net_dev_names[_omvs_net_dev_idx]);
|
||||||
|
goto finish_return3;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst = NULL;
|
||||||
|
urihashtable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
time1 = g_get_monotonic_time();
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
gint ret;
|
||||||
|
guint caplen;
|
||||||
|
OMVSIPHdr *ip;
|
||||||
|
OMVSUDPHdr *udp;
|
||||||
|
guint ip_hdr_len;
|
||||||
|
gint udp_port;
|
||||||
|
GInetAddress *addr;
|
||||||
|
gchar *addr_str;
|
||||||
|
guint32 haddr;
|
||||||
|
gchar *uri;
|
||||||
|
gchar *filename;
|
||||||
|
|
||||||
|
ret = pcap_next_ex(pcap, &header, &packet);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst) {
|
||||||
|
time2 = g_get_monotonic_time();
|
||||||
|
if (omvs_gst_is_finished(gst)) {
|
||||||
|
if (!_omvs_quiet) {
|
||||||
|
g_print("[%p] finish scanning %s\n", (void *)g_thread_self(),
|
||||||
|
cur_uri);
|
||||||
|
}
|
||||||
|
omvs_gst_close(gst);
|
||||||
|
gst = NULL;
|
||||||
|
} else if (time2 - time1 > (gint64)((gint64)_omvs_timeout * 1000)) {
|
||||||
|
if (!_omvs_quiet) {
|
||||||
|
g_print("[%p] finish scanning %s\n", (void *)g_thread_self(),
|
||||||
|
cur_uri);
|
||||||
|
}
|
||||||
|
omvs_gst_close(gst);
|
||||||
|
gst = NULL;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
caplen = header->caplen;
|
||||||
|
|
||||||
|
if (caplen < sizeof(OMVSEthHdr)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
packet += sizeof(OMVSEthHdr);
|
||||||
|
caplen -= sizeof(OMVSEthHdr);
|
||||||
|
if (caplen < sizeof(OMVSIPHdr)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = (OMVSIPHdr *)packet;
|
||||||
|
ip_hdr_len = (ip->vhl & 0x0f) * 4;
|
||||||
|
if (caplen < ip_hdr_len) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ip->protocol != _OMVS_IPPROTO_UDP) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr = g_inet_address_new_from_bytes(
|
||||||
|
(const guint8 *)&ip->daddr, G_SOCKET_FAMILY_IPV4);
|
||||||
|
if (!g_inet_address_get_is_multicast(addr)) {
|
||||||
|
g_object_unref(addr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
g_object_unref(addr);
|
||||||
|
|
||||||
|
packet += ip_hdr_len;
|
||||||
|
caplen -= ip_hdr_len;
|
||||||
|
|
||||||
|
if (caplen < sizeof(OMVSUDPHdr)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
udp = (OMVSUDPHdr *)packet;
|
||||||
|
udp_port = g_ntohs(udp->uh_dport);
|
||||||
|
|
||||||
|
haddr = g_ntohl(ip->daddr);
|
||||||
|
addr_str = g_strdup_printf("%u.%u.%u.%u",
|
||||||
|
(haddr >> 24) & 0xff,
|
||||||
|
(haddr >> 16) & 0xff,
|
||||||
|
(haddr >> 8) & 0xff,
|
||||||
|
(haddr >> 0) & 0xff);
|
||||||
|
uri = g_strdup_printf("udp://%s:%u", addr_str, udp_port);
|
||||||
|
filename =
|
||||||
|
g_strdup_printf("%s/%s-%d.png", _omvs_outdir, addr_str, udp_port);
|
||||||
|
g_free(addr_str);
|
||||||
|
|
||||||
|
if (!g_hash_table_insert(urihashtable, uri, NULL)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_uri = uri;
|
||||||
|
if (!_omvs_quiet) {
|
||||||
|
g_print("[%p] start scanning %s\n", (void *)g_thread_self(), cur_uri);
|
||||||
|
g_print("[%p] trying to save %s to %s\n", (void *)g_thread_self(),
|
||||||
|
cur_uri, filename);
|
||||||
|
}
|
||||||
|
time1 = g_get_monotonic_time();
|
||||||
|
g_assert(gst == NULL);
|
||||||
|
gst = omvs_gst_open(cur_uri, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hash_table_destroy(urihashtable);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
finish_return3:
|
||||||
|
pcap_close(pcap);
|
||||||
|
finish_return2:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GOptionContext *context;
|
GOptionContext *context;
|
||||||
@ -428,7 +579,7 @@ int main(int argc, char *argv[]) {
|
|||||||
goto finish_return;
|
goto finish_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc < 2 || _omvs_net_dev_idx >= _omvs_num_net_devs) {
|
if ((!_omvs_wait && argc < 2) || _omvs_net_dev_idx >= _omvs_num_net_devs) {
|
||||||
gchar *help_msg;
|
gchar *help_msg;
|
||||||
help_msg = g_option_context_get_help(context, TRUE, NULL);
|
help_msg = g_option_context_get_help(context, TRUE, NULL);
|
||||||
g_print("%s", help_msg);
|
g_print("%s", help_msg);
|
||||||
@ -439,6 +590,11 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
g_mkdir(_omvs_outdir, 0755);
|
g_mkdir(_omvs_outdir, 0755);
|
||||||
|
|
||||||
|
if (_omvs_wait) {
|
||||||
|
_omvs_wait_for_multicast_packet();
|
||||||
|
goto finish_return;
|
||||||
|
}
|
||||||
|
|
||||||
num_ipaddrs = 0;
|
num_ipaddrs = 0;
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
GInetAddressMask *mask;
|
GInetAddressMask *mask;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user