Skip to content

Commit 9ba79f0

Browse files
jukkarkartben
authored andcommitted
net: arp: Fix ARP protocol handler to not use Ethernet hdr directly
The ARP protocol handler cannot directly access the Ethernet header because the caller has removed the header already when the handler is called. So change net_arp_input() and pass source and destination MAC address there instead of bogus pointer that was pointing to ARP header instead of Ethernet header. This requires changes to ARP tests. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 8873ff9 commit 9ba79f0

File tree

3 files changed

+28
-20
lines changed

3 files changed

+28
-20
lines changed

subsys/net/l2/ethernet/arp.c

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,6 @@ void net_arp_update(struct net_if *iface,
718718

719719
static inline struct net_pkt *arp_prepare_reply(struct net_if *iface,
720720
struct net_pkt *req,
721-
struct net_eth_hdr *eth_query,
722721
struct net_eth_addr *dst_addr)
723722
{
724723
struct net_arp_hdr *hdr, *query;
@@ -780,18 +779,17 @@ static bool arp_hdr_check(struct net_arp_hdr *arp_hdr)
780779
}
781780

782781
enum net_verdict net_arp_input(struct net_pkt *pkt,
783-
struct net_eth_hdr *eth_hdr)
782+
struct net_eth_addr *src,
783+
struct net_eth_addr *dst)
784784
{
785785
struct net_eth_addr *dst_hw_addr;
786786
struct net_arp_hdr *arp_hdr;
787787
struct net_pkt *reply;
788788
struct in_addr *addr;
789789

790-
if (net_pkt_get_len(pkt) < (sizeof(struct net_arp_hdr) -
791-
(net_pkt_ip_data(pkt) - (uint8_t *)eth_hdr))) {
792-
NET_DBG("Invalid ARP header (len %zu, min %zu bytes) %p",
793-
net_pkt_get_len(pkt), sizeof(struct net_arp_hdr) -
794-
(net_pkt_ip_data(pkt) - (uint8_t *)eth_hdr), pkt);
790+
if (net_pkt_get_len(pkt) < sizeof(struct net_arp_hdr)) {
791+
NET_DBG("DROP: Too short ARP msg (%zu bytes, min %zu bytes)",
792+
net_pkt_get_len(pkt), sizeof(struct net_arp_hdr));
795793
return NET_DROP;
796794
}
797795

@@ -812,7 +810,7 @@ enum net_verdict net_arp_input(struct net_pkt *pkt,
812810
}
813811

814812
if (IS_ENABLED(CONFIG_NET_ARP_GRATUITOUS)) {
815-
if (net_eth_is_addr_broadcast(&eth_hdr->dst) &&
813+
if (net_eth_is_addr_broadcast(dst) &&
816814
(net_eth_is_addr_broadcast(&arp_hdr->dst_hwaddr) ||
817815
net_eth_is_addr_all_zeroes(&arp_hdr->dst_hwaddr)) &&
818816
net_ipv4_addr_cmp_raw(arp_hdr->dst_ipaddr,
@@ -831,7 +829,7 @@ enum net_verdict net_arp_input(struct net_pkt *pkt,
831829
/* Discard ARP request if Ethernet address is broadcast
832830
* and Source IP address is Multicast address.
833831
*/
834-
if (memcmp(&eth_hdr->dst, net_eth_broadcast_addr(),
832+
if (memcmp(dst, net_eth_broadcast_addr(),
835833
sizeof(struct net_eth_addr)) == 0 &&
836834
net_ipv4_is_addr_mcast((struct in_addr *)arp_hdr->src_ipaddr)) {
837835
NET_DBG("DROP: eth addr is bcast, src addr is mcast");
@@ -870,12 +868,11 @@ enum net_verdict net_arp_input(struct net_pkt *pkt,
870868

871869
dst_hw_addr = &arp_hdr->src_hwaddr;
872870
} else {
873-
dst_hw_addr = &eth_hdr->src;
871+
dst_hw_addr = src;
874872
}
875873

876874
/* Send reply */
877-
reply = arp_prepare_reply(net_pkt_iface(pkt), pkt, eth_hdr,
878-
dst_hw_addr);
875+
reply = arp_prepare_reply(net_pkt_iface(pkt), pkt, dst_hw_addr);
879876
if (reply) {
880877
net_if_queue_tx(net_pkt_iface(reply), reply);
881878
} else {
@@ -1022,23 +1019,23 @@ static enum net_verdict arp_recv(struct net_if *iface,
10221019
uint16_t ptype,
10231020
struct net_pkt *pkt)
10241021
{
1025-
struct net_eth_hdr *hdr = NET_ETH_HDR(pkt);
1026-
10271022
ARG_UNUSED(iface);
10281023
ARG_UNUSED(ptype);
10291024

10301025
net_pkt_set_family(pkt, AF_INET);
10311026

10321027
NET_DBG("ARP packet from %s received",
1033-
net_sprint_ll_addr((uint8_t *)hdr->src.addr,
1028+
net_sprint_ll_addr(net_pkt_lladdr_src(pkt)->addr,
10341029
sizeof(struct net_eth_addr)));
10351030

10361031
if (IS_ENABLED(CONFIG_NET_IPV4_ACD) &&
10371032
net_ipv4_acd_input(iface, pkt) == NET_DROP) {
10381033
return NET_DROP;
10391034
}
10401035

1041-
return net_arp_input(pkt, hdr);
1036+
return net_arp_input(pkt,
1037+
(struct net_eth_addr *)net_pkt_lladdr_src(pkt)->addr,
1038+
(struct net_eth_addr *)net_pkt_lladdr_dst(pkt)->addr);
10421039
}
10431040

10441041
ETH_NET_L3_REGISTER(ARP, NET_ETH_PTYPE_ARP, arp_recv);

subsys/net/l2/ethernet/arp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ struct net_pkt *net_arp_prepare(struct net_pkt *pkt,
4747
struct in_addr *request_ip,
4848
struct in_addr *current_ip);
4949
enum net_verdict net_arp_input(struct net_pkt *pkt,
50-
struct net_eth_hdr *eth_hdr);
50+
struct net_eth_addr *src,
51+
struct net_eth_addr *dst);
5152

5253
int net_arp_clear_pending(struct net_if *iface,
5354
struct in_addr *dst);

tests/net/arp/src/main.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ ZTEST(arp_fn_tests, test_arp)
313313
}
314314

315315
struct net_eth_hdr *eth_hdr = NULL;
316+
struct net_eth_addr dst_lladdr;
316317
struct net_pkt *pkt;
317318
struct net_pkt *pkt2;
318319
struct net_if *iface;
@@ -330,6 +331,8 @@ ZTEST(arp_fn_tests, test_arp)
330331

331332
net_arp_init();
332333

334+
(void)memset(&dst_lladdr, 0xff, sizeof(struct net_eth_addr));
335+
333336
iface = net_if_lookup_by_dev(DEVICE_GET(net_arp_test));
334337

335338
net_if_ipv4_set_gw(iface, &gw);
@@ -528,7 +531,9 @@ ZTEST(arp_fn_tests, test_arp)
528531
zassert_not_null(pkt2, "ARP reply generation failed.");
529532

530533
/* The pending packet should now be sent */
531-
switch (net_arp_input(pkt2, eth_hdr)) {
534+
switch (net_arp_input(pkt2,
535+
(struct net_eth_addr *)net_pkt_lladdr_src(pkt2)->addr,
536+
&dst_lladdr)) {
532537
case NET_OK:
533538
case NET_CONTINUE:
534539
break;
@@ -573,7 +578,9 @@ ZTEST(arp_fn_tests, test_arp)
573578

574579
req_test = true;
575580

576-
switch (net_arp_input(pkt2, eth_hdr)) {
581+
switch (net_arp_input(pkt2,
582+
(struct net_eth_addr *)net_pkt_lladdr_src(pkt2)->addr,
583+
&dst_lladdr)) {
577584
case NET_OK:
578585
case NET_CONTINUE:
579586
break;
@@ -630,7 +637,10 @@ ZTEST(arp_fn_tests, test_arp)
630637

631638
net_pkt_set_ll_proto_type(pkt, NET_ETH_PTYPE_ARP);
632639

633-
verdict = net_arp_input(pkt, eth_hdr);
640+
verdict = net_arp_input(pkt,
641+
(struct net_eth_addr *)net_pkt_lladdr_src(pkt)->addr,
642+
&dst_lladdr);
643+
634644
zassert_not_equal(verdict, NET_DROP, "Gratuitous ARP failed");
635645

636646
/* Then check that the HW address is changed for an existing

0 commit comments

Comments
 (0)