|
8 | 8 | * Copyright (c) 2017 Intel Corporation |
9 | 9 | * Copyright (c) 2020 Friedt Professional Engineering Services, Inc |
10 | 10 | * Copyright (c) 2024 Nordic Semiconductor ASA |
| 11 | + * Copyright (c) 2025 SynchronicIT BV |
11 | 12 | * |
12 | 13 | * SPDX-License-Identifier: Apache-2.0 |
13 | 14 | */ |
@@ -110,6 +111,7 @@ static size_t external_records_count; |
110 | 111 |
|
111 | 112 | #ifndef CONFIG_NET_TEST |
112 | 113 | static int setup_dst_addr(int sock, sa_family_t family, |
| 114 | + struct sockaddr *src, socklen_t src_len, |
113 | 115 | struct sockaddr *dst, socklen_t *dst_len); |
114 | 116 | #endif /* CONFIG_NET_TEST */ |
115 | 117 |
|
@@ -194,25 +196,36 @@ static int set_ttl_hop_limit(int sock, int level, int option, int new_limit) |
194 | 196 | } |
195 | 197 |
|
196 | 198 | int setup_dst_addr(int sock, sa_family_t family, |
| 199 | + struct sockaddr *src, socklen_t src_len, |
197 | 200 | struct sockaddr *dst, socklen_t *dst_len) |
198 | 201 | { |
199 | 202 | int ret; |
200 | 203 |
|
201 | 204 | if (IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) { |
202 | | - create_ipv4_addr(net_sin(dst)); |
203 | | - *dst_len = sizeof(struct sockaddr_in); |
| 205 | + if ((src != NULL) && (net_sin(src)->sin_port != htons(MDNS_LISTEN_PORT))) { |
| 206 | + memcpy(dst, src, src_len); |
| 207 | + *dst_len = src_len; |
| 208 | + } else { |
| 209 | + create_ipv4_addr(net_sin(dst)); |
| 210 | + *dst_len = sizeof(struct sockaddr_in); |
204 | 211 |
|
205 | | - ret = set_ttl_hop_limit(sock, IPPROTO_IP, IP_MULTICAST_TTL, 255); |
206 | | - if (ret < 0) { |
207 | | - NET_DBG("Cannot set %s multicast %s (%d)", "IPv4", "TTL", ret); |
| 212 | + ret = set_ttl_hop_limit(sock, IPPROTO_IP, IP_MULTICAST_TTL, 255); |
| 213 | + if (ret < 0) { |
| 214 | + NET_DBG("Cannot set %s multicast %s (%d)", "IPv4", "TTL", ret); |
| 215 | + } |
208 | 216 | } |
209 | 217 | } else if (IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) { |
210 | | - create_ipv6_addr(net_sin6(dst)); |
211 | | - *dst_len = sizeof(struct sockaddr_in6); |
| 218 | + if ((src != NULL) && (net_sin6(src)->sin6_port != htons(MDNS_LISTEN_PORT))) { |
| 219 | + memcpy(dst, src, src_len); |
| 220 | + *dst_len = src_len; |
| 221 | + } else { |
| 222 | + create_ipv6_addr(net_sin6(dst)); |
| 223 | + *dst_len = sizeof(struct sockaddr_in6); |
212 | 224 |
|
213 | | - ret = set_ttl_hop_limit(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 255); |
214 | | - if (ret < 0) { |
215 | | - NET_DBG("Cannot set %s multicast %s (%d)", "IPv6", "hoplimit", ret); |
| 225 | + ret = set_ttl_hop_limit(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 255); |
| 226 | + if (ret < 0) { |
| 227 | + NET_DBG("Cannot set %s multicast %s (%d)", "IPv6", "hoplimit", ret); |
| 228 | + } |
216 | 229 | } |
217 | 230 | } else { |
218 | 231 | return -EPFNOSUPPORT; |
@@ -346,7 +359,7 @@ static int send_response(int sock, |
346 | 359 | COND_CODE_1(IS_ENABLED(CONFIG_NET_IPV6), |
347 | 360 | (struct sockaddr_in6), (struct sockaddr_in)) dst; |
348 | 361 |
|
349 | | - ret = setup_dst_addr(sock, family, (struct sockaddr *)&dst, &dst_len); |
| 362 | + ret = setup_dst_addr(sock, family, src_addr, addrlen, (struct sockaddr *)&dst, &dst_len); |
350 | 363 | if (ret < 0) { |
351 | 364 | NET_DBG("unable to set up the response address"); |
352 | 365 | return ret; |
@@ -456,7 +469,7 @@ static void send_sd_response(int sock, |
456 | 469 | label[2] = proto_buf; |
457 | 470 | label[3] = domain_buf; |
458 | 471 |
|
459 | | - ret = setup_dst_addr(sock, family, (struct sockaddr *)&dst, &dst_len); |
| 472 | + ret = setup_dst_addr(sock, family, src_addr, addrlen, (struct sockaddr *)&dst, &dst_len); |
460 | 473 | if (ret < 0) { |
461 | 474 | NET_DBG("unable to set up the response address"); |
462 | 475 | return; |
@@ -608,12 +621,15 @@ static int dns_read(int sock, |
608 | 621 |
|
609 | 622 | queries = ret; |
610 | 623 |
|
611 | | - NET_DBG("Received %d %s from %s", queries, |
| 624 | + NET_DBG("Received %d %s from %s:%u", queries, |
612 | 625 | queries > 1 ? "queries" : "query", |
613 | 626 | net_sprint_addr(family, |
614 | 627 | family == AF_INET ? |
615 | 628 | (const void *)&net_sin(src_addr)->sin_addr : |
616 | | - (const void *)&net_sin6(src_addr)->sin6_addr)); |
| 629 | + (const void *)&net_sin6(src_addr)->sin6_addr), |
| 630 | + ntohs(family == AF_INET ? |
| 631 | + net_sin(src_addr)->sin_port : |
| 632 | + net_sin6(src_addr)->sin6_port)); |
617 | 633 |
|
618 | 634 | do { |
619 | 635 | enum dns_rr_type qtype; |
@@ -1525,7 +1541,7 @@ static int send_unsolicited_response(struct net_if *iface, |
1525 | 1541 | COND_CODE_1(IS_ENABLED(CONFIG_NET_IPV6), |
1526 | 1542 | (struct sockaddr_in6), (struct sockaddr_in)) dst; |
1527 | 1543 |
|
1528 | | - ret = setup_dst_addr(sock, family, (struct sockaddr *)&dst, &dst_len); |
| 1544 | + ret = setup_dst_addr(sock, family, NULL, 0, (struct sockaddr *)&dst, &dst_len); |
1529 | 1545 | if (ret < 0) { |
1530 | 1546 | NET_DBG("unable to set up the response address"); |
1531 | 1547 | return ret; |
|
0 commit comments