@@ -440,6 +440,23 @@ static void arp_update(struct net_if *iface,
440440 if (entry ) {
441441 memcpy (& entry -> eth , hwaddr ,
442442 sizeof (struct net_eth_addr ));
443+ } else {
444+ /* Add new entry as it was not found and force
445+ * was set.
446+ */
447+ entry = arp_entry_get_free ();
448+ if (!entry ) {
449+ /* Then let's take one from table? */
450+ entry = arp_entry_get_last_from_table ();
451+ }
452+
453+ if (entry ) {
454+ entry -> req_start = k_uptime_get ();
455+ entry -> iface = iface ;
456+ net_ipaddr_copy (& entry -> ip , src );
457+ memcpy (& entry -> eth , hwaddr , sizeof (entry -> eth ));
458+ sys_slist_prepend (& arp_table , & entry -> node );
459+ }
443460 }
444461 }
445462
@@ -468,7 +485,8 @@ static void arp_update(struct net_if *iface,
468485
469486static inline struct net_pkt * arp_prepare_reply (struct net_if * iface ,
470487 struct net_pkt * req ,
471- struct net_eth_hdr * eth_query )
488+ struct net_eth_hdr * eth_query ,
489+ struct net_eth_addr * dst_addr )
472490{
473491 struct net_arp_hdr * hdr , * query ;
474492 struct net_pkt * pkt ;
@@ -492,7 +510,7 @@ static inline struct net_pkt *arp_prepare_reply(struct net_if *iface,
492510 hdr -> protolen = sizeof (struct in_addr );
493511 hdr -> opcode = htons (NET_ARP_REPLY );
494512
495- memcpy (& hdr -> dst_hwaddr .addr , & eth_query -> src . addr ,
513+ memcpy (& hdr -> dst_hwaddr .addr , & dst_addr -> addr ,
496514 sizeof (struct net_eth_addr ));
497515 memcpy (& hdr -> src_hwaddr .addr , net_if_get_link_addr (iface )-> addr ,
498516 sizeof (struct net_eth_addr ));
@@ -526,6 +544,7 @@ static bool arp_hdr_check(struct net_arp_hdr *arp_hdr)
526544enum net_verdict net_arp_input (struct net_pkt * pkt ,
527545 struct net_eth_hdr * eth_hdr )
528546{
547+ struct net_eth_addr * dst_hw_addr ;
529548 struct net_arp_hdr * arp_hdr ;
530549 struct net_pkt * reply ;
531550 struct in_addr * addr ;
@@ -594,9 +613,7 @@ enum net_verdict net_arp_input(struct net_pkt *pkt,
594613 * changed. In this case the target MAC address is all zeros
595614 * and the target IP address is our address.
596615 */
597- if (memcmp (& eth_hdr -> src , & arp_hdr -> src_hwaddr ,
598- sizeof (struct net_eth_addr )) == 0 &&
599- net_eth_is_addr_unspecified (& arp_hdr -> dst_hwaddr )) {
616+ if (net_eth_is_addr_unspecified (& arp_hdr -> dst_hwaddr )) {
600617 NET_DBG ("Updating ARP cache for %s [%s]" ,
601618 log_strdup (net_sprint_ipv4_addr (
602619 & arp_hdr -> src_ipaddr )),
@@ -608,10 +625,15 @@ enum net_verdict net_arp_input(struct net_pkt *pkt,
608625 & arp_hdr -> src_ipaddr ,
609626 & arp_hdr -> src_hwaddr ,
610627 false, true);
628+
629+ dst_hw_addr = & arp_hdr -> src_hwaddr ;
630+ } else {
631+ dst_hw_addr = & eth_hdr -> src ;
611632 }
612633
613634 /* Send reply */
614- reply = arp_prepare_reply (net_pkt_iface (pkt ), pkt , eth_hdr );
635+ reply = arp_prepare_reply (net_pkt_iface (pkt ), pkt , eth_hdr ,
636+ dst_hw_addr );
615637 if (reply ) {
616638 net_if_queue_tx (net_pkt_iface (reply ), reply );
617639 } else {
0 commit comments