Compare commits
9 Commits
v2.87test9
...
v2.87
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4b9bc63e0 | ||
|
|
4447d48bb9 | ||
|
|
04cc2ae1a6 | ||
|
|
32588c755a | ||
|
|
84a6d07cdd | ||
|
|
d6c69f6bdb | ||
|
|
ce372917fe | ||
|
|
09d741f58a | ||
|
|
0666ae3d27 |
@@ -79,6 +79,11 @@ version 2.87
|
||||
This would return <ip> for queries in some.domain, rather than
|
||||
forwarding the query via the default server.
|
||||
|
||||
Tweak DHCPv6 relay code so that packets relayed towards a server
|
||||
have source address on the server-facing network, not the
|
||||
client facing network. Thanks to Luis Thomas for spotting this
|
||||
and initial patch.
|
||||
|
||||
|
||||
version 2.86
|
||||
Handle DHCPREBIND requests in the DHCPv6 server code.
|
||||
|
||||
@@ -1676,10 +1676,8 @@ int cache_make_stat(struct txt_record *t)
|
||||
{
|
||||
/* expand buffer if necessary */
|
||||
newlen = bytes_needed + 1 + bufflen - bytes_avail;
|
||||
if (!(new = whine_malloc(newlen)))
|
||||
if (!(new = whine_realloc(buff, newlen)))
|
||||
return 0;
|
||||
memcpy(new, buff, bufflen);
|
||||
free(buff);
|
||||
p = new + (p - buff);
|
||||
lenp = p - 1;
|
||||
buff = new;
|
||||
|
||||
@@ -685,6 +685,7 @@ static const struct opttab_t {
|
||||
{ "client-machine-id", 97, 0 },
|
||||
{ "posix-timezone", 100, OT_NAME }, /* RFC 4833, Sec. 2 */
|
||||
{ "tzdb-timezone", 101, OT_NAME }, /* RFC 4833, Sec. 2 */
|
||||
{ "ipv6-only", 108, 4 | OT_DEC }, /* RFC 8925 */
|
||||
{ "subnet-select", 118, OT_INTERNAL },
|
||||
{ "domain-search", 119, OT_RFC1035_NAME },
|
||||
{ "sip-server", 120, 0 },
|
||||
|
||||
15
src/dhcp.c
15
src/dhcp.c
@@ -177,8 +177,7 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_DHCP, (void *)daemon->dhcp_packet.iov_base, sz, (union mysockaddr *)&dest, NULL,
|
||||
pxe_fd ? PXE_PORT : daemon->dhcp_server_port);
|
||||
dump_packet_udp(DUMP_DHCP, (void *)daemon->dhcp_packet.iov_base, sz, (union mysockaddr *)&dest, NULL, fd);
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_LINUX_NETWORK)
|
||||
@@ -464,8 +463,8 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
dest.sin_addr = mess->yiaddr;
|
||||
dest.sin_port = htons(daemon->dhcp_client_port);
|
||||
|
||||
dump_packet(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
|
||||
(union mysockaddr *)&dest, daemon->dhcp_server_port);
|
||||
dump_packet_udp(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
|
||||
(union mysockaddr *)&dest, fd);
|
||||
#endif
|
||||
|
||||
send_via_bpf(mess, iov.iov_len, iface_addr, &ifr);
|
||||
@@ -478,8 +477,8 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
|
||||
(union mysockaddr *)&dest, daemon->dhcp_server_port);
|
||||
dump_packet_udp(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
|
||||
(union mysockaddr *)&dest, fd);
|
||||
#endif
|
||||
|
||||
while(retry_send(sendmsg(fd, &msg, 0)));
|
||||
@@ -1147,8 +1146,8 @@ static int relay_upstream4(int iface_index, struct dhcp_packet *mess, size_t sz)
|
||||
fromsock.in.sin_port = htons(daemon->dhcp_server_port);
|
||||
fromsock.in.sin_addr = from.addr4;
|
||||
fromsock.sa.sa_family = AF_INET;
|
||||
|
||||
dump_packet(DUMP_DHCP, (void *)mess, sz, &fromsock, &to, 0);
|
||||
|
||||
dump_packet_udp(DUMP_DHCP, (void *)mess, sz, &fromsock, &to, -1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
12
src/dhcp6.c
12
src/dhcp6.c
@@ -119,8 +119,8 @@ void dhcp6_packet(time_t now)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_DHCPV6, (void *)daemon->dhcp_packet.iov_base, sz,
|
||||
(union mysockaddr *)&from, NULL, DHCPV6_SERVER_PORT);
|
||||
dump_packet_udp(DUMP_DHCPV6, (void *)daemon->dhcp_packet.iov_base, sz,
|
||||
(union mysockaddr *)&from, NULL, daemon->dhcp6fd);
|
||||
#endif
|
||||
|
||||
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
|
||||
@@ -142,8 +142,8 @@ void dhcp6_packet(time_t now)
|
||||
if (relay_reply6(&from, sz, ifr.ifr_name))
|
||||
{
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1), NULL,
|
||||
(union mysockaddr *)&from, DHCPV6_SERVER_PORT);
|
||||
dump_packet_udp(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1), NULL,
|
||||
(union mysockaddr *)&from, daemon->dhcp6fd);
|
||||
#endif
|
||||
|
||||
while (retry_send(sendto(daemon->dhcp6fd, daemon->outpacket.iov_base,
|
||||
@@ -254,8 +254,8 @@ void dhcp6_packet(time_t now)
|
||||
from.sin6_port = htons(port);
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1),
|
||||
NULL, (union mysockaddr *)&from, DHCPV6_SERVER_PORT);
|
||||
dump_packet_udp(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1),
|
||||
NULL, (union mysockaddr *)&from, daemon->dhcp6fd);
|
||||
#endif
|
||||
|
||||
while (retry_send(sendto(daemon->dhcp6fd, daemon->outpacket.iov_base,
|
||||
|
||||
@@ -1396,6 +1396,7 @@ void *safe_malloc(size_t size);
|
||||
void safe_strncpy(char *dest, const char *src, size_t size);
|
||||
void safe_pipe(int *fd, int read_noblock);
|
||||
void *whine_malloc(size_t size);
|
||||
void *whine_realloc(void *ptr, size_t size);
|
||||
int sa_len(union mysockaddr *addr);
|
||||
int sockaddr_isequal(const union mysockaddr *s1, const union mysockaddr *s2);
|
||||
int hostname_order(const char *a, const char *b);
|
||||
@@ -1802,8 +1803,10 @@ int do_arp_script_run(void);
|
||||
/* dump.c */
|
||||
#ifdef HAVE_DUMPFILE
|
||||
void dump_init(void);
|
||||
void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src,
|
||||
union mysockaddr *dst, int port);
|
||||
void dump_packet_udp(int mask, void *packet, size_t len, union mysockaddr *src,
|
||||
union mysockaddr *dst, int fd);
|
||||
void dump_packet_icmp(int mask, void *packet, size_t len, union mysockaddr *src,
|
||||
union mysockaddr *dst);
|
||||
#endif
|
||||
|
||||
/* domain-match.c */
|
||||
|
||||
125
src/dump.c
125
src/dump.c
@@ -21,6 +21,8 @@
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
static u32 packet_count;
|
||||
static void do_dump_packet(int mask, void *packet, size_t len,
|
||||
union mysockaddr *src, union mysockaddr *dst, int port, int proto);
|
||||
|
||||
/* https://wiki.wireshark.org/Development/LibpcapFileFormat */
|
||||
struct pcap_hdr_s {
|
||||
@@ -81,9 +83,45 @@ void dump_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* port == -1 ->ICMPv6 */
|
||||
void dump_packet(int mask, void *packet, size_t len,
|
||||
union mysockaddr *src, union mysockaddr *dst, int port)
|
||||
void dump_packet_udp(int mask, void *packet, size_t len,
|
||||
union mysockaddr *src, union mysockaddr *dst, int fd)
|
||||
{
|
||||
union mysockaddr fd_addr;
|
||||
socklen_t addr_len = sizeof(fd_addr);
|
||||
|
||||
if (daemon->dumpfd != -1 && (mask & daemon->dump_mask))
|
||||
{
|
||||
/* if fd is negative it carries a port number (negated)
|
||||
which we use as a source or destination when not otherwise
|
||||
specified so wireshark can ID the packet.
|
||||
If both src and dst are specified, set this to -1 to avoid
|
||||
a spurious getsockname() call. */
|
||||
int port = (fd < 0) ? -fd : -1;
|
||||
|
||||
/* fd >= 0 is a file descriptor and the address of that file descriptor is used
|
||||
in place of a NULL src or dst. */
|
||||
if (fd >= 0 && getsockname(fd, (struct sockaddr *)&fd_addr, &addr_len) != -1)
|
||||
{
|
||||
if (!src)
|
||||
src = &fd_addr;
|
||||
|
||||
if (!dst)
|
||||
dst = &fd_addr;
|
||||
}
|
||||
|
||||
do_dump_packet(mask, packet, len, src, dst, port, IPPROTO_UDP);
|
||||
}
|
||||
}
|
||||
|
||||
void dump_packet_icmp(int mask, void *packet, size_t len,
|
||||
union mysockaddr *src, union mysockaddr *dst)
|
||||
{
|
||||
if (daemon->dumpfd != -1 && (mask & daemon->dump_mask))
|
||||
do_dump_packet(mask, packet, len, src, dst, -1, IPPROTO_ICMP);
|
||||
}
|
||||
|
||||
static void do_dump_packet(int mask, void *packet, size_t len,
|
||||
union mysockaddr *src, union mysockaddr *dst, int port, int proto)
|
||||
{
|
||||
struct ip ip;
|
||||
struct ip6_hdr ip6;
|
||||
@@ -100,13 +138,14 @@ void dump_packet(int mask, void *packet, size_t len,
|
||||
void *iphdr;
|
||||
size_t ipsz;
|
||||
int rc;
|
||||
|
||||
/* if port != -1 it carries a port number
|
||||
which we use as a source or destination when not otherwise
|
||||
specified so wireshark can ID the packet.
|
||||
If both src and dst are specified, set this to -1 to avoid
|
||||
a spurious getsockname() call. */
|
||||
udp.uh_sport = udp.uh_dport = htons(port < 0 ? 0 : port);
|
||||
|
||||
if (daemon->dumpfd == -1 || !(mask & daemon->dump_mask))
|
||||
return;
|
||||
|
||||
/* So wireshark can Id the packet. */
|
||||
udp.uh_sport = udp.uh_dport = htons(port);
|
||||
|
||||
if (src)
|
||||
family = src->sa.sa_family;
|
||||
else
|
||||
@@ -121,15 +160,12 @@ void dump_packet(int mask, void *packet, size_t len,
|
||||
ip6.ip6_vfc = 6 << 4;
|
||||
ip6.ip6_hops = 64;
|
||||
|
||||
if (port == -1)
|
||||
{
|
||||
ip6.ip6_plen = htons(len);
|
||||
ip6.ip6_nxt = IPPROTO_ICMPV6;
|
||||
}
|
||||
if ((ip6.ip6_nxt = proto) == IPPROTO_UDP)
|
||||
ip6.ip6_plen = htons(sizeof(struct udphdr) + len);
|
||||
else
|
||||
{
|
||||
ip6.ip6_plen = htons(sizeof(struct udphdr) + len);
|
||||
ip6.ip6_nxt = IPPROTO_UDP;
|
||||
proto = ip6.ip6_nxt = IPPROTO_ICMPV6;
|
||||
ip6.ip6_plen = htons(len);
|
||||
}
|
||||
|
||||
if (src)
|
||||
@@ -161,15 +197,12 @@ void dump_packet(int mask, void *packet, size_t len,
|
||||
ip.ip_hl = sizeof(struct ip) / 4;
|
||||
ip.ip_ttl = IPDEFTTL;
|
||||
|
||||
if (port == -1)
|
||||
{
|
||||
ip.ip_len = htons(sizeof(struct ip) + len);
|
||||
ip.ip_p = IPPROTO_ICMP;
|
||||
}
|
||||
if ((ip.ip_p = proto) == IPPROTO_UDP)
|
||||
ip.ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + len);
|
||||
else
|
||||
{
|
||||
ip.ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + len);
|
||||
ip.ip_p = IPPROTO_UDP;
|
||||
ip.ip_len = htons(sizeof(struct ip) + len);
|
||||
proto = ip.ip_p = IPPROTO_ICMP;
|
||||
}
|
||||
|
||||
if (src)
|
||||
@@ -191,7 +224,7 @@ void dump_packet(int mask, void *packet, size_t len,
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
ip.ip_sum = (sum == 0xffff) ? sum : ~sum;
|
||||
|
||||
/* start UDP checksum */
|
||||
/* start UDP/ICMP checksum */
|
||||
sum = ip.ip_src.s_addr & 0xffff;
|
||||
sum += (ip.ip_src.s_addr >> 16) & 0xffff;
|
||||
sum += ip.ip_dst.s_addr & 0xffff;
|
||||
@@ -201,25 +234,7 @@ void dump_packet(int mask, void *packet, size_t len,
|
||||
if (len & 1)
|
||||
((unsigned char *)packet)[len] = 0; /* for checksum, in case length is odd. */
|
||||
|
||||
if (port == -1)
|
||||
{
|
||||
/* ICMP - ICMPv6 packet is a superset of ICMP */
|
||||
struct icmp6_hdr *icmp = packet;
|
||||
|
||||
/* See comment in UDP code below. */
|
||||
sum += htons((family == AF_INET6) ? IPPROTO_ICMPV6 : IPPROTO_ICMP);
|
||||
sum += htons(len);
|
||||
|
||||
icmp->icmp6_cksum = 0;
|
||||
for (i = 0; i < (len + 1) / 2; i++)
|
||||
sum += ((u16 *)packet)[i];
|
||||
while (sum >> 16)
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
icmp->icmp6_cksum = (sum == 0xffff) ? sum : ~sum;
|
||||
|
||||
pcap_header.incl_len = pcap_header.orig_len = ipsz + len;
|
||||
}
|
||||
else
|
||||
if (proto == IPPROTO_UDP)
|
||||
{
|
||||
/* Add Remaining part of the pseudoheader. Note that though the
|
||||
IPv6 pseudoheader is very different to the IPv4 one, the
|
||||
@@ -241,7 +256,25 @@ void dump_packet(int mask, void *packet, size_t len,
|
||||
|
||||
pcap_header.incl_len = pcap_header.orig_len = ipsz + sizeof(udp) + len;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* ICMP - ICMPv6 packet is a superset of ICMP */
|
||||
struct icmp6_hdr *icmp = packet;
|
||||
|
||||
/* See comment in UDP code above. */
|
||||
sum += htons(proto);
|
||||
sum += htons(len);
|
||||
|
||||
icmp->icmp6_cksum = 0;
|
||||
for (i = 0; i < (len + 1) / 2; i++)
|
||||
sum += ((u16 *)packet)[i];
|
||||
while (sum >> 16)
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
icmp->icmp6_cksum = (sum == 0xffff) ? sum : ~sum;
|
||||
|
||||
pcap_header.incl_len = pcap_header.orig_len = ipsz + len;
|
||||
}
|
||||
|
||||
rc = gettimeofday(&time, NULL);
|
||||
pcap_header.ts_sec = time.tv_sec;
|
||||
pcap_header.ts_usec = time.tv_usec;
|
||||
@@ -249,9 +282,11 @@ void dump_packet(int mask, void *packet, size_t len,
|
||||
if (rc == -1 ||
|
||||
!read_write(daemon->dumpfd, (void *)&pcap_header, sizeof(pcap_header), 0) ||
|
||||
!read_write(daemon->dumpfd, iphdr, ipsz, 0) ||
|
||||
(port != -1 && !read_write(daemon->dumpfd, (void *)&udp, sizeof(udp), 0)) ||
|
||||
(proto == IPPROTO_UDP && !read_write(daemon->dumpfd, (void *)&udp, sizeof(udp), 0)) ||
|
||||
!read_write(daemon->dumpfd, (void *)packet, len, 0))
|
||||
my_syslog(LOG_ERR, _("failed to write packet dump"));
|
||||
else if (option_bool(OPT_EXTRALOG))
|
||||
my_syslog(LOG_INFO, _("%u dumping packet %u mask 0x%04x"), daemon->log_display_id, ++packet_count, mask);
|
||||
else
|
||||
my_syslog(LOG_INFO, _("dumping packet %u mask 0x%04x"), ++packet_count, mask);
|
||||
|
||||
|
||||
@@ -244,6 +244,14 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
||||
if (!daemon->free_frec_src)
|
||||
{
|
||||
query_full(now, NULL);
|
||||
/* This is tricky; if we're blasted with the same query
|
||||
over and over, we'll end up taking this path each time
|
||||
and never resetting until the frec gets deleted by
|
||||
aging followed by the receipt of a different query. This
|
||||
is a bit of a DoS vuln. Avoid by explicitly deleting the
|
||||
frec once it expires. */
|
||||
if (difftime(now, forward->time) >= TIMEOUT)
|
||||
free_frec(forward);
|
||||
goto reply;
|
||||
}
|
||||
|
||||
@@ -510,7 +518,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
||||
if (errno == 0)
|
||||
{
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_UP_QUERY, (void *)header, plen, NULL, &srv->addr, daemon->port);
|
||||
dump_packet_udp(DUMP_UP_QUERY, (void *)header, plen, NULL, &srv->addr, fd);
|
||||
#endif
|
||||
|
||||
/* Keep info in case we want to re-send this packet */
|
||||
@@ -839,8 +847,8 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
|
||||
NULL, NULL, NULL);
|
||||
#ifdef HAVE_DUMPFILE
|
||||
if (STAT_ISEQUAL(status, STAT_BOGUS))
|
||||
dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_BOGUS : DUMP_BOGUS,
|
||||
header, (size_t)plen, &forward->sentto->addr, NULL, daemon->port);
|
||||
dump_packet_udp((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_BOGUS : DUMP_BOGUS,
|
||||
header, (size_t)plen, &forward->sentto->addr, NULL, -daemon->port);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -950,13 +958,13 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
|
||||
set_outgoing_mark(orig, fd);
|
||||
#endif
|
||||
|
||||
server_send(server, fd, header, nn, 0);
|
||||
server->queries++;
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_SEC_QUERY, (void *)header, (size_t)nn, NULL, &server->addr, daemon->port);
|
||||
dump_packet_udp(DUMP_SEC_QUERY, (void *)header, (size_t)nn, NULL, &server->addr, fd);
|
||||
#endif
|
||||
log_query_mysockaddr(F_NOEXTRA | F_DNSSEC | F_SERVER, daemon->keyname, &server->addr,
|
||||
STAT_ISEQUAL(status, STAT_NEED_KEY) ? "dnssec-query[DNSKEY]" : "dnssec-query[DS]", 0);
|
||||
server_send(server, fd, header, nn, 0);
|
||||
server->queries++;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1045,16 +1053,16 @@ void reply_query(int fd, time_t now)
|
||||
if (difftime(now, server->pktsz_reduced) > UDP_TEST_TIME)
|
||||
server->edns_pktsz = daemon->edns_pktsz;
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_REPLY : DUMP_UP_REPLY,
|
||||
(void *)header, n, &serveraddr, NULL, daemon->port);
|
||||
#endif
|
||||
|
||||
/* log_query gets called indirectly all over the place, so
|
||||
pass these in global variables - sorry. */
|
||||
daemon->log_display_id = forward->frec_src.log_id;
|
||||
daemon->log_source_addr = &forward->frec_src.source;
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet_udp((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_REPLY : DUMP_UP_REPLY,
|
||||
(void *)header, n, &serveraddr, NULL, fd);
|
||||
#endif
|
||||
|
||||
if (daemon->ignore_addr && RCODE(header) == NOERROR &&
|
||||
check_for_ignored_address(header, n))
|
||||
return;
|
||||
@@ -1073,12 +1081,15 @@ void reply_query(int fd, time_t now)
|
||||
size_t nn = 0;
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
/* DNSSEC queries have a copy of the original query stashed.
|
||||
The query MAY have got a good answer, and be awaiting
|
||||
/* The query MAY have got a good answer, and be awaiting
|
||||
the results of further queries, in which case
|
||||
The Stash contains something else and we don't need to retry anyway. */
|
||||
if ((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) && !forward->blocking_query)
|
||||
if (forward->blocking_query)
|
||||
return;
|
||||
|
||||
if (forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY))
|
||||
{
|
||||
/* DNSSEC queries have a copy of the original query stashed. */
|
||||
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
|
||||
nn = forward->stash_len;
|
||||
udp_size = daemon->edns_pktsz;
|
||||
@@ -1144,6 +1155,13 @@ void reply_query(int fd, time_t now)
|
||||
}
|
||||
|
||||
forward->sentto = server;
|
||||
|
||||
/* We have a good answer, and will now validate it or return it.
|
||||
It may be some time before this the validation completes, but we don't need
|
||||
any more answers, so close the socket(s) on which we were expecting
|
||||
answers, to conserve file descriptors, and to save work reading and
|
||||
discarding answers for other upstreams. */
|
||||
free_rfds(&forward->rfds);
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
if ((forward->sentto->flags & SERV_DO_DNSSEC) &&
|
||||
@@ -1251,7 +1269,7 @@ static void return_reply(time_t now, struct frec *forward, struct dns_header *he
|
||||
header->id = htons(src->orig_id);
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_REPLY, daemon->packet, (size_t)nn, NULL, &src->source, daemon->port);
|
||||
dump_packet_udp(DUMP_REPLY, daemon->packet, (size_t)nn, NULL, &src->source, src->fd);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
|
||||
@@ -1566,7 +1584,7 @@ void receive_query(struct listener *listen, time_t now)
|
||||
daemon->log_source_addr = &source_addr;
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_QUERY, daemon->packet, (size_t)n, &source_addr, NULL, daemon->port);
|
||||
dump_packet_udp(DUMP_QUERY, daemon->packet, (size_t)n, &source_addr, NULL, listen->fd);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONNTRACK
|
||||
@@ -1653,7 +1671,7 @@ void receive_query(struct listener *listen, time_t now)
|
||||
if (m >= 1)
|
||||
{
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_REPLY, daemon->packet, m, NULL, &source_addr, daemon->port);
|
||||
dump_packet_udp(DUMP_REPLY, daemon->packet, m, NULL, &source_addr, listen->fd);
|
||||
#endif
|
||||
send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
|
||||
(char *)header, m, &source_addr, &dst_addr, if_index);
|
||||
@@ -1669,7 +1687,7 @@ void receive_query(struct listener *listen, time_t now)
|
||||
if (m >= 1)
|
||||
{
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_REPLY, daemon->packet, m, NULL, &source_addr, daemon->port);
|
||||
dump_packet_udp(DUMP_REPLY, daemon->packet, m, NULL, &source_addr, listen->fd);
|
||||
#endif
|
||||
#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
|
||||
if (local_auth)
|
||||
@@ -1695,7 +1713,7 @@ void receive_query(struct listener *listen, time_t now)
|
||||
if (m >= 1)
|
||||
{
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_REPLY, daemon->packet, m, NULL, &source_addr, daemon->port);
|
||||
dump_packet_udp(DUMP_REPLY, daemon->packet, m, NULL, &source_addr, listen->fd);
|
||||
#endif
|
||||
#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
|
||||
if (option_bool(OPT_CMARK_ALST_EN) && have_mark && ((u32)mark & daemon->allowlist_mask))
|
||||
|
||||
@@ -1180,17 +1180,11 @@ void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, unsigned
|
||||
if ((lease->extradata_size - lease->extradata_len) < (len + 1))
|
||||
{
|
||||
size_t newsz = lease->extradata_len + len + 100;
|
||||
unsigned char *new = whine_malloc(newsz);
|
||||
unsigned char *new = whine_realloc(lease->extradata, newsz);
|
||||
|
||||
if (!new)
|
||||
return;
|
||||
|
||||
if (lease->extradata)
|
||||
{
|
||||
memcpy(new, lease->extradata, lease->extradata_len);
|
||||
free(lease->extradata);
|
||||
}
|
||||
|
||||
lease->extradata = new;
|
||||
lease->extradata_size = newsz;
|
||||
}
|
||||
|
||||
17
src/poll.c
17
src/poll.c
@@ -96,28 +96,21 @@ void poll_listen(int fd, short event)
|
||||
pollfds[i].events |= event;
|
||||
else
|
||||
{
|
||||
if (arrsize != nfds)
|
||||
memmove(&pollfds[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
|
||||
else
|
||||
if (arrsize == nfds)
|
||||
{
|
||||
/* Array too small, extend. */
|
||||
struct pollfd *new;
|
||||
|
||||
arrsize = (arrsize == 0) ? 64 : arrsize * 2;
|
||||
|
||||
if (!(new = whine_malloc(arrsize * sizeof(struct pollfd))))
|
||||
if (!(new = whine_realloc(pollfds, arrsize * sizeof(struct pollfd))))
|
||||
return;
|
||||
|
||||
if (pollfds)
|
||||
{
|
||||
memcpy(new, pollfds, i * sizeof(struct pollfd));
|
||||
memcpy(&new[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
|
||||
free(pollfds);
|
||||
}
|
||||
|
||||
pollfds = new;
|
||||
}
|
||||
|
||||
|
||||
memmove(&pollfds[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
|
||||
|
||||
pollfds[i].fd = fd;
|
||||
pollfds[i].events = event;
|
||||
nfds++;
|
||||
|
||||
10
src/radv.c
10
src/radv.c
@@ -203,7 +203,7 @@ void icmp6_packet(time_t now)
|
||||
int opt_sz;
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_RA, (void *)packet, sz, (union mysockaddr *)&from, NULL, -1);
|
||||
dump_packet_icmp(DUMP_RA, (void *)packet, sz, (union mysockaddr *)&from, NULL);
|
||||
#endif
|
||||
|
||||
/* look for link-layer address option for logging */
|
||||
@@ -560,7 +560,13 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
|
||||
}
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_RA, (void *)daemon->outpacket.iov_base, save_counter(-1), NULL, (union mysockaddr *)&addr, -1);
|
||||
{
|
||||
struct sockaddr_in6 src;
|
||||
src.sin6_family = AF_INET6;
|
||||
src.sin6_addr = parm.link_local;
|
||||
|
||||
dump_packet_icmp(DUMP_RA, (void *)daemon->outpacket.iov_base, save_counter(-1), (union mysockaddr *)&src, (union mysockaddr *)&addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
while (retry_send(sendto(daemon->icmp6fd, daemon->outpacket.iov_base,
|
||||
|
||||
@@ -2181,10 +2181,7 @@ int relay_upstream6(int iface_index, ssize_t sz,
|
||||
if (relay->iface_index != 0 && relay->iface_index == iface_index)
|
||||
{
|
||||
union mysockaddr to;
|
||||
union all_addr from;
|
||||
|
||||
/* source address == relay address */
|
||||
from.addr6 = relay->local.addr6;
|
||||
|
||||
memcpy(&header[2], &relay->local.addr6, IN6ADDRSZ);
|
||||
|
||||
to.sa.sa_family = AF_INET6;
|
||||
@@ -2206,18 +2203,11 @@ int relay_upstream6(int iface_index, ssize_t sz,
|
||||
}
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
{
|
||||
union mysockaddr fromsock;
|
||||
fromsock.in6.sin6_port = htons(DHCPV6_SERVER_PORT);
|
||||
fromsock.in6.sin6_addr = from.addr6;
|
||||
fromsock.sa.sa_family = AF_INET6;
|
||||
fromsock.in6.sin6_flowinfo = 0;
|
||||
fromsock.in6.sin6_scope_id = 0;
|
||||
|
||||
dump_packet(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1), &fromsock, &to, 0);
|
||||
}
|
||||
dump_packet_udp(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1), NULL, &to, daemon->dhcp6fd);
|
||||
#endif
|
||||
send_from(daemon->dhcp6fd, 0, daemon->outpacket.iov_base, save_counter(-1), &to, &from, 0);
|
||||
|
||||
while (retry_send(sendto(daemon->dhcp6fd, (void *)daemon->outpacket.iov_base, save_counter(-1),
|
||||
0, (struct sockaddr *)&to, sa_len(&to))));
|
||||
|
||||
if (option_bool(OPT_LOG_OPTS))
|
||||
{
|
||||
|
||||
@@ -159,7 +159,7 @@ static int check_rrs(unsigned char *p, struct dns_header *header, size_t plen, i
|
||||
/* mode may be remove EDNS0 or DNSSEC RRs or remove A or AAAA from answer section. */
|
||||
size_t rrfilter(struct dns_header *header, size_t plen, int mode)
|
||||
{
|
||||
static unsigned char **rrs;
|
||||
static unsigned char **rrs = NULL;
|
||||
static int rr_sz = 0;
|
||||
|
||||
unsigned char *p = (unsigned char *)(header+1);
|
||||
@@ -339,15 +339,11 @@ int expand_workspace(unsigned char ***wkspc, int *szp, int new)
|
||||
return 0;
|
||||
|
||||
new += 5;
|
||||
|
||||
if (!(p = whine_malloc(new * sizeof(unsigned char *))))
|
||||
return 0;
|
||||
|
||||
if (old != 0 && *wkspc)
|
||||
{
|
||||
memcpy(p, *wkspc, old * sizeof(unsigned char *));
|
||||
free(*wkspc);
|
||||
}
|
||||
|
||||
if (!(p = whine_realloc(*wkspc, new * sizeof(unsigned char *))))
|
||||
return 0;
|
||||
|
||||
memset(p+old, 0, new-old);
|
||||
|
||||
*wkspc = p;
|
||||
*szp = new;
|
||||
|
||||
@@ -97,7 +97,7 @@ void tftp_request(struct listener *listen, time_t now)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_TFTP, (void *)packet, len, (union mysockaddr *)&peer, NULL, TFTP_PORT);
|
||||
dump_packet_udp(DUMP_TFTP, (void *)packet, len, (union mysockaddr *)&peer, NULL, listen->tftpfd);
|
||||
#endif
|
||||
|
||||
/* Can always get recvd interface for IPv6 */
|
||||
@@ -488,7 +488,7 @@ void tftp_request(struct listener *listen, time_t now)
|
||||
send_from(transfer->sockfd, !option_bool(OPT_SINGLE_PORT), packet, len, &peer, &addra, if_index);
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_TFTP, (void *)packet, len, NULL, (union mysockaddr *)&peer, TFTP_PORT);
|
||||
dump_packet_udp(DUMP_TFTP, (void *)packet, len, NULL, (union mysockaddr *)&peer, transfer->sockfd);
|
||||
#endif
|
||||
|
||||
if (is_err)
|
||||
@@ -610,7 +610,7 @@ void check_tftp_listeners(time_t now)
|
||||
while(retry_send(sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer))));
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_TFTP, (void *)daemon->packet, len, NULL, (union mysockaddr *)&peer, TFTP_PORT);
|
||||
dump_packet_udp(DUMP_TFTP, (void *)daemon->packet, len, NULL, (union mysockaddr *)&peer, transfer->sockfd);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -650,7 +650,7 @@ void check_tftp_listeners(time_t now)
|
||||
send_from(transfer->sockfd, !option_bool(OPT_SINGLE_PORT), daemon->packet, len,
|
||||
&transfer->peer, &transfer->source, transfer->if_index);
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_TFTP, (void *)daemon->packet, len, NULL, (union mysockaddr *)&transfer->peer, TFTP_PORT);
|
||||
dump_packet_udp(DUMP_TFTP, (void *)daemon->packet, len, NULL, (union mysockaddr *)&transfer->peer, transfer->sockfd);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
10
src/util.c
10
src/util.c
@@ -336,6 +336,16 @@ void *whine_malloc(size_t size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *whine_realloc(void *ptr, size_t size)
|
||||
{
|
||||
void *ret = realloc(ptr, size);
|
||||
|
||||
if (!ret)
|
||||
my_syslog(LOG_ERR, _("failed to reallocate %d bytes"), (int) size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sockaddr_isequal(const union mysockaddr *s1, const union mysockaddr *s2)
|
||||
{
|
||||
if (s1->sa.sa_family == s2->sa.sa_family)
|
||||
|
||||
Reference in New Issue
Block a user