You have some misconceptions.
No fancy tools/techniques to prevent two hosts to have the same IP
address with different MAC addresses.
That is an OS requirement for your hosts, nothing special or fancy. See RFC 5227, IPv4 Address Conflict Detection (note what I highlighted):
2.1. Probing an Address
Before beginning to use an IPv4 address (whether received from manual
configuration, DHCP, or some other means), a host implementing this
specification MUST test to see if the address is already in use, by
broadcasting ARP Probe packets. This also applies when a network
interface transitions from an inactive to an active state, when a
computer awakes from sleep, when a link-state change signals that an
Ethernet cable has been connected, when an 802.11 wireless interface
associates with a new base station, or when any other change in
connectivity occurs where a host becomes actively connected to a
If the device "A" were a host then such "A" host would update its ARP
table based on packets received because end hosts don't normally do
extra checks on arriving packets, they just look at the src MAC
address and IP address and update the ARP table accordingly.
No, they do not. Only ARP packets update ARP tables. That is a requirement in the RFC, and a frame with an EtherType for IPv4 (0x0800) or IPv6 (0x86DD) is sent to the corresponding IP process, not the ARP process. Only frames with the ARP EtherType (0x0806) are sent to the ARP process. Even reception of unsolicited ARP packets will not create an entry in the ARP table; that will only update an existing entry in the ARP table (see the pseudocode below).
On the contrary, if the device "A" were a firewall what I know is that
the first ICMP echo request will update the FW's ARP table whereas the
second will do nothing, meaning that the FW will keep the first entry.
Not exactly, but closer. Receiving an ICMP echo request will not update the ARP table, but sending an ICMP echo reply may if the ARP table does not already have the destination and needs to update it with an ARP request.
This answer is related.
RFC 826, An Ethernet Address Resolution Protocol has the pseudocode for updating the ARP table:
When an address resolution packet is received, the receiving Ethernet
module gives the packet to the Address Resolution module which goes
through an algorithm similar to the following. Negative conditionals
indicate an end of processing and a discarding of the packet.
?Do I have the hardware type in ar$hrd?
Yes: (almost definitely)
[optionally check the hardware length ar$hln]
?Do I speak the protocol in ar$pro?
[optionally check the protocol length ar$pln]
Merge_flag := false
If the pair <protocol type, sender protocol address> is
already in my translation table, update the sender
hardware address field of the entry with the new
information in the packet and set Merge_flag to true.
?Am I the target protocol address?
If Merge_flag is false, add the triplet <protocol type,
sender protocol address, sender hardware address> to
the translation table.
?Is the opcode ares_op$REQUEST? (NOW look at the opcode!!)
Swap hardware and protocol fields, putting the local
hardware and protocol addresses in the sender fields.
Set the ar$op field to ares_op$REPLY
Send the packet to the (new) target hardware address on
the same hardware on which the request was received.
Notice that the <protocol type, sender protocol address, sender
hardware address> triplet is merged into the table before the opcode
is looked at. This is on the assumption that communcation is
bidirectional; if A has some reason to talk to B, then B will probably
have some reason to talk to A. Notice also that if an entry already
exists for the <protocol type, sender protocol address> pair, then the
new hardware address supersedes the old one. Related Issues gives some
motivation for this.