Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arp: set and check arp state #27

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions arp.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ const (
)

// Add either adds a new entry or updates an ArpEntry in the ArpTable syncmap.
func (t *ArpTable) Add(IP string, mac net.HardwareAddr, timeNow time.Time) error {
func (t *ArpTable) Add(IP string, mac net.HardwareAddr, timeNow time.Time, status ArpStatus) error {
if IP == "" {
return errors.New("valid IP address must be provided")
}
ip := net.ParseIP(IP)
t.ArpMap.Store(IP, &ArpEntry{IP: ip, Mac: mac, Status: StatusReady, Timestamp: timeNow})
t.ArpMap.Store(IP, &ArpEntry{IP: ip, Mac: mac, Status: status, Timestamp: timeNow})
return nil
}

Expand All @@ -78,8 +78,10 @@ func (t *ArpTable) Get(IP string) (*ArpEntry, bool, error) {
return nil, false, errors.New("invalid ARP entry type")
}

if arpEntry.Mac == nil {
return nil, false, errors.New("invalid ARP entry")
// Update the status from waiting to stale to express that the waiting time (2seconds) has expired
// This will allow us to send again an ARP request
if arpEntry.Status == StatusWaiting && arpEntry.Timestamp.Add(time.Second*2).Before(time.Now()) {
arpEntry.Status = StatusStale
}

return arpEntry, found, nil
Expand Down Expand Up @@ -138,7 +140,7 @@ func GenerateARPRequest(arpTable *ArpTable, srcMAC []byte, dstIP string, srcIP s

// FIXME this function should be .Upsert() (Add or Update the entry)
if arpTable != nil {
err := arpTable.Add(dstIP, net.HardwareAddr{}, time.Now())
err := arpTable.Add(dstIP, net.HardwareAddr{}, time.Now(), StatusWaiting)
if err != nil {
return nil, fmt.Errorf("unable to add waiting ARP entry: %v", err)
}
Expand Down
8 changes: 4 additions & 4 deletions network.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func ReadUTUN() {
Lerror.Printf("unable to retrieve ARP entry for %v: %v", dstIP.String(), err)
}

if found {
if found && entry.Status == StatusReady {
// We found the destination MAC in the ARP table, continue to craft
// the ethernet header of the IP packet.

Expand All @@ -163,7 +163,7 @@ func ReadUTUN() {
}
Ldebug.Printf("wrote %d bytes to vswitch\n", b)

} else {
} else if !found || found && entry.Status == StatusStale {

// TODO: Queue ethernet frame while ARP is being resolving the dst MAC address

Expand Down Expand Up @@ -394,7 +394,7 @@ func connSwitch(ctx context.Context, cancel context.CancelFunc, config *tls.Conf
if oper == OperationReply {
Ldebug.Printf("Received ARP response\n")
// We received an ARP response
err := arpTable.Add(spa.String(), sha, time.Now())
err := arpTable.Add(spa.String(), sha, time.Now(), StatusReady)
if err != nil {
Lerror.Printf("unable to update ARP entry: %v", err)
}
Expand All @@ -405,7 +405,7 @@ func connSwitch(ctx context.Context, cancel context.CancelFunc, config *tls.Conf
// ETH src MAC match the arp SHA AND arp SPA match TPA
if bytes.Equal(frameBuf[10:16], frameBuf[26:32]) && bytes.Equal(frameBuf[32:36], frameBuf[42:46]) {
Ldebug.Printf("we received an GARP")
arpTable.Add(spa.String(), sha, time.Now())
arpTable.Add(spa.String(), sha, time.Now(), StatusReady)
} else {
// We received an ARP request, send a response
sendBuf := GenerateARPReply(gMAC[0:6], sha, tpa, spa)
Expand Down