Advertisement
Guest User

Untitled

a guest
Aug 3rd, 2012
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.13 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2. #
  3. # checkcable - Check cable on network interfaces. Solaris.
  4. #
  5. # This program prints the link up status for network interfaces, which
  6. # also appears in /var/adm/messages as cables are connected or
  7. # disconnected. (This is different to the link UP that ifconfig prints).
  8. #
  9. # This version uses ndd, and must be run as root (see CODE comments below).
  10. #
  11. # 26-Jan-2006 ver 0.95 (check for newer versions)
  12. #
  13. # USAGE: checkcable [-h] [interface ...]
  14. # checkcable # check all configured interfaces
  15. # checkcable hme0 # look at specific interface
  16. #
  17. # FIELDS:
  18. # Link "link up", this is the cable status (plugged in)
  19. # Duplex half or full duplex
  20. # Speed Mb/s
  21. #
  22. # NOTES:
  23. # - If a value cannot be read from the interface, "ERR" is printed.
  24. # This is likely on older servers or Solaris x86 where not all network
  25. # cards support this status information.
  26. # - If you have upgraded /usr/bin/perl, this program may be unable to
  27. # find the Sun::Solaris::Kstat library (which is under /usr/perl5).
  28. # Before the "use strict;" line, you may need to add,
  29. # use lib "/usr/perl5/5.6.1/lib";
  30. # to point to your location of Sun/Solaris/Kstat.pm.
  31. #
  32. # COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
  33. #
  34. # This program is free software; you can redistribute it and/or
  35. # modify it under the terms of the GNU General Public License
  36. # as published by the Free Software Foundation; either version 2
  37. # of the License, or (at your option) any later version.
  38. #
  39. # This program is distributed in the hope that it will be useful,
  40. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  41. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  42. # GNU General Public License for more details.
  43. #
  44. # You should have received a copy of the GNU General Public License
  45. # along with this program; if not, write to the Free Software Foundation,
  46. # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  47. #
  48. # (http://www.gnu.org/copyleft/gpl.html)
  49. #
  50. # CODE:
  51. #
  52. # While this program works, it is a temporary solution that is not ideal.
  53. #
  54. # This script fetches most of it's values by running "ndd" as root. It would
  55. # be better to fetch these values from Kstat, as Kstat doesn't require root
  56. # access AND there is a Perl library for Kstat. The first version I wrote did
  57. # just that - but I found the output was often incorrect when run for
  58. # different NICs. It turns out that the Kstat values are unreliable for some
  59. # network cards, however this is being improved in future versions of Solaris.
  60. # For now, we must use ndd to get many of the values, but I hope in the future
  61. # I can switch back to an entirely Kstat based solution.
  62. #
  63. # HISTORY:
  64. #
  65. # 21-Mar-2004 Brendan Gregg Created this.
  66. # 14-Apr-2004 Michael Miller Added support for dfme, bge, ce.
  67. # 29-Apr-2004 Kevin Kwast Added support for gigabit ge.
  68. # 28-Oct-2005 Markus Schulewski Added AutoNEG column; bge DUPLEX corrected
  69. # 25-Jan-2006 Brendan Gregg Tweaked style, added some rtls support.
  70. # 26-Jan-2006 " " Readded Sun::Solaris::Kstat (ce, rtls).
  71.  
  72. use strict;
  73. use Sun::Solaris::Kstat;
  74.  
  75. #
  76. # Global Vars
  77. #
  78. $ENV{PATH} = "/usr/bin:/usr/sbin";
  79. $main::Kstat = Sun::Solaris::Kstat->new();
  80. my %Interfaces;
  81.  
  82. #
  83. # Process command line args
  84. #
  85. usage() if (defined $ARGV[0] ? $ARGV[0] : "") =~ /^(-h|--help)$/;
  86. die "ERROR1: Sorry, you must be root to run this.\n" unless -r "/dev/mem";
  87. if ($ARGV[0]) {
  88. ### Read from args
  89. while (defined $ARGV[0] and $ARGV[0] ne "") {
  90. $Interfaces{$ARGV[0]} = 1;
  91. shift @ARGV;
  92. }
  93. }
  94. else {
  95. ### Fetch from ifconfig
  96. foreach my $line (`ifconfig -a`) {
  97. next unless $line =~ /^\w*:/;
  98. my ($interface, $junk) = split /:/, $line, 2;
  99. next if $interface eq "lo0";
  100. $Interfaces{$interface} = 1;
  101. }
  102. }
  103.  
  104. #
  105. # Main
  106. #
  107. printf "%-9s %6s %6s %6s %8s\n", "Interface", "Link", "Duplex", "Speed",
  108. "AutoNEG";
  109.  
  110. foreach my $interface (keys %Interfaces) {
  111. my ($dev, $ins) = $interface =~ /^(.*?)(\d+)$/;
  112.  
  113. ### Defaults
  114. my $link = "ERR";
  115. my $duplex = "ERR";
  116. my $speed = "ERR";
  117. my $auto = "ERR";
  118.  
  119. # --- dmfe card ---
  120. if ($dev eq "dmfe") {
  121. ### Fetch status
  122. chomp($link = `ndd /dev/$dev$ins link_status 2> /dev/null`);
  123. chomp($duplex = `ndd /dev/$dev$ins link_mode 2> /dev/null`);
  124. chomp($speed = `ndd /dev/$dev$ins link_speed 2> /dev/null`);
  125. chomp($auto = `ndd /dev/$dev$ins adv_autoneg_cap 2> /dev/null`);
  126.  
  127. ### Process status
  128. unless ($speed =~ /^(10|100|1000)$/) { $speed = "ERR"; }
  129. }
  130.  
  131. # --- bge card ---
  132. elsif ($dev eq "bge") {
  133. ### Fetch status
  134. chomp($link = `ndd /dev/$dev$ins link_status 2> /dev/null`);
  135. chomp($duplex = `ndd /dev/$dev$ins link_duplex 2> /dev/null`);
  136. chomp($speed = `ndd /dev/$dev$ins link_speed 2> /dev/null`);
  137. chomp($auto = `ndd /dev/$dev$ins adv_autoneg_cap 2> /dev/null`);
  138.  
  139. ### Process status
  140. unless ($speed =~ /^(10|100|1000)$/) { $speed = "ERR"; }
  141. if ($duplex eq "2") { $duplex = 1; }
  142. elsif ($duplex eq "1") { $duplex = 0; }
  143. else { $duplex = "ERR"; }
  144. }
  145.  
  146. # --- ce card ---
  147. elsif ($dev eq "ce") {
  148. ### Fetch status
  149. $link = $main::Kstat->{$dev}->{$ins}->{$interface}->{link_up};
  150. $duplex = $main::Kstat->{$dev}->{$ins}->{$interface}->{link_duplex};
  151. $speed = $main::Kstat->{$dev}->{$ins}->{$interface}->{link_speed};
  152.  
  153. ### Fetch auto
  154. system "ndd -set /dev/$dev instance $ins > /dev/null 2>&1"
  155. and die "ERROR2: ndd failed, $interface: $!\n";
  156. chomp($auto = `ndd /dev/$dev adv_autoneg_cap 2> /dev/null`);
  157.  
  158. ### Process status
  159. $link = unpack "Z*", $link; # remove NULL padding
  160. $duplex = unpack "Z*", $duplex;
  161. $speed = unpack "Z*", $speed;
  162. if ($duplex eq "2") { $duplex = 1; }
  163. elsif ($duplex eq "1") { $duplex = 0; }
  164. else { $duplex = "ERR"; }
  165. }
  166.  
  167. # --- rtls card ---
  168. elsif ($dev eq "rtls") {
  169. ## Kstat provides a couple of these values, the others will be
  170. ## printed as "???".
  171.  
  172. ### Fetch status
  173. $duplex = $main::Kstat->{$dev}->{$ins}->{$interface}->{duplex};
  174. $speed = $main::Kstat->{$dev}->{$ins}->{$interface}->{ifspeed};
  175. $link = "???";
  176. $auto = "???";
  177.  
  178. ### Process status
  179. $duplex = unpack "Z*", $duplex; # remove NULL padding
  180. $speed = unpack "Z*", $speed;
  181. $speed /= 1000000;
  182. if ($duplex eq "full") { $duplex = 1; }
  183. elsif ($duplex eq "half") { $duplex = 0; }
  184. else { $duplex = "ERR"; }
  185. }
  186.  
  187. # --- ge card ---
  188. elsif ($dev eq "ge") {
  189. ## Unfortunately ge info from kstat is not always complete.
  190. ## My ge returns the speed as 10, 100, or 1000, but I left
  191. ## support for the simple "0" or "1" response just in case.
  192.  
  193. ### Set instance
  194. system "ndd -set /dev/$dev instance $ins > /dev/null 2>&1"
  195. and die "ERROR2: ndd failed, $interface: $!\n";
  196.  
  197. ### Fetch status
  198. chomp($link = `ndd /dev/$dev link_status 2> /dev/null`);
  199. chomp($duplex = `ndd /dev/$dev link_mode 2> /dev/null`);
  200. chomp($speed = `ndd /dev/$dev link_speed 2> /dev/null`);
  201. chomp($auto = `ndd /dev/$dev adv_1000autoneg_cap 2> /dev/null`);
  202.  
  203. ### Process speed (10, 100, or 1000)
  204. if ($speed =~ m/^(10+)/) { $speed = $1; }
  205. elsif ($speed eq "1") { $speed = 100; }
  206. elsif ($speed eq "0") { $speed = 10; }
  207. else { $speed = "ERR"; }
  208. }
  209.  
  210. # --- all other cards ---
  211. else {
  212. ### Set instance
  213. system "ndd -set /dev/$dev instance $ins > /dev/null 2>&1"
  214. and die "ERROR2: ndd failed, $interface: $!\n";
  215.  
  216. ### Fetch status
  217. chomp($link = `ndd /dev/$dev link_status 2> /dev/null`);
  218. chomp($duplex = `ndd /dev/$dev link_mode 2> /dev/null`);
  219. chomp($speed = `ndd /dev/$dev link_speed 2> /dev/null`);
  220. chomp($auto = `ndd /dev/$dev adv_autoneg_cap 2> /dev/null`);
  221.  
  222. ### Process status
  223. if ($speed eq "0") { $speed = 10; }
  224. elsif ($speed eq "1") { $speed = 100; }
  225. else { $speed = "ERR"; }
  226. }
  227.  
  228. ### Process status
  229. if ($link eq "0") { $link = "DOWN"; }
  230. elsif ($link eq "1") { $link = "UP"; }
  231. elsif ($link ne "???") { $link = "ERR"; }
  232.  
  233. if ($duplex eq "0") { $duplex = "HALF"; }
  234. elsif ($duplex eq "1") { $duplex = "FULL"; }
  235. elsif ($duplex ne "???") { $duplex = "ERR"; }
  236.  
  237. if ($auto eq "0") { $auto = "OFF"; }
  238. elsif ($auto eq "1") { $auto = "ON"; }
  239. elsif ($auto ne "???") { $auto = "ERR"; }
  240.  
  241. ### Print line
  242. printf "%-9s %6s %6s %6s %8s\n", $interface, $link, $duplex, $speed, $auto;
  243. }
  244.  
  245. #
  246. # Subroutines
  247. #
  248. sub usage {
  249. print STDERR <<END;
  250. USAGE: checkcable [-h] [interface ...]
  251. checkcable # check all configured interfaces
  252. checkcable hme0 # look at specific interface
  253. END
  254. exit 1;
  255. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement