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
|
Author: Sergei Golovan
Description: Patch replaces the arp and ifconfig calls by direct parsing of
/proc/net/arp and ip address call respectively.
Last-Modified: Fri, 02 Feb 2018 09:04:55 +0300
Debian-Bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=822293
Bug: https://core.tcl.tk/tcllib/tktview?name=d879576438
Bug: https://core.tcl.tk/tcllib/tktview?name=9a21637273
--- a/modules/nettool/nettool.tcl
+++ b/modules/nettool/nettool.tcl
@@ -1042,7 +1042,9 @@
###
proc ::nettool::arp_table {} {
set result {}
- set dat [exec arp -a]
+ if {[catch {exec /usr/sbin/arp -a} dat]} {
+ return {}
+ }
foreach line [split $dat \n] {
set host [lindex $line 0]
set ip [lindex $line 1]
@@ -1062,6 +1064,24 @@
if {$::tcl_platform(platform) eq "unix" && $genus eq "linux"} {
###
+# topic: 825cd25953c2cc896a96006b7f454e00
+# title: Return pairings of MAC numbers to IP addresses on the local network
+# description: Under Linux, we read the arp table from /proc/net/arp
+# ###
+proc ::nettool::arp_table {} {
+ set result {}
+ set fd [open /proc/net/arp]
+ set dat [read $fd]
+ close $fd
+ foreach line [lrange [split $dat \n] 1 end-1] {
+ set ip [lindex $line 0]
+ set macid [lindex $line 3]
+ lappend result $macid $ip
+ }
+ return $result
+}
+
+###
# topic: 92ebbfa155883ad41c37d3f843392be4
# title: Return list of broadcast addresses for local networks
###
@@ -1069,8 +1089,8 @@
set result {}
lappend result 127.0.0.1
foreach {iface info} [dump] {
- if {[dict exists $info ipv4 Bcast:]} {
- lappend result [dict get $info ipv4 Bcast:]
+ if {[dict exists $info ipv4 brd]} {
+ lappend result [dict get $info ipv4 brd]
}
}
return [lsort -unique -dictionary $result]
@@ -1153,38 +1173,45 @@
# description: Dump interfaces
###
proc ::nettool::dump {} {
- set data [exec ifconfig]
+ set data [exec ip address show]
set iface {}
set result {}
foreach line [split $data \n] {
if {[string index $line 0] in {" " "\t"} } {
# Indented line appends the prior iface
- switch [lindex $line 0] {
+ switch -glob -- [lindex $line 0] {
inet {
- foreach tuple [lrange $line 1 end] {
- set idx [string first : $tuple]
- set field [string trim [string range $tuple 0 $idx]]
- set value [string trim [string range $tuple $idx+1 end]]
- dict set result $iface ipv4 [string trim $field] [string trim $value]
+ lassign [split [lindex $line 1]/32 /] addr prefix
+ set ipv4dict [dict create addr: $addr prefix: $prefix]
+ foreach {field value} [lrange $line 2 end] {
+ dict set ipv4dict [string trim $field] [string trim $value]
+ }
+ if {![dict exists $result $iface ipv4 scope] || \
+ [dict get $result $iface ipv4 scope] ne "global"} {
+ dict set result $iface ipv4 $ipv4dict
}
}
inet6 {
- dict set result $iface ipv6 addr: [lindex $line 2]
- foreach tuple [lrange $line 3 end] {
- set idx [string first : $tuple]
- set field [string trim [string range $tuple 0 $idx]]
- set value [string trim [string range $tuple $idx+1 end]]
- dict set result $iface ipv6 [string trim $field] [string trim $value]
+ lassign [split [lindex $line 1]/128 /] addr prefix
+ set ipv6dict [dict create addr: $addr prefix: $prefix]
+ foreach {field value} [lrange $line 2 end] {
+ dict set ipv6dict [string trim $field] [string trim $value]
+ }
+ if {![dict exists $result $iface ipv6 scope] || \
+ [dict get $result $iface ipv6 scope] ne "global"} {
+ dict set result $iface ipv6 $ipv6dict
}
}
+ link/* {
+ set ether [lindex $line 1]
+ if {$ether ne ""} {
+ dict set result $iface ether: $ether
+ }
+ }
}
} else {
# Non-intended line - new iface
- set iface [lindex $line 0]
- set idx [lsearch $line HWaddr]
- if {$idx >= 0 } {
- dict set result $iface ether: [lindex $line $idx+1]
- }
+ set iface [string trim [lindex $line 1] :]
}
}
return $result
@@ -1201,8 +1228,7 @@
lappend result [dict get $info ipv4 addr:]
}
}
- ldelete result 127.0.0.1
- return $result
+ return [lsearch -all -inline -not -exact $result 127.0.0.1]
}
###
@@ -1216,7 +1242,7 @@
lappend result [dict get $info ether:]
}
}
- return $result
+ return [lsearch -all -inline -not -exact $result 00:00:00:00:00:00]
}
###
@@ -1225,10 +1251,10 @@
proc ::nettool::network_list {} {
foreach {iface info} [dump] {
if {![dict exists $info ipv4 addr:]} continue
- if {![dict exists $info ipv4 Mask:]} continue
- #set mask [::ip::maskToInt $netmask]
+ if {![dict exists $info ipv4 prefix:]} continue
set addr [dict get $info ipv4 addr:]
- set mask [dict get $info ipv4 Mask:]
+ set prefix [dict get $info ipv4 prefix:]
+ set mask [::ip::toInteger [::ip::lengthToMask $prefix]]
set addri [::ip::toInteger $addr]
lappend result [ip::nativeToPrefix [list [expr {$addri & $mask}] $mask] -ipv4]
}
|