Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libdvbpsi
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
libdvbpsi
Commits
4da7ecbf
Commit
4da7ecbf
authored
Sep 17, 2012
by
Jean-Paul Saman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dvbinfo: add support for multicast and ipv6
parent
e1ac8d51
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
130 additions
and
4 deletions
+130
-4
examples/dvbinfo/udp.c
examples/dvbinfo/udp.c
+129
-3
examples/dvbinfo/udp.h
examples/dvbinfo/udp.h
+1
-1
No files found.
examples/dvbinfo/udp.c
View file @
4da7ecbf
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#include <errno.h>
#include <string.h>
#include <string.h>
#include <unistd.h>
#include <unistd.h>
...
@@ -34,7 +35,9 @@
...
@@ -34,7 +35,9 @@
#ifdef HAVE_SYS_SOCKET_H
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <netinet/in.h>
# include <net/if.h>
# ifdef HAVE_NET_IF_H
# include <net/if.h>
# endif
# if defined(WIN32)
# if defined(WIN32)
# include <netinet/if_ether.h>
# include <netinet/if_ether.h>
# endif
# endif
...
@@ -46,9 +49,122 @@
...
@@ -46,9 +49,122 @@
# include <arpa/inet.h>
# include <arpa/inet.h>
#endif
#endif
#include <assert.h>
#include "udp.h"
#include "udp.h"
#ifdef HAVE_SYS_SOCKET_H
#ifdef HAVE_SYS_SOCKET_H
static
bool
is_multicast
(
const
struct
sockaddr
*
addr
,
socklen_t
len
)
{
switch
(
addr
->
sa_family
)
{
#if defined(IN_MULTICAST)
case
AF_INET
:
{
const
struct
sockaddr_in
*
ip
=
(
const
struct
sockaddr_in
*
)
addr
;
if
((
size_t
)
len
<
sizeof
(
*
ip
))
return
false
;
return
IN_MULTICAST
(
ntohl
(
ip
->
sin_addr
.
s_addr
))
!=
0
;
}
#endif
#if defined(IN6_IS_ADDR_MULTICAST)
case
AF_INET6
:
{
const
struct
sockaddr_in6
*
ip6
=
(
const
struct
sockaddr_in6
*
)
addr
;
if
((
size_t
)
len
<
sizeof
(
*
ip6
))
return
false
;
return
IN6_IS_ADDR_MULTICAST
(
&
ip6
->
sin6_addr
)
!=
0
;
}
#endif
}
return
false
;
}
static
bool
mcast_connect
(
int
socket
,
const
char
*
interface
,
const
struct
sockaddr
*
addr
,
socklen_t
len
)
{
unsigned
int
ifindex
=
interface
?
if_nametoindex
(
interface
)
:
0
;
#if defined(MCAST_JOIN_GROUP)
/* Source Specific Multicast Join */
struct
group_req
greq
;
memset
(
&
greq
,
0
,
sizeof
(
greq
));
if
(
ifindex
==
0
)
return
false
;
greq
.
gr_interface
=
ifindex
;
assert
(
len
<=
sizeof
(
greq
.
gr_group
));
memcpy
(
&
greq
.
gr_group
,
addr
,
len
);
switch
(
addr
->
sa_family
)
{
case
AF_INET6
:
{
const
struct
sockaddr_in6
*
sin6
=
(
const
struct
sockaddr_in6
*
)
addr
;
assert
(
len
>=
sizeof
(
struct
sockaddr_in6
));
if
(
sin6
->
sin6_scope_id
!=
0
)
greq
.
gr_interface
=
sin6
->
sin6_scope_id
;
if
(
setsockopt
(
socket
,
SOL_IPV6
,
MCAST_JOIN_GROUP
,
&
greq
,
sizeof
(
greq
))
==
0
)
return
true
;
break
;
}
case
AF_INET
:
if
(
setsockopt
(
socket
,
SOL_IP
,
MCAST_JOIN_GROUP
,
&
greq
,
sizeof
(
greq
))
==
0
)
return
true
;
break
;
default:
return
false
;
}
#else
switch
(
addr
->
sa_family
)
{
case
AF_INET6
:
{
struct
ipv6_mreq
ipv6mr
;
const
struct
sockaddr_in6
*
ip6
=
(
const
struct
sockaddr_in6
*
)
addr
;
memset
(
&
ipv6mr
,
0
,
sizeof
(
ipv6mr
));
assert
(
len
>=
sizeof
(
struct
sockaddr_in6
));
ipv6mr
.
ipv6mr_multiaddr
=
ip6
->
sin6_addr
;
ipv6mr
.
ipv6mr_interface
=
(
ifindex
>
0
)
?
ifindex
:
ip6
->
sin6_scope_id
;
# ifdef IPV6_JOIN_GROUP
if
(
setsockopt
(
socket
,
SOL_IPV6
,
IPV6_JOIN_GROUP
,
&
ipv6mr
,
sizeof
(
ipv6mr
))
==
0
)
# else
if
(
setsockopt
(
socket
,
SOL_IPV6
,
IPV6_ADD_MEMBERSHIP
,
&
ipv6mr
,
sizeof
(
ipv6mr
))
==
0
)
# endif
return
true
;
break
;
}
# ifdef IP_ADD_MEMBERSHIP
case
AF_INET
:
{
struct
ip_mreq
imr
;
memset
(
&
imr
,
0
,
sizeof
(
imr
));
assert
(
len
>=
sizeof
(
struct
sockaddr_in
));
imr
.
imr_multiaddr
=
((
const
struct
sockaddr_in
*
)
addr
)
->
sin_addr
;
#if 0 /* TODO: Source Specific Multicast Join */
if (ifaddr) /* Linux specific interface bound multicast address */
imr.imr_address.s_addr = if_addr;
if (ifindex > 0)
imr.imr_index = ifindex;
#endif
if
(
setsockopt
(
socket
,
SOL_IP
,
IP_ADD_MEMBERSHIP
,
&
imr
,
sizeof
(
imr
))
==
0
)
return
true
;
break
;
}
# endif
}
#endif
return
false
;
}
static
bool
is_ipv6
(
const
char
*
ipaddress
)
{
/* NOTE: we assume the address does not include the port number */
return
(
strchr
(
ipaddress
,
':'
)
!=
NULL
);
}
int
udp_close
(
int
fd
)
int
udp_close
(
int
fd
)
{
{
int
result
=
0
;
int
result
=
0
;
...
@@ -59,7 +175,7 @@ int udp_close(int fd)
...
@@ -59,7 +175,7 @@ int udp_close(int fd)
return
result
;
return
result
;
}
}
int
udp_open
(
const
char
*
ipaddress
,
int
port
)
int
udp_open
(
const
char
*
i
nterface
,
const
char
*
i
paddress
,
int
port
)
{
{
int
s_ctl
=
-
1
;
int
s_ctl
=
-
1
;
int
result
=
-
1
;
int
result
=
-
1
;
...
@@ -79,7 +195,7 @@ int udp_open(const char *ipaddress, int port)
...
@@ -79,7 +195,7 @@ int udp_open(const char *ipaddress, int port)
return
-
1
;
return
-
1
;
memset
(
&
hints
,
0
,
sizeof
(
hints
));
memset
(
&
hints
,
0
,
sizeof
(
hints
));
hints
.
ai_family
=
AF_INET
;
/* use AF_INET6 for ipv6 */
hints
.
ai_family
=
is_ipv6
(
ipaddress
)
?
AF_INET6
:
AF_INET
;
hints
.
ai_socktype
=
SOCK_DGRAM
;
hints
.
ai_socktype
=
SOCK_DGRAM
;
hints
.
ai_protocol
=
IPPROTO_TCP
;
hints
.
ai_protocol
=
IPPROTO_TCP
;
hints
.
ai_flags
=
IPPROTO_UDP
|
0
;
hints
.
ai_flags
=
IPPROTO_UDP
|
0
;
...
@@ -117,6 +233,16 @@ int udp_open(const char *ipaddress, int port)
...
@@ -117,6 +233,16 @@ int udp_open(const char *ipaddress, int port)
perror
(
"udp bind error"
);
perror
(
"udp bind error"
);
continue
;
continue
;
}
}
if
(
is_multicast
(
ptr
->
ai_addr
,
ptr
->
ai_addrlen
)
&&
mcast_connect
(
s_ctl
,
NULL
,
ptr
->
ai_addr
,
ptr
->
ai_addrlen
))
{
close
(
s_ctl
);
perror
(
"mcast connect error"
);
continue
;
}
break
;
}
}
freeaddrinfo
(
addr
);
freeaddrinfo
(
addr
);
...
...
examples/dvbinfo/udp.h
View file @
4da7ecbf
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
#ifndef DVBINFO_UDP_H_
#ifndef DVBINFO_UDP_H_
#define DVBINFO_UDP_H_
#define DVBINFO_UDP_H_
int
udp_open
(
const
char
*
ipaddress
,
int
port
);
int
udp_open
(
const
char
*
i
nterface
,
const
char
*
i
paddress
,
int
port
);
int
udp_close
(
int
fd
);
int
udp_close
(
int
fd
);
ssize_t
udp_read
(
int
fd
,
void
*
buf
,
size_t
count
);
ssize_t
udp_read
(
int
fd
,
void
*
buf
,
size_t
count
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment