mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2025-01-14 06:00:59 +00:00
[FEATURE] Support for Source-Specific Multicast (#802)
* Support for Source-Specific Multicast * fixing whitespace issues * updating changelog
This commit is contained in:
parent
44a9e8b2af
commit
59b8f81283
@ -1,3 +1,7 @@
|
||||
0.87
|
||||
-----------------
|
||||
- New: Support for source-specific multicast.
|
||||
|
||||
0.86
|
||||
-----------------
|
||||
- New: Added a histogram in one-minute increments of the number of lines in a subtitle.
|
||||
|
@ -48,7 +48,7 @@ void draw_network_popup(struct nk_context *ctx, struct network_popup *network_se
|
||||
nk_label(ctx, "UDP:", NK_TEXT_CENTERED);
|
||||
nk_layout_row_static(ctx, 20, 200, 2);
|
||||
nk_label(ctx, "Hostname/IPv4 Address:", NK_TEXT_LEFT);
|
||||
nk_edit_string(ctx, NK_EDIT_SIMPLE, network_settings->udp_ipv4, &network_settings->udp_ipv4_len, 25, nk_filter_default);
|
||||
nk_edit_string(ctx, NK_EDIT_SIMPLE, network_settings->udp_ipv4, &network_settings->udp_ipv4_len, 50, nk_filter_default);
|
||||
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 21, 3, udp_tcp_ratio);
|
||||
nk_spacing(ctx, 1);
|
||||
|
@ -90,6 +90,7 @@ void init_options (struct ccx_s_options *options)
|
||||
options->debug_mask=CCX_DMT_GENERIC_NOTICES; // dbg_print will use this mask to print or ignore different types
|
||||
options->debug_mask_on_debug=CCX_DMT_VERBOSE; // If we're using temp_debug to enable/disable debug "live", this is the mask when temp_debug=1
|
||||
/* Networking */
|
||||
options->udpsrc = NULL;
|
||||
options->udpaddr = NULL;
|
||||
options->udpport=0; // Non-zero => Listen for UDP packets on this port, no files.
|
||||
options->send_to_srv = 0;
|
||||
|
@ -157,6 +157,7 @@ struct ccx_s_options // Options from user parameters
|
||||
LLONG debug_mask; // dbg_print will use this mask to print or ignore different types
|
||||
LLONG debug_mask_on_debug; // If we're using temp_debug to enable/disable debug "live", this is the mask when temp_debug=1
|
||||
/* Networking */
|
||||
char *udpsrc;
|
||||
char *udpaddr;
|
||||
unsigned udpport; // Non-zero => Listen for UDP packets on this port, no files.
|
||||
char *tcpport;
|
||||
|
@ -78,7 +78,7 @@ static int ccx_demuxer_open(struct ccx_demuxer *ctx, const char *file)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->infd = start_upd_srv(ccx_options.udpaddr, ccx_options.udpport);
|
||||
ctx->infd = start_upd_srv(ccx_options.udpsrc, ccx_options.udpaddr, ccx_options.udpport);
|
||||
if(ctx->infd < 0)
|
||||
{
|
||||
print_error(ccx_options.gui_mode_reports,"socket() failed.");
|
||||
|
@ -927,10 +927,28 @@ ssize_t read_byte(int fd, char *ch)
|
||||
return readn(fd, ch, 1);
|
||||
}
|
||||
|
||||
int start_upd_srv(const char *addr_str, unsigned port)
|
||||
int start_upd_srv(const char *src_str, const char *addr_str, unsigned port)
|
||||
{
|
||||
init_sockets();
|
||||
|
||||
in_addr_t src;
|
||||
if (src_str != NULL)
|
||||
{
|
||||
struct hostent *host = gethostbyname(src_str);
|
||||
if (NULL == host)
|
||||
{
|
||||
fatal(EXIT_MALFORMED_PARAMETER, "Cannot look up udp network address: %s\n",
|
||||
src_str);
|
||||
}
|
||||
else if (host->h_addrtype != AF_INET)
|
||||
{
|
||||
fatal(EXIT_MALFORMED_PARAMETER, "No support for non-IPv4 network addresses: %s\n",
|
||||
src_str);
|
||||
}
|
||||
|
||||
src = ntohl(((struct in_addr *)host->h_addr_list[0])->s_addr);
|
||||
}
|
||||
|
||||
in_addr_t addr;
|
||||
if (addr_str != NULL)
|
||||
{
|
||||
@ -1000,10 +1018,23 @@ int start_upd_srv(const char *addr_str, unsigned port)
|
||||
}
|
||||
|
||||
if (IN_MULTICAST(addr)) {
|
||||
struct ip_mreq group;
|
||||
group.imr_multiaddr.s_addr = htonl(addr);
|
||||
group.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0)
|
||||
int setsockopt_return = 0;
|
||||
if (src_str != NULL) {
|
||||
struct ip_mreq_source multicast_req;
|
||||
multicast_req.imr_sourceaddr.s_addr = htonl(src);
|
||||
multicast_req.imr_multiaddr.s_addr = htonl(addr);
|
||||
multicast_req.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
setsockopt_return = setsockopt(sockfd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (char *)&multicast_req, sizeof(multicast_req));
|
||||
}
|
||||
else
|
||||
{
|
||||
struct ip_mreq multicast_req;
|
||||
multicast_req.imr_multiaddr.s_addr = htonl(addr);
|
||||
multicast_req.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
setsockopt_return = setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&multicast_req, sizeof(multicast_req));
|
||||
}
|
||||
|
||||
if (setsockopt_return < 0)
|
||||
{
|
||||
#if _WIN32
|
||||
wprintf(L"setsockopt() error: %ld\n", WSAGetLastError());
|
||||
@ -1019,6 +1050,21 @@ int start_upd_srv(const char *addr_str, unsigned port)
|
||||
{
|
||||
mprint("\rReading from UDP socket %u\n", port);
|
||||
}
|
||||
else if (src_str != NULL)
|
||||
{
|
||||
struct in_addr source;
|
||||
struct in_addr group;
|
||||
char src_ip[15];
|
||||
char addr_ip[15];
|
||||
source.s_addr = htonl(src);
|
||||
memset(src_ip, 0, sizeof(char) * 15);
|
||||
memcpy(src_ip, inet_ntoa(source), sizeof(src_ip));
|
||||
group.s_addr = htonl(addr);
|
||||
memset(addr_ip, 0, sizeof(char) * 15);
|
||||
memcpy(addr_ip, inet_ntoa(group), sizeof(addr_ip));
|
||||
|
||||
mprint("\rReading from UDP socket %s@%s:%u\n", src_ip, addr_ip, port);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct in_addr in;
|
||||
|
@ -23,6 +23,6 @@ int net_tcp_read(int socket, void *buffer, size_t length);
|
||||
|
||||
int start_tcp_srv(const char *port, const char *pwd);
|
||||
|
||||
int start_upd_srv(const char *addr, unsigned port);
|
||||
int start_upd_srv(const char *src, const char *addr, unsigned port);
|
||||
|
||||
#endif /* end of include guard: NETWORKING_H */
|
||||
|
@ -335,6 +335,10 @@ void print_usage (void)
|
||||
mprint (" port) instead of reading a file. Host can be a\n");
|
||||
mprint (" hostname or IPv4 address. If host is not specified\n");
|
||||
mprint (" then listens on the local host.\n\n");
|
||||
mprint (" -udp [src@host:]port: Read the input via UDP (listening in the specified\n");
|
||||
mprint (" port) instead of reading a file. Host and src can be a\n");
|
||||
mprint (" hostname or IPv4 address. If host is not specified\n");
|
||||
mprint (" then listens on the local host.\n\n");
|
||||
mprint (" -sendto host[:port]: Sends data in BIN format to the server\n");
|
||||
mprint (" according to the CCExtractor's protocol over\n");
|
||||
mprint (" TCP. For IPv6 use [address]:port\n");
|
||||
@ -2220,8 +2224,21 @@ int parse_parameters (struct ccx_s_options *opt, int argc, char *argv[])
|
||||
/* Network stuff */
|
||||
if (strcmp (argv[i],"-udp")==0 && i<argc-1)
|
||||
{
|
||||
char *at = strchr(argv[i + 1], '@');
|
||||
char *colon = strchr(argv[i + 1], ':');
|
||||
if (colon)
|
||||
if (at && !colon)
|
||||
{
|
||||
fatal(EXIT_MALFORMED_PARAMETER, "If -udp contains an '@', it must also contain a ':'");
|
||||
}
|
||||
else if (at && colon)
|
||||
{
|
||||
*at = '\0';
|
||||
*colon = '\0';
|
||||
opt->udpsrc = argv[i + 1];
|
||||
opt->udpaddr = at + 1;
|
||||
opt->udpport = atoi_hex(colon + 1);
|
||||
}
|
||||
else if (colon)
|
||||
{
|
||||
*colon = '\0';
|
||||
opt->udpaddr = argv[i + 1];
|
||||
|
@ -18,7 +18,9 @@ void params_dump(struct lib_ccx_ctx *ctx)
|
||||
mprint ("stdin");
|
||||
break;
|
||||
case CCX_DS_NETWORK:
|
||||
if (ccx_options.udpaddr == NULL)
|
||||
if (ccx_options.udpsrc != NULL)
|
||||
mprint ("Network, %s@%s:%d", ccx_options.udpsrc, ccx_options.udpaddr, ccx_options.udpport);
|
||||
else if (ccx_options.udpaddr == NULL)
|
||||
mprint ("Network, UDP/%u",ccx_options.udpport);
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user