Skip to content

Commit e0239c1

Browse files
added another way to configure arpspoofer, added some funcs to network
1 parent d673090 commit e0239c1

File tree

5 files changed

+62
-6
lines changed

5 files changed

+62
-6
lines changed

arpspoof/arpspoof.go

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
)
2424

2525
const (
26-
protocolARP = 0x0806
2726
unixEthPAll = 0x03
2827
)
2928

@@ -32,6 +31,9 @@ var (
3231
probeTargetsInterval = 60 * time.Second
3332
refreshARPTableInterval = 15 * time.Second
3433
arpSpoofTargetsInterval = 1 * time.Second
34+
errARPSpoofConfig = fmt.Errorf(
35+
`failed parsing arp options. Example: "targets 10.0.0.1,10.0.0.5-10,192.168.1.*,192.168.10.0/24;fullduplex false;debug true"`,
36+
)
3537
)
3638

3739
type Packet struct {
@@ -48,6 +50,45 @@ type ARPSpoofConfig struct {
4850
Debug bool
4951
}
5052

53+
// NewARPSpoofConfig creates ARPSpoofConfig from a list of options separated by semicolon and logger.
54+
//
55+
// Example: "targets 10.0.0.1,10.0.0.5-10,192.168.1.*,192.168.10.0/24;fullduplex false;debug true;interface eth0;gateway 192.168.1.1"`.
56+
// All fields in configuration string are optional.
57+
func NewARPSpoofConfig(s string, logger *zerolog.Logger) (*ARPSpoofConfig, error) {
58+
asc := &ARPSpoofConfig{Logger: logger}
59+
for opt := range strings.SplitSeq(strings.ToLower(s), ";") {
60+
keyval := strings.SplitN(strings.Trim(opt, " "), " ", 2)
61+
if len(keyval) < 2 {
62+
return nil, errARPSpoofConfig
63+
}
64+
key := keyval[0]
65+
val := keyval[1]
66+
switch key {
67+
case "targets":
68+
asc.Targets = val
69+
case "interface":
70+
asc.Interface = val
71+
case "gateway":
72+
gateway, err := netip.ParseAddr(val)
73+
if err != nil {
74+
return nil, err
75+
}
76+
asc.Gateway = &gateway
77+
case "fullduplex":
78+
if val == "true" {
79+
asc.FullDuplex = true
80+
}
81+
case "debug":
82+
if val == "true" {
83+
asc.Debug = true
84+
}
85+
default:
86+
return nil, errARPSpoofConfig
87+
}
88+
}
89+
return asc, nil
90+
}
91+
5192
type ARPTable struct {
5293
sync.RWMutex
5394
Ifname string

cmd/marpspoof/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func root(args []string) error {
3838
flags.BoolVar(&conf.Debug, "d", false, "Enable debug logging")
3939
nocolor := flags.Bool("nocolor", false, "Disable colored output")
4040
flags.BoolFunc("I", "Display list of interfaces and exit.", func(flagValue string) error {
41-
if err := network.DisplayInterfaces(); err != nil {
41+
if err := network.DisplayInterfaces(false); err != nil {
4242
fmt.Fprintf(os.Stderr, "%s: %v\n", app, err)
4343
os.Exit(2)
4444
}

cmd/mshark/cli.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func root(args []string) error {
8989
packetBuffer := flags.Int("b", 8192, "The maximum size of packet queue.")
9090
flags.StringVar(&conf.Expr, "e", "", `BPF filter expression. Example: "ip proto tcp".`)
9191
flags.BoolFunc("D", "Display list of interfaces and exit.", func(flagValue string) error {
92-
if err := network.DisplayInterfaces(); err != nil {
92+
if err := network.DisplayInterfaces(true); err != nil {
9393
fmt.Fprintf(os.Stderr, "%s: %v\n", app, err)
9494
os.Exit(2)
9595
}

network/network.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,17 @@ func InterfaceByName(name string) (*net.Interface, error) {
4242
return in, nil
4343
}
4444

45-
func DisplayInterfaces() error {
45+
func DisplayInterfaces(includeAny bool) error {
4646
w := new(tabwriter.Writer)
4747
w.Init(os.Stdout, 0, 0, 2, ' ', tabwriter.TabIndent)
4848
ifaces, err := net.Interfaces()
4949
if err != nil {
5050
return fmt.Errorf("failed to get network interfaces: %v", err)
5151
}
5252
fmt.Fprintln(w, "Index\tName\tFlags")
53-
fmt.Fprintln(w, "0\tany\tUP")
53+
if includeAny {
54+
fmt.Fprintln(w, "0\tany\tUP")
55+
}
5456
for _, iface := range ifaces {
5557
fmt.Fprintf(w, "%d\t%s\t%s\n", iface.Index, iface.Name, strings.ToUpper(iface.Flags.String()))
5658
}
@@ -146,3 +148,16 @@ func GetIPv4PrefixFromInterface(iface *net.Interface) (netip.Prefix, error) {
146148
}
147149
return netip.Prefix{}, fmt.Errorf("no IPv4 prefix found")
148150
}
151+
152+
func IsLocalAddress(addr string) bool {
153+
host, _, err := net.SplitHostPort(addr)
154+
if err != nil {
155+
host = addr
156+
}
157+
ip := net.ParseIP(host)
158+
if ip != nil {
159+
return ip.IsLoopback()
160+
}
161+
host = strings.ToLower(host)
162+
return strings.HasSuffix(host, ".local") || host == "localhost"
163+
}

version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package mshark
22

3-
const Version string = "mshark v0.0.9"
3+
const Version string = "mshark v0.0.10"

0 commit comments

Comments
 (0)