-
Notifications
You must be signed in to change notification settings - Fork 398
/
plt_darwin.go
402 lines (382 loc) · 13.2 KB
/
plt_darwin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
// +build darwin
//-----------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license.
// See LICENSE.txt file in the project root for full license information.
//-----------------------------------------------------------------------------
package main
import (
"bytes"
"encoding/binary"
"net"
"syscall"
tm "github.com/nsf/termbox-go"
"golang.org/x/sys/unix"
)
func getNetDevStats(stats *ethrNetStat) {
ifs, err := net.Interfaces()
if err != nil {
ui.printErr("%v", err)
return
}
for _, iface := range ifs {
if iface.Flags&net.FlagUp == 0 {
continue
}
ifaceData, err := getIfaceData(iface.Index)
if err != nil {
ui.printErr("Failed to load data for interface %q: %v", iface.Name, err)
continue
}
stats.netDevStats = append(stats.netDevStats, ethrNetDevStat{
interfaceName: iface.Name,
rxBytes: ifaceData.Data.Ibytes,
rxPkts: ifaceData.Data.Ipackets,
txBytes: ifaceData.Data.Obytes,
txPkts: ifaceData.Data.Opackets,
})
}
}
func getTCPStats(stats *ethrNetStat) {
var data tcpStat
rawData, err := unix.SysctlRaw("net.inet.tcp.stats")
if err != nil {
// return EthrTCPStat{}, errors.Wrap(err, "GetTCPStats: could not get net.inet.tcp.stats")
return
}
buf := bytes.NewReader(rawData)
binary.Read(buf, binary.LittleEndian, &data)
// return EthrTCPStat{uint64(data.Sndrexmitpack)}, nil
// return the TCP Retransmits
stats.tcpStats.segRetrans = uint64(data.Sndrexmitpack)
return
}
func hideCursor() {
tm.SetCursor(0, 0)
}
func blockWindowResize() {
}
func getIfaceData(index int) (*ifMsghdr2, error) {
var data ifMsghdr2
rawData, err := unix.SysctlRaw("net", unix.AF_ROUTE, 0, 0, unix.NET_RT_IFLIST2, index)
if err != nil {
return nil, err
}
err = binary.Read(bytes.NewReader(rawData), binary.LittleEndian, &data)
return &data, err
}
type ifMsghdr2 struct {
Msglen uint16
Version uint8
Type uint8
Addrs int32
Flags int32
Index uint16
_ [2]byte
SndLen int32
SndMaxlen int32
SndDrops int32
Timer int32
Data ifData64
}
type ifData64 struct {
Type uint8
Typelen uint8
Physical uint8
Addrlen uint8
Hdrlen uint8
Recvquota uint8
Xmitquota uint8
Unused1 uint8
Mtu uint32
Metric uint32
Baudrate uint64
Ipackets uint64
Ierrors uint64
Opackets uint64
Oerrors uint64
Collisions uint64
Ibytes uint64
Obytes uint64
Imcasts uint64
Omcasts uint64
Iqdrops uint64
Noproto uint64
Recvtiming uint32
Xmittiming uint32
Lastchange unix.Timeval32
}
type tcpStat struct {
Connattempt uint32
Accepts uint32
Connects uint32
Drops uint32
Conndrops uint32
Closed uint32
Segstimed uint32
Rttupdated uint32
Delack uint32
Timeoutdrop uint32
Rexmttimeo uint32
Persisttimeo uint32
Keeptimeo uint32
Keepprobe uint32
Keepdrops uint32
Sndtotal uint32
Sndpack uint32
Sndbyte uint32
Sndrexmitpack uint32
Sndrexmitbyte uint32
Sndacks uint32
Sndprobe uint32
Sndurg uint32
Sndwinup uint32
Sndctrl uint32
Rcvtotal uint32
Rcvpack uint32
Rcvbyte uint32
Rcvbadsum uint32
Rcvbadoff uint32
Rcvmemdrop uint32
Rcvshort uint32
Rcvduppack uint32
Rcvdupbyte uint32
Rcvpartduppack uint32
Rcvpartdupbyte uint32
Rcvoopack uint32
Rcvoobyte uint32
Rcvpackafterwin uint32
Rcvbyteafterwin uint32
Rcvafterclose uint32
Rcvwinprobe uint32
Rcvdupack uint32
Rcvacktoomuch uint32
Rcvackpack uint32
Rcvackbyte uint32
Rcvwinupd uint32
Pawsdrop uint32
Predack uint32
Preddat uint32
Pcbcachemiss uint32
Cachedrtt uint32
Cachedrttvar uint32
Cachedssthresh uint32
Usedrtt uint32
Usedrttvar uint32
Usedssthresh uint32
Persistdrop uint32
Badsyn uint32
Mturesent uint32
Listendrop uint32
Minmssdrops uint32
Sndrexmitbad uint32
Badrst uint32
Sc_added uint32
Sc_retransmitted uint32
Sc_dupsyn uint32
Sc_dropped uint32
Sc_completed uint32
Sc_bucketoverflow uint32
Sc_cacheoverflow uint32
Sc_reset uint32
Sc_stale uint32
Sc_aborted uint32
Sc_badack uint32
Sc_unreach uint32
Sc_zonefail uint32
Sc_sendcookie uint32
Sc_recvcookie uint32
Hc_added uint32
Hc_bucketoverflow uint32
Sack_recovery_episode uint32
Sack_rexmits uint32
Sack_rexmit_bytes uint32
Sack_rcv_blocks uint32
Sack_send_blocks uint32
Sack_sboverflow uint32
Bg_rcvtotal uint32
Rxtfindrop uint32
Fcholdpacket uint32
Coalesced_pack uint32
Flowtbl_full uint32
Flowtbl_collision uint32
Lro_twopack uint32
Lro_multpack uint32
Lro_largepack uint32
Limited_txt uint32
Early_rexmt uint32
Sack_ackadv uint32
Rcv_swcsum uint32
Rcv_swcsum_bytes uint32
Rcv6_swcsum uint32
Rcv6_swcsum_bytes uint32
Snd_swcsum uint32
Snd_swcsum_bytes uint32
Snd6_swcsum uint32
Snd6_swcsum_bytes uint32
Msg_unopkts uint32
Msg_unoappendfail uint32
Msg_sndwaithipri uint32
Invalid_mpcap uint32
Invalid_joins uint32
Mpcap_fallback uint32
Join_fallback uint32
Estab_fallback uint32
Invalid_opt uint32
Mp_outofwin uint32
Mp_reducedwin uint32
Mp_badcsum uint32
Mp_oodata uint32
Mp_switches uint32
Mp_rcvtotal uint32
Mp_rcvbytes uint32
Mp_sndpacks uint32
Mp_sndbytes uint32
Join_rxmts uint32
Tailloss_rto uint32
Reordered_pkts uint32
Recovered_pkts uint32
Pto uint32
Rto_after_pto uint32
Tlp_recovery uint32
Tlp_recoverlastpkt uint32
Ecn_client_success uint32
Ecn_recv_ece uint32
Ecn_sent_ece uint32
Detect_reordering uint32
Delay_recovery uint32
Avoid_rxmt uint32
Unnecessary_rxmt uint32
Nostretchack uint32
Rescue_rxmt uint32
Pto_in_recovery uint32
Pmtudbh_reverted uint32
Dsack_disable uint32
Dsack_ackloss uint32
Dsack_badrexmt uint32
Dsack_sent uint32
Dsack_recvd uint32
Dsack_recvd_old uint32
Mp_sel_symtomsd uint32
Mp_sel_rtt uint32
Mp_sel_rto uint32
Mp_sel_peer uint32
Mp_num_probes uint32
Mp_verdowngrade uint32
Drop_after_sleep uint32
Probe_if uint32
Probe_if_conflict uint32
Ecn_client_setup uint32
Ecn_server_setup uint32
Ecn_server_success uint32
Ecn_lost_synack uint32
Ecn_lost_syn uint32
Ecn_not_supported uint32
Ecn_recv_ce uint32
Ecn_conn_recv_ce uint32
Ecn_conn_recv_ece uint32
Ecn_conn_plnoce uint32
Ecn_conn_pl_ce uint32
Ecn_conn_nopl_ce uint32
Ecn_fallback_synloss uint32
Ecn_fallback_reorder uint32
Ecn_fallback_ce uint32
Tfo_syn_data_rcv uint32
Tfo_cookie_req_rcv uint32
Tfo_cookie_sent uint32
Tfo_cookie_invalid uint32
Tfo_cookie_req uint32
Tfo_cookie_rcv uint32
Tfo_syn_data_sent uint32
Tfo_syn_data_acked uint32
Tfo_syn_loss uint32
Tfo_blackhole uint32
Tfo_cookie_wrong uint32
Tfo_no_cookie_rcv uint32
Tfo_heuristics_disable uint32
Tfo_sndblackhole uint32
Mss_to_default uint32
Mss_to_medium uint32
Mss_to_low uint32
Ecn_fallback_droprst uint32
Ecn_fallback_droprxmt uint32
Ecn_fallback_synrst uint32
Mptcp_rcvmemdrop uint32
Mptcp_rcvduppack uint32
Mptcp_rcvpackafterwin uint32
Timer_drift_le_1_ms uint32
Timer_drift_le_10_ms uint32
Timer_drift_le_20_ms uint32
Timer_drift_le_50_ms uint32
Timer_drift_le_100_ms uint32
Timer_drift_le_200_ms uint32
Timer_drift_le_500_ms uint32
Timer_drift_le_1000_ms uint32
Timer_drift_gt_1000_ms uint32
Mptcp_handover_attempt uint32
Mptcp_interactive_attempt uint32
Mptcp_aggregate_attempt uint32
Mptcp_fp_handover_attempt uint32
Mptcp_fp_interactive_attempt uint32
Mptcp_fp_aggregate_attempt uint32
Mptcp_heuristic_fallback uint32
Mptcp_fp_heuristic_fallback uint32
Mptcp_handover_success_wifi uint32
Mptcp_handover_success_cell uint32
Mptcp_interactive_success uint32
Mptcp_aggregate_success uint32
Mptcp_fp_handover_success_wifi uint32
Mptcp_fp_handover_success_cell uint32
Mptcp_fp_interactive_success uint32
Mptcp_fp_aggregate_success uint32
Mptcp_handover_cell_from_wifi uint32
Mptcp_handover_wifi_from_cell uint32
Mptcp_interactive_cell_from_wifi uint32
_ [4]byte
Mptcp_handover_cell_bytes uint64
Mptcp_interactive_cell_bytes uint64
Mptcp_aggregate_cell_bytes uint64
Mptcp_handover_all_bytes uint64
Mptcp_interactive_all_bytes uint64
Mptcp_aggregate_all_bytes uint64
Mptcp_back_to_wifi uint32
Mptcp_wifi_proxy uint32
Mptcp_cell_proxy uint32
_ [4]byte
}
func setSockOptInt(fd uintptr, level, opt, val int) (err error) {
err = syscall.SetsockoptInt(int(fd), level, opt, val)
if err != nil {
ui.printErr("Failed to set socket option (%v) to value (%v) during Dial. Error: %s", opt, val, err)
}
return
}
func IcmpNewConn(address string) (net.PacketConn, error) {
dialedConn, err := net.Dial(Icmp(), address)
if err != nil {
return nil, err
}
localAddr := dialedConn.LocalAddr()
dialedConn.Close()
conn, err := net.ListenPacket(Icmp(), localAddr.String())
if err != nil {
return nil, err
}
return conn, nil
}
func VerifyPermissionForTest(testID EthrTestID) {
if testID.Protocol == ICMP || (testID.Protocol == TCP &&
(testID.Type == TraceRoute || testID.Type == MyTraceRoute)) {
if !IsAdmin() {
ui.printMsg("Warning: You are not running as administrator. For %s based %s",
protoToString(testID.Protocol), testToString(testID.Type))
ui.printMsg("test, running as administrator is required.\n")
}
}
}
func IsAdmin() bool {
return true
}
func SetTClass(fd uintptr, tos int) {
setSockOptInt(fd, syscall.IPPROTO_IPV6, syscall.IPV6_TCLASS, tos)
}