pull/16/head v0.0.2
Bruce Leidl 9 years ago
parent 7f94d3189e
commit 2d4c127f4e

@ -4,21 +4,21 @@ import (
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt" "fmt"
"github.com/subgraph/fw-daemon/Godeps/_workspace/src/github.com/op/go-logging"
"io/ioutil" "io/ioutil"
"net" "net"
"strconv" "strconv"
"strings" "strings"
"github.com/subgraph/fw-daemon/Godeps/_workspace/src/github.com/op/go-logging"
) )
var log = logging.MustGetLogger("proc") var log = logging.MustGetLogger("proc")
func SetLogger(logger *logging.Logger) { func SetLogger(logger *logging.Logger) {
log = logger log = logger
} }
var pcache = &pidCache{} var pcache = &pidCache{}
func LookupUDPSocketProcess(srcPort uint16) *ProcInfo { func LookupUDPSocketProcess(srcPort uint16) *ProcInfo {
ss := findUDPSocket(srcPort) ss := findUDPSocket(srcPort)
if ss == nil { if ss == nil {
@ -36,8 +36,8 @@ func LookupTCPSocketProcess(srcPort uint16, dstAddr net.IP, dstPort uint16) *Pro
} }
type ConnectionInfo struct { type ConnectionInfo struct {
pinfo *ProcInfo pinfo *ProcInfo
local *socketAddr local *socketAddr
remote *socketAddr remote *socketAddr
} }
@ -63,7 +63,6 @@ func (sa *socketAddr) parse(s string) error {
return nil return nil
} }
func ParseIp(ip string) (net.IP, error) { func ParseIp(ip string) (net.IP, error) {
var result net.IP var result net.IP
dst, err := hex.DecodeString(ip) dst, err := hex.DecodeString(ip)
@ -88,7 +87,7 @@ func ParsePort(port string) (uint16, error) {
} }
func getConnections() ([]*ConnectionInfo, error) { func getConnections() ([]*ConnectionInfo, error) {
conns,err := readConntrack() conns, err := readConntrack()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -98,7 +97,7 @@ func getConnections() ([]*ConnectionInfo, error) {
func resolveProcinfo(conns []*ConnectionInfo) { func resolveProcinfo(conns []*ConnectionInfo) {
var sockets []*socketStatus var sockets []*socketStatus
for _,line := range getSocketLines("tcp") { for _, line := range getSocketLines("tcp") {
if len(strings.TrimSpace(line)) == 0 { if len(strings.TrimSpace(line)) == 0 {
continue continue
} }
@ -107,16 +106,16 @@ func resolveProcinfo(conns []*ConnectionInfo) {
log.Warning("Unable to parse line [%s]: %v", line, err) log.Warning("Unable to parse line [%s]: %v", line, err)
} else { } else {
/* /*
pid := findPidForInode(ss.inode) pid := findPidForInode(ss.inode)
if pid > 0 { if pid > 0 {
ss.pid = pid ss.pid = pid
fmt.Println("Socket", ss) fmt.Println("Socket", ss)
sockets = append(sockets, ss) sockets = append(sockets, ss)
} }
*/ */
} }
} }
for _,ci := range conns { for _, ci := range conns {
ss := findContrackSocket(ci, sockets) ss := findContrackSocket(ci, sockets)
if ss == nil { if ss == nil {
continue continue
@ -129,7 +128,7 @@ func resolveProcinfo(conns []*ConnectionInfo) {
} }
func findContrackSocket(ci *ConnectionInfo, sockets []*socketStatus) *socketStatus { func findContrackSocket(ci *ConnectionInfo, sockets []*socketStatus) *socketStatus {
for _,ss := range sockets { for _, ss := range sockets {
if ss.local.port == ci.local.port && ss.remote.ip.Equal(ci.remote.ip) && ss.remote.port == ci.remote.port { if ss.local.port == ci.local.port && ss.remote.ip.Equal(ci.remote.ip) && ss.remote.port == ci.remote.port {
return ss return ss
} }
@ -145,8 +144,8 @@ func readConntrack() ([]*ConnectionInfo, error) {
} }
var result []*ConnectionInfo var result []*ConnectionInfo
lines := strings.Split(string(data), "\n") lines := strings.Split(string(data), "\n")
for _,line := range(lines) { for _, line := range lines {
ci,err := parseConntrackLine(line) ci, err := parseConntrackLine(line)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -163,33 +162,33 @@ func parseConntrackLine(line string) (*ConnectionInfo, error) {
return nil, nil return nil, nil
} }
local,err := conntrackAddr(parts[4], parts[6]) local, err := conntrackAddr(parts[4], parts[6])
if err != nil { if err != nil {
return nil, err return nil, err
} }
remote,err := conntrackAddr(parts[5], parts[7]) remote, err := conntrackAddr(parts[5], parts[7])
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &ConnectionInfo{ return &ConnectionInfo{
local: local, local: local,
remote: remote, remote: remote,
},nil }, nil
} }
func conntrackAddr(ip_str, port_str string) (*socketAddr, error) { func conntrackAddr(ip_str, port_str string) (*socketAddr, error) {
ip := net.ParseIP(stripLabel(ip_str)) ip := net.ParseIP(stripLabel(ip_str))
if ip == nil { if ip == nil {
return nil, errors.New("Could not parse IP: "+ip_str) return nil, errors.New("Could not parse IP: " + ip_str)
} }
i64, err := strconv.Atoi(stripLabel(port_str)) i64, err := strconv.Atoi(stripLabel(port_str))
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &socketAddr{ return &socketAddr{
ip: ip, ip: ip,
port: uint16(i64), port: uint16(i64),
},nil }, nil
} }
func stripLabel(s string) string { func stripLabel(s string) string {

@ -1,39 +1,38 @@
package proc package proc
import ( import (
"fmt"
"io/ioutil"
"os" "os"
"path"
"strconv" "strconv"
"fmt"
"strings" "strings"
"path"
"io/ioutil"
"sync" "sync"
"syscall" "syscall"
) )
type ProcInfo struct { type ProcInfo struct {
Uid int Uid int
Pid int Pid int
loaded bool loaded bool
ExePath string ExePath string
CmdLine string CmdLine string
} }
type pidCache struct { type pidCache struct {
cacheMap map[uint64]*ProcInfo cacheMap map[uint64]*ProcInfo
lock sync.Mutex lock sync.Mutex
} }
func (pc *pidCache) lookup(inode uint64) *ProcInfo { func (pc *pidCache) lookup(inode uint64) *ProcInfo {
pc.lock.Lock() pc.lock.Lock()
defer pc.lock.Unlock() defer pc.lock.Unlock()
pi,ok := pc.cacheMap[inode] pi, ok := pc.cacheMap[inode]
if ok && pi.loadProcessInfo() { if ok && pi.loadProcessInfo() {
return pi return pi
} }
pc.cacheMap = loadCache() pc.cacheMap = loadCache()
pi,ok = pc.cacheMap[inode] pi, ok = pc.cacheMap[inode]
if ok && pi.loadProcessInfo() { if ok && pi.loadProcessInfo() {
return pi return pi
} }
@ -46,7 +45,7 @@ func loadCache() map[uint64]*ProcInfo {
pid := toPid(n) pid := toPid(n)
if pid != 0 { if pid != 0 {
pinfo := &ProcInfo{Pid: pid} pinfo := &ProcInfo{Pid: pid}
for _,inode := range inodesFromPid(pid) { for _, inode := range inodesFromPid(pid) {
cmap[inode] = pinfo cmap[inode] = pinfo
} }
} }
@ -60,7 +59,7 @@ func toPid(name string) int {
return 0 return 0
} }
fdpath := fmt.Sprintf("/proc/%d/fd", pid) fdpath := fmt.Sprintf("/proc/%d/fd", pid)
fi,err := os.Stat(fdpath) fi, err := os.Stat(fdpath)
if err != nil { if err != nil {
return 0 return 0
} }
@ -91,8 +90,8 @@ func extractSocket(name string) uint64 {
if !strings.HasPrefix(name, "socket:[") || !strings.HasSuffix(name, "]") { if !strings.HasPrefix(name, "socket:[") || !strings.HasSuffix(name, "]") {
return 0 return 0
} }
val := name[8:len(name)-1] val := name[8 : len(name)-1]
inode,err := strconv.ParseUint(val, 10, 64) inode, err := strconv.ParseUint(val, 10, 64)
if err != nil { if err != nil {
log.Warning("Error parsing inode value from %s: %v", name, err) log.Warning("Error parsing inode value from %s: %v", name, err)
return 0 return 0
@ -101,7 +100,7 @@ func extractSocket(name string) uint64 {
} }
func readdir(dir string) []string { func readdir(dir string) []string {
d,err := os.Open(dir) d, err := os.Open(dir)
if err != nil { if err != nil {
log.Warning("Error opening directory %s: %v", dir, err) log.Warning("Error opening directory %s: %v", dir, err)
return nil return nil

@ -1,15 +1,16 @@
package proc package proc
import ( import (
"net" "errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"strings" "net"
"errors"
"strconv" "strconv"
"strings"
) )
type socketAddr struct { type socketAddr struct {
ip net.IP ip net.IP
port uint16 port uint16
} }
@ -18,11 +19,11 @@ func (sa socketAddr) String() string {
} }
type socketStatus struct { type socketStatus struct {
local socketAddr local socketAddr
remote socketAddr remote socketAddr
uid int uid int
inode uint64 inode uint64
line string line string
} }
func (ss *socketStatus) String() string { func (ss *socketStatus) String() string {
@ -43,7 +44,7 @@ func findTCPSocket(srcPort uint16, dstAddr net.IP, dstPort uint16) *socketStatus
func findSocket(proto string, matcher func(socketStatus) bool) *socketStatus { func findSocket(proto string, matcher func(socketStatus) bool) *socketStatus {
var ss socketStatus var ss socketStatus
for _,line := range getSocketLines(proto) { for _, line := range getSocketLines(proto) {
if len(line) == 0 { if len(line) == 0 {
continue continue
} }
@ -83,7 +84,6 @@ func (ss *socketStatus) parseLine(line string) error {
return nil return nil
} }
func getSocketLines(proto string) []string { func getSocketLines(proto string) []string {
path := fmt.Sprintf("/proc/net/%s", proto) path := fmt.Sprintf("/proc/net/%s", proto)
data, err := ioutil.ReadFile(path) data, err := ioutil.ReadFile(path)

Loading…
Cancel
Save