- next if !(my($tell,$who_has,$tell_hw)=arp_unpack($msg));
- $V and print localtime()." got: tell=$tell,who_has=$who_has,tell_hw=$tell_hw\n";
- next if $tell eq $who_has; # do not reply to self-detection queries
- my $msg_reply=arp_pack($tell_hw,$hash->{"hw"},$tell,$who_has);
- send $hash->{"sock"},$msg_reply,0,$from_addr or die "send($ifname): $!";
+ next if !(my($tell,$who_has,$tell_hw,$type)=arp_unpack($msg));
+ $V and print localtime()." got: type=$type,tell=$tell,who_has=$who_has,tell_hw=$tell_hw\n";
+ if ($type eq "REQUEST") {
+ next if $tell eq $who_has; # do not reply to self-detection queries
+ my $msg_reply=arp_pack(
+ "FF:FF:FF:FF:FF:FF", # dst_hw
+ $hash->{"hw"}, # src_hw
+ $who_has, # dst
+ $hash->{"ip"}, # src
+ "REQUEST", # type
+ );
+ send $hash->{"sock"},$msg_reply,0,$from_addr or die "send($ifname): $!";
+ $V and print localtime()." probing: type=REQUEST,"
+ ."tell=".$hash->{"ip"}.",who_has=$who_has,tell_hw=".$hash->{"hw"}."\n";
+ push @{$pending{$who_has}},{
+ "when"=>now()+$opt_timeout,
+ "ifname"=>$ifname,
+ "tell" =>$tell,
+ "who_has"=>$who_has,
+ "tell_hw"=>$tell_hw,
+ "from_addr"=>$from_addr,
+ };
+ }
+ elsif ($type eq "REPLY") {
+ # Rename the fields a bit for REPLY
+ my($told,$who,$is_at_hw)=($who_has,$tell,$tell_hw);
+ for my $pending (@{$pending{$who}}) {
+ $V and print localtime()." discarded: "
+ .join(",",map(("$_=".$pending->{$_}),qw(tell who_has tell_hw)))."\n";
+ }
+ delete $pending{$who};
+ }
+ else {
+ die "NOTREACHED";
+ }