Package: tcllib / 1.19-dfsg-2

nettool.patch Patch series | download
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]
   }