4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with FFmpeg; if not, write to the Free Software * Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "libavutil/avstring.h"
24 #include "libavutil/mem.h"
26 static int compare_addr(const struct sockaddr_storage
*a
,
27 const struct sockaddr_storage
*b
)
29 if (a
->ss_family
!= b
->ss_family
)
31 if (a
->ss_family
== AF_INET
) {
32 return (((const struct sockaddr_in
*)a
)->sin_addr
.s_addr
!=
33 ((const struct sockaddr_in
*)b
)->sin_addr
.s_addr
);
36 #if HAVE_STRUCT_SOCKADDR_IN6
37 if (a
->ss_family
== AF_INET6
) {
38 const uint8_t *s6_addr_a
= ((const struct sockaddr_in6
*)a
)->sin6_addr
.s6_addr
;
39 const uint8_t *s6_addr_b
= ((const struct sockaddr_in6
*)b
)->sin6_addr
.s6_addr
;
40 return memcmp(s6_addr_a
, s6_addr_b
, 16);
46 int ff_ip_check_source_lists(struct sockaddr_storage
*source_addr_ptr
, IPSourceFilters
*s
)
49 if (s
->nb_exclude_addrs
) {
50 for (i
= 0; i
< s
->nb_exclude_addrs
; i
++) {
51 if (!compare_addr(source_addr_ptr
, &s
->exclude_addrs
[i
]))
55 if (s
->nb_include_addrs
) {
56 for (i
= 0; i
< s
->nb_include_addrs
; i
++) {
57 if (!compare_addr(source_addr_ptr
, &s
->include_addrs
[i
]))
65 struct addrinfo
*ff_ip_resolve_host(void *log_ctx
,
66 const char *hostname
, int port
,
67 int type
, int family
, int flags
)
69 struct addrinfo hints
= { 0 }, *res
= 0;
72 const char *node
= 0, *service
= "0";
75 snprintf(sport
, sizeof(sport
), "%d", port
);
78 if ((hostname
) && (hostname
[0] != '\0') && (hostname
[0] != '?')) {
81 hints
.ai_socktype
= type
;
82 hints
.ai_family
= family
;
83 hints
.ai_flags
= flags
;
84 if ((error
= getaddrinfo(node
, service
, &hints
, &res
))) {
86 av_log(log_ctx
, AV_LOG_ERROR
, "getaddrinfo(%s, %s): %s\n",
87 node
? node
: "unknown",
96 static int ip_parse_addr_list(void *log_ctx
, const char *buf
,
97 struct sockaddr_storage
**address_list_ptr
,
98 int *address_list_size_ptr
)
100 struct addrinfo
*ai
= NULL
;
102 /* Resolve all of the IPs */
104 while (buf
&& buf
[0]) {
105 char* host
= av_get_token(&buf
, ",");
107 return AVERROR(ENOMEM
);
109 ai
= ff_ip_resolve_host(log_ctx
, host
, 0, SOCK_DGRAM
, AF_UNSPEC
, 0);
113 struct sockaddr_storage source_addr
= {0};
114 memcpy(&source_addr
, ai
->ai_addr
, ai
->ai_addrlen
);
116 av_dynarray2_add((void **)address_list_ptr
, address_list_size_ptr
, sizeof(source_addr
), (uint8_t *)&source_addr
);
117 if (!*address_list_ptr
)
118 return AVERROR(ENOMEM
);
120 return AVERROR(EINVAL
);
130 static int ip_parse_sources_and_blocks(void *log_ctx
, const char *buf
, IPSourceFilters
*filters
, int parse_include_list
)
133 if (parse_include_list
)
134 ret
= ip_parse_addr_list(log_ctx
, buf
, &filters
->include_addrs
, &filters
->nb_include_addrs
);
136 ret
= ip_parse_addr_list(log_ctx
, buf
, &filters
->exclude_addrs
, &filters
->nb_exclude_addrs
);
138 if (ret
>= 0 && filters
->nb_include_addrs
&& filters
->nb_exclude_addrs
) {
139 av_log(log_ctx
, AV_LOG_ERROR
, "Simultaneously including and excluding sources is not supported.\n");
140 return AVERROR(EINVAL
);
145 int ff_ip_parse_sources(void *log_ctx
, const char *buf
, IPSourceFilters
*filters
)
147 return ip_parse_sources_and_blocks(log_ctx
, buf
, filters
, 1);
150 int ff_ip_parse_blocks(void *log_ctx
, const char *buf
, IPSourceFilters
*filters
)
152 return ip_parse_sources_and_blocks(log_ctx
, buf
, filters
, 0);
155 void ff_ip_reset_filters(IPSourceFilters
*filters
)
157 av_freep(&filters
->exclude_addrs
);
158 av_freep(&filters
->include_addrs
);
159 filters
->nb_include_addrs
= 0;
160 filters
->nb_exclude_addrs
= 0;