1
1
package pcap
2
2
3
3
import (
4
- // "fmt"
4
+ "fmt"
5
5
"time"
6
6
7
7
"github.com/danielpaulus/go-ios/ios"
@@ -26,24 +26,22 @@ func (n PacketInfo) complete() bool {
26
26
return (n .IPv6 != "" && n .Mac != "" ) || (n .IPv4 != "" && n .Mac != "" )
27
27
}
28
28
29
- // FindIp reads pcap packets until one is found that matches the given MAC
29
+ // FindIPByMac reads pcap packets until one is found that matches the given MAC
30
30
// and contains an IP address. This won't work if the iOS device "automatic Wifi address" privacy
31
31
// feature is enabled. The MAC needs to be static.
32
32
func FindIPByMac (device ios.DeviceEntry ) (NetworkInfo , error ) {
33
33
mac , err := ios .GetWifiMac (device )
34
- _ = mac
35
34
if err != nil {
36
- return NetworkInfo {}, err
35
+ return NetworkInfo {}, fmt . Errorf ( "FindIPMyMac: unable to get WiFi MAC Address: %w" , err )
37
36
}
38
37
39
38
// channel to receive PacketInfo
40
39
c := make (chan PacketInfo )
41
40
done := make (chan bool )
41
+ captureError := make (chan error )
42
42
43
43
go func () {
44
- if err := startCapture (device , c , done ); err != nil {
45
- log .Error (err )
46
- }
44
+ captureError <- startCapture (device , c , done )
47
45
}()
48
46
49
47
// captureDuration := time.Duration(10 * time.Second)
@@ -55,27 +53,27 @@ func FindIPByMac(device ios.DeviceEntry) (NetworkInfo, error) {
55
53
}
56
54
}
57
55
58
- return NetworkInfo {}, nil
56
+ captureErrorResult := <- captureError
57
+ if captureErrorResult != nil {
58
+ return NetworkInfo {}, fmt .Errorf ("FindIPByMac: failed to startCapture got err: %w" , captureErrorResult )
59
+ }
60
+
61
+ return NetworkInfo {}, fmt .Errorf ("failed to get any IP matching the MAC: %s" , mac )
59
62
}
60
63
61
- // FindIp reads pcap packets until one is found that matches the given MAC
62
- // and contains an IP address. This won't work if the iOS device "automatic Wifi address" privacy
63
- // feature is enabled. The MAC needs to be static.
64
+ // FindIPByLazy reads pcap packets for a specified duration, whereafter it will
65
+ // try to find the IP address that occurs the most times, and assume that is the IP of the device.
66
+ // This is of course based on, that the device contacts mulitple IPs, and that there is some traffic.
67
+ // If the device only contains a single IP, then it would be 50/50 which IP will be returned.
68
+ // This is best effort! It's important to generate some traffic, when this function runs to get better results.
64
69
func FindIPByLazy (device ios.DeviceEntry , capture_duration time.Duration ) (NetworkInfo , error ) {
65
- mac , err := ios .GetWifiMac (device )
66
- _ = mac
67
- if err != nil {
68
- return NetworkInfo {}, err
69
- }
70
-
71
70
// channel to receive PacketInfo
72
71
c := make (chan PacketInfo )
73
72
done := make (chan bool )
73
+ captureError := make (chan error )
74
74
75
75
go func () {
76
- if err := startCapture (device , c , done ); err != nil {
77
- log .Error (err )
78
- }
76
+ captureError <- startCapture (device , c , done )
79
77
}()
80
78
81
79
// captureDuration := time.Duration(10 * time.Second)
@@ -96,6 +94,11 @@ func FindIPByLazy(device ios.DeviceEntry, capture_duration time.Duration) (Netwo
96
94
}
97
95
}
98
96
97
+ captureErrorResult := <- captureError
98
+ if captureErrorResult != nil {
99
+ return NetworkInfo {}, fmt .Errorf ("FindIPByLazy: failed to startCapture got err: %w" , captureErrorResult )
100
+ }
101
+
99
102
highestIPv4Hits , highestIPv4Addr := 0 , ""
100
103
for ipv4 , hits := range ipv4Hits {
101
104
if hits > highestIPv4Hits {
@@ -118,8 +121,9 @@ func FindIPByLazy(device ios.DeviceEntry, capture_duration time.Duration) (Netwo
118
121
func startCapture (device ios.DeviceEntry , c chan PacketInfo , done chan bool ) error {
119
122
intf , err := ios .ConnectToService (device , "com.apple.pcapd" )
120
123
if err != nil {
121
- return err
124
+ return fmt . Errorf ( "startCapture: failed connecting to com.apple.pcapd with err: %w" , err )
122
125
}
126
+
123
127
plistCodec := ios .NewPlistCodec ()
124
128
for {
125
129
// if the channel is signalling to stop
@@ -131,22 +135,18 @@ func startCapture(device ios.DeviceEntry, c chan PacketInfo, done chan bool) err
131
135
132
136
b , err := plistCodec .Decode (intf .Reader ())
133
137
if err != nil {
134
- return err
138
+ return fmt . Errorf ( "startCapture: failed decoding plistCodec err: %w" , err )
135
139
}
136
140
decodedBytes , err := fromBytes (b )
137
141
if err != nil {
138
- return err
142
+ return fmt . Errorf ( "startCapture: failed decoding fromBytes err: %w" , err )
139
143
}
140
144
_ , packet , err := getPacket (decodedBytes )
141
145
if err != nil {
142
- return err
146
+ return fmt . Errorf ( "startCapture: failed getPacket err: %w" , err )
143
147
}
144
148
if len (packet ) > 0 {
145
- pInfo , err := parsePacket (packet )
146
- if err != nil {
147
- return err
148
- }
149
-
149
+ pInfo := parsePacket (packet )
150
150
if ! pInfo .complete () {
151
151
continue
152
152
}
@@ -158,7 +158,7 @@ func startCapture(device ios.DeviceEntry, c chan PacketInfo, done chan bool) err
158
158
return nil
159
159
}
160
160
161
- func parsePacket (p []byte ) ( PacketInfo , error ) {
161
+ func parsePacket (p []byte ) PacketInfo {
162
162
packet := gopacket .NewPacket (p , layers .LayerTypeEthernet , gopacket .Default )
163
163
res := PacketInfo {}
164
164
@@ -183,5 +183,5 @@ func parsePacket(p []byte) (PacketInfo, error) {
183
183
}
184
184
}
185
185
186
- return res , nil
186
+ return res
187
187
}
0 commit comments