Skip to content

Commit 8a1ffc4

Browse files
author
Code Express
committed
JSON and Debug feature added. Fixed IPv6 issue on Mac OS X
1 parent d86e6d3 commit 8a1ffc4

3 files changed

Lines changed: 124 additions & 22 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*.dll
44
*.so
55
*.dylib
6+
binaries/
67

78
# Test binary, build with `go test -c`
89
*.test

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
all:
2+
GOOS=windows GOARCH=386 go build -o binaries/respounder-x86.exe respounder.go
3+
GOOS=windows GOARCH=amd64 go build -o binaries/respounder-x64.exe respounder.go
4+
GOOS=linux GOARCH=386 go build -o binaries/respounder-x86 respounder.go
5+
GOOS=linux GOARCH=amd64 go build -o binaries/respounder-x64 respounder.go
6+
GOOS=darwin GOARCH=386 go build -o binaries/respounder-osx respounder.go
7+
GOOS=darwin GOARCH=amd64 go build -o binaries/respounder-osx64 respounder.go

respounder.go

Lines changed: 116 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ package main
22

33
import (
44
"encoding/hex"
5+
"encoding/json"
6+
"flag"
57
"fmt"
8+
"io/ioutil"
9+
"log"
610
"math/rand"
711
"net"
812
"os"
@@ -11,39 +15,86 @@ import (
1115
)
1216

1317
const (
14-
banner = `
18+
Banner = `
1519
16-
.´/
17-
/ ( .----------------.
18-
[ ]░░░░░░░░░░░|// RESPOUNDER //|
19-
) ( '----------------'` + "\n" +
20-
" '-' \n"
20+
.´/
21+
/ ( .----------------.
22+
[ ]░░░░░░░░░░░|// RESPOUNDER //|
23+
) ( '----------------'
24+
'-'
25+
`
2126

22-
timeoutSec = 3
27+
Version = 1.0
28+
TimeoutSec = 3
29+
)
30+
31+
var (
32+
// stdout is default output
33+
outFile = os.Stdout
34+
35+
// default logger is set to abyss
36+
logger = log.New(ioutil.Discard, "", 0)
37+
38+
// argument flags
39+
jsonPtr = flag.Bool("json", false,
40+
`Prints a JSON to STDOUT if a responder is detected on
41+
network. Other text is sent to STDERR`)
42+
43+
debugPtr = flag.Bool("debug", false,
44+
`Creates a debug.log file with a trace of the program`)
2345
)
2446

2547
func main() {
26-
fmt.Fprintln(os.Stderr, banner)
48+
initFlags()
49+
50+
fmt.Fprintln(os.Stderr, Banner)
2751

2852
interfaces, _ := net.Interfaces()
53+
logger.Println("======== Starting RESPOUNDER ========")
54+
logger.Printf("List of all interfaces: \n %+v\n", interfaces)
55+
56+
var resultMap []map[string]string
57+
2958
for _, inf := range interfaces {
30-
checkResponderOnInterface(inf)
59+
detailsMap := checkResponderOnInterface(inf)
60+
if len(detailsMap) > 0 {
61+
resultMap = append(resultMap, detailsMap)
62+
}
63+
}
64+
65+
if *debugPtr {
66+
fmt.Fprintln(os.Stderr, "Debug file 'debug.log' created.")
67+
}
68+
69+
if *jsonPtr {
70+
resultJSON, _ := json.Marshal(resultMap)
71+
fmt.Println(string(resultJSON))
3172
}
73+
logger.Println("======== Ending RESPOUNDER Session ========")
3274
}
3375

34-
func checkResponderOnInterface(inf net.Interface) string {
35-
json := ""
76+
func checkResponderOnInterface(inf net.Interface) map[string]string {
77+
var json map[string]string
3678
addrs, _ := inf.Addrs()
37-
if len(addrs) > 0 {
38-
ip := addrs[0].(*net.IPNet).IP
39-
if ip.String() != "127.0.0.1" {
40-
fmt.Printf("%-10s Sending probe from %s...\t", "["+inf.Name+"]", ip)
41-
responderAddr := sendLLMNRProbe(ip)
42-
if responderAddr != "" {
43-
fmt.Printf("responder detected at %s\n", responderAddr)
44-
} else {
45-
fmt.Println("responder not detected")
79+
logger.Printf("List of all addresses on interface [%s]: %+v\n",
80+
inf.Name, addrs)
81+
ip := getValidIPv4Addr(addrs)
82+
logger.Printf("Bind IP address for interface %+v is %+v\n",
83+
inf.Name, ip)
84+
85+
if ip != nil {
86+
fmt.Fprintf(outFile, "%-10s Sending probe from %s...\t",
87+
"["+inf.Name+"]", ip)
88+
responderIP := sendLLMNRProbe(ip)
89+
if responderIP != "" {
90+
fmt.Fprintf(outFile, "responder detected at %s\n", responderIP)
91+
json = map[string]string{
92+
"interface": inf.Name,
93+
"sourceIP": ip.String(),
94+
"responderIP": responderIP,
4695
}
96+
} else {
97+
fmt.Fprintln(outFile, "responder not detected")
4798
}
4899
}
49100
return json
@@ -68,16 +119,59 @@ func sendLLMNRProbe(ip net.IP) string {
68119
conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: ip})
69120
if err != nil {
70121
fmt.Println("Couldn't bind to a UDP interface. Bailing out!")
122+
logger.Printf("Bind error: %+v\nSource IP: %v\n", err, ip)
123+
fmt.Println(err)
71124
}
72125

73126
defer conn.Close()
74127
_, _ = conn.WriteToUDP(n, &remoteAddr)
75128

76-
conn.SetReadDeadline(time.Now().Add(timeoutSec * time.Second))
129+
conn.SetReadDeadline(time.Now().Add(TimeoutSec * time.Second))
77130
buffer := make([]byte, 1024)
78-
_, clientIP, err := conn.ReadFromUDP(buffer)
131+
bytes, clientIP, err := conn.ReadFromUDP(buffer)
79132
if err == nil { // no timeout (or any other) error
80133
responderIP = strings.Split(clientIP.String(), ":")[0]
134+
logger.Printf("Data received on %s from responder IP %s: %x\n",
135+
ip, clientIP, buffer[:bytes])
136+
} else {
137+
logger.Printf("Error getting response: %s\n", err)
81138
}
82139
return responderIP
83140
}
141+
142+
// From all the IP addresses of this interface,
143+
// extract the IPv4 address where we'll bind to
144+
func getValidIPv4Addr(addrs []net.Addr) net.IP {
145+
var ip net.IP
146+
for _, addr := range addrs { // amongst all addrs,
147+
ip = addr.(*net.IPNet).IP.To4() // pick the IPv4 addr
148+
if ip != nil && ip.String() != "127.0.0.1" {
149+
break
150+
}
151+
}
152+
return ip
153+
}
154+
155+
// parses cmd line flag and set appropriate variables
156+
func initFlags() {
157+
flag.Usage = func() {
158+
fmt.Fprintf(os.Stderr, "Respounder version %1.1f\n", Version)
159+
fmt.Fprintf(os.Stderr, "Usage: $ respounder [-json] [-debug]")
160+
fmt.Fprintf(os.Stderr, "\n\nFlags:\n")
161+
flag.PrintDefaults()
162+
}
163+
164+
flag.Parse()
165+
if *jsonPtr {
166+
outFile = os.Stderr
167+
}
168+
if *debugPtr {
169+
f, err := os.OpenFile("debug.log",
170+
os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
171+
if err != nil {
172+
panic(err)
173+
}
174+
logger = log.New(f, "", 0)
175+
logger.SetPrefix("[" + time.Now().Format("02-Jan-2006 15:04:05 MST") + "]: ")
176+
}
177+
}

0 commit comments

Comments
 (0)