Skip to content

Commit 1493c99

Browse files
committed
ARP cache file option
1 parent 0b6f42f commit 1493c99

File tree

4 files changed

+54
-11
lines changed

4 files changed

+54
-11
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,18 @@ or individual ports:
128128
cat arp.cache | ./sx tcp -p 22,443 192.168.0.171
129129
```
130130

131+
It is possible to specify the ARP cache file using the `-a` or `--arp-cache` options:
132+
133+
```
134+
./sx tcp -a arp.cache -p 22,443 192.168.0.171
135+
```
136+
137+
or stdin redirect:
138+
139+
```
140+
./sx tcp -p 22,443 192.168.0.171 < arp.cache
141+
```
142+
131143
You can also use the `tcp syn` subcommand instead of the `tcp`:
132144

133145
```

command/root.go

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package command
22

33
import (
4+
"bufio"
45
"context"
56
"errors"
67
"io"
@@ -63,13 +64,14 @@ var rootCmd = &cobra.Command{
6364
}
6465

6566
var (
66-
cliJSONFlag bool
67-
cliInterfaceFlag string
68-
cliSrcIPFlag string
69-
cliSrcMACFlag string
70-
cliPortsFlag string
71-
cliRateLimitFlag string
72-
cliExitDelayFlag string
67+
cliJSONFlag bool
68+
cliInterfaceFlag string
69+
cliSrcIPFlag string
70+
cliSrcMACFlag string
71+
cliPortsFlag string
72+
cliRateLimitFlag string
73+
cliExitDelayFlag string
74+
cliARPCacheFileFlag string
7375

7476
cliInterface *net.Interface
7577
cliSrcIP net.IP
@@ -85,6 +87,7 @@ var (
8587
errSrcMAC = errors.New("invalid source MAC")
8688
errSrcInterface = errors.New("invalid source interface")
8789
errRateLimit = errors.New("invalid ratelimit")
90+
errStdin = errors.New("stdin is from a terminal")
8891
)
8992

9093
func init() {
@@ -128,10 +131,8 @@ func parseScanConfig(scanName, subnet string) (c *scanConfig, err error) {
128131
return
129132
}
130133

131-
// TODO file argument
132-
// TODO handle pipes
133-
cache := arp.NewCache()
134-
if err = arp.FillCache(cache, os.Stdin); err != nil {
134+
var cache *arp.Cache
135+
if cache, err = parseARPCache(); err != nil {
135136
return
136137
}
137138

@@ -148,6 +149,32 @@ func parseScanConfig(scanName, subnet string) (c *scanConfig, err error) {
148149
return
149150
}
150151

152+
func parseARPCache() (cache *arp.Cache, err error) {
153+
var r io.Reader
154+
if len(cliARPCacheFileFlag) > 0 {
155+
var f *os.File
156+
if f, err = os.Open(cliARPCacheFileFlag); err != nil {
157+
return
158+
}
159+
defer f.Close()
160+
r = bufio.NewReader(f)
161+
} else {
162+
var info os.FileInfo
163+
if info, err = os.Stdin.Stat(); err != nil {
164+
return
165+
}
166+
// only data being piped to stdin is valid
167+
if (info.Mode() & os.ModeCharDevice) != 0 {
168+
// stdin from terminal is not valid
169+
return nil, errStdin
170+
}
171+
r = os.Stdin
172+
}
173+
cache = arp.NewCache()
174+
err = arp.FillCache(cache, r)
175+
return
176+
}
177+
151178
func parseScanRange(subnet string) (*scan.Range, error) {
152179
dstSubnet, err := ip.ParseIPNet(subnet)
153180
if err != nil {

command/tcp.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ func init() {
3838
if err := tcpCmd.MarkPersistentFlagRequired("ports"); err != nil {
3939
golog.Fatalln(err)
4040
}
41+
tcpCmd.PersistentFlags().StringVarP(&cliARPCacheFileFlag, "arp-cache", "a", "",
42+
strings.Join([]string{"set ARP cache file", "reads from stdin by default"}, "\n"))
4143
tcpCmd.Flags().StringVar(&cliTCPPacketFlags, "flags", "", "set TCP flags")
4244
rootCmd.AddCommand(tcpCmd)
4345
}

command/udp.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import (
1717

1818
func init() {
1919
udpCmd.Flags().StringVarP(&cliPortsFlag, "ports", "p", "", "set ports to scan")
20+
udpCmd.Flags().StringVarP(&cliARPCacheFileFlag, "arp-cache", "a", "",
21+
strings.Join([]string{"set ARP cache file", "reads from stdin by default"}, "\n"))
2022
rootCmd.AddCommand(udpCmd)
2123
}
2224

0 commit comments

Comments
 (0)