Files
weave-scope/probe/endpoint/nat.go
2015-10-27 10:53:23 +00:00

71 lines
1.8 KiB
Go

package endpoint
import (
"strconv"
"github.com/weaveworks/scope/report"
)
// This is our 'abstraction' of the endpoint that have been rewritten by NAT.
// Original is the private IP that has been rewritten.
type endpointMapping struct {
originalIP string
originalPort int
rewrittenIP string
rewrittenPort int
}
// natMapper rewrites a report to deal with NAT'd connections.
type natMapper struct {
flowWalker
}
func makeNATMapper(fw flowWalker) natMapper {
return natMapper{fw}
}
func toMapping(f flow) *endpointMapping {
var mapping endpointMapping
if f.Original.Layer3.SrcIP == f.Reply.Layer3.DstIP {
mapping = endpointMapping{
originalIP: f.Reply.Layer3.SrcIP,
originalPort: f.Reply.Layer4.SrcPort,
rewrittenIP: f.Original.Layer3.DstIP,
rewrittenPort: f.Original.Layer4.DstPort,
}
} else {
mapping = endpointMapping{
originalIP: f.Original.Layer3.SrcIP,
originalPort: f.Original.Layer4.SrcPort,
rewrittenIP: f.Reply.Layer3.DstIP,
rewrittenPort: f.Reply.Layer4.DstPort,
}
}
return &mapping
}
// applyNAT duplicates Nodes in the endpoint topology of a report, based on
// the NAT table.
func (n natMapper) applyNAT(rpt report.Report, scope string) {
n.flowWalker.walkFlows(func(f flow) {
var (
mapping = toMapping(f)
realEndpointID = report.MakeEndpointNodeID(scope, mapping.originalIP, strconv.Itoa(mapping.originalPort))
copyEndpointPort = strconv.Itoa(mapping.rewrittenPort)
copyEndpointID = report.MakeEndpointNodeID(scope, mapping.rewrittenIP, copyEndpointPort)
node, ok = rpt.Endpoint.Nodes[realEndpointID]
)
if !ok {
return
}
node = node.Copy()
node.Metadata[Addr] = mapping.rewrittenIP
node.Metadata[Port] = copyEndpointPort
node.Metadata["copy_of"] = realEndpointID
rpt.Endpoint.AddNode(copyEndpointID, node)
})
}