1 /* GStreamer UDP network utility functions
2 * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
3 * Copyright (C) 2006 Joni Valtanen <joni.valtanen@movial.fi>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
29 /* EAI_ADDRFAMILY was obsoleted in BSD at some point */
30 #ifndef EAI_ADDRFAMILY
31 #define EAI_ADDRFAMILY 1
34 #include "gstudpnetutils.h"
39 gst_udp_net_utils_win32_wsa_startup (GstObject * obj)
44 error = WSAStartup (0x0202, &w);
47 GST_WARNING_OBJECT (obj, "WSAStartup error: %d", error);
51 if (w.wVersion != 0x0202) {
53 GST_WARNING_OBJECT (obj, "Winsock version wrong : 0x%x", w.wVersion);
63 gst_udp_get_addr (const char *hostname, int port, struct sockaddr_storage *addr)
65 struct addrinfo hints, *res, *nres;
66 char service[NI_MAXSERV];
69 memset (&hints, 0, sizeof (hints));
70 hints.ai_family = AF_UNSPEC;
71 hints.ai_socktype = SOCK_DGRAM;
72 snprintf (service, sizeof (service) - 1, "%d", port);
73 service[sizeof (service) - 1] = '\0';
75 if ((ret = getaddrinfo (hostname, (port == -1) ? NULL : service, &hints,
82 if (nres->ai_family == AF_INET || nres->ai_family == AF_INET6)
88 memcpy (addr, nres->ai_addr, nres->ai_addrlen);
90 errno = EAI_ADDRFAMILY;
99 gst_udp_set_loop_ttl (int sockfd, gboolean loop, int ttl)
104 int l = (loop == FALSE) ? 0 : 1;
106 switch (addr->ss_family) {
110 setsockopt (sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &l,
115 setsockopt (sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
123 setsockopt (sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &l,
128 setsockopt (sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl,
135 errno = EAFNOSUPPORT;
142 gst_udp_join_group (int sockfd, struct sockaddr_storage *addr)
146 switch (addr->ss_family) {
149 struct ip_mreq mreq4;
151 mreq4.imr_multiaddr.s_addr =
152 ((struct sockaddr_in *) addr)->sin_addr.s_addr;
153 mreq4.imr_interface.s_addr = INADDR_ANY;
156 setsockopt (sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
157 (const void *) &mreq4, sizeof (mreq4))) < 0)
164 struct ipv6_mreq mreq6;
166 memcpy (&mreq6.ipv6mr_multiaddr,
167 &(((struct sockaddr_in6 *) addr)->sin6_addr),
168 sizeof (struct in6_addr));
169 mreq6.ipv6mr_interface = 0;
172 setsockopt (sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
173 (const void *) &mreq6, sizeof (mreq6))) < 0)
179 errno = EAFNOSUPPORT;
185 gst_udp_leave_group (int sockfd, struct sockaddr_storage *addr)
189 switch (addr->ss_family) {
192 struct ip_mreq mreq4;
194 mreq4.imr_multiaddr.s_addr =
195 ((struct sockaddr_in *) addr)->sin_addr.s_addr;
196 mreq4.imr_interface.s_addr = INADDR_ANY;
199 setsockopt (sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
200 (const void *) &mreq4, sizeof (mreq4))) < 0)
207 struct ipv6_mreq mreq6;
209 memcpy (&mreq6.ipv6mr_multiaddr,
210 &(((struct sockaddr_in6 *) addr)->sin6_addr),
211 sizeof (struct in6_addr));
212 mreq6.ipv6mr_interface = 0;
215 setsockopt (sockfd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
216 (const void *) &mreq6, sizeof (mreq6))) < 0)
222 errno = EAFNOSUPPORT;
229 gst_udp_is_multicast (struct sockaddr_storage *addr)
233 switch (addr->ss_family) {
236 struct sockaddr_in *addr4 = (struct sockaddr_in *) addr;
238 ret = IN_MULTICAST (g_ntohl (addr4->sin_addr.s_addr));
244 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr;
246 ret = IN6_IS_ADDR_MULTICAST (&addr6->sin6_addr);
251 errno = EAFNOSUPPORT;