#!/usr/local/bin/perl -w # hmeconfig v0.1b # # by Jay Kreibich with many thanks to # Gian-Paolo D. Musumeci for technical help. # # # Copyright (C) 2000 ALL RIGHTS RESERVED # by Jay Kreibich and the Board of Trustees of the # University of Illinois at Urbana-Champaign. use strict; my( $ndd ) = ( '/usr/sbin/ndd' ); my( $dev ) = ( '/dev/hme' ); my( $ifc ) = ( '/sbin/ifconfig' ); my( @fields ) = ( 'transceiver_inuse', 'link_status', 'link_speed', 'link_mode', 'ipg1', 'ipg2', 'use_int_xcvr', 'adv_autoneg_cap', 'adv_100T4_cap', 'adv_100fdx_cap', 'adv_100hdx_cap', 'adv_10fdx_cap', 'adv_10hdx_cap', 'autoneg_cap', '100T4_cap', '100fdx_cap', '100hdx_cap', '10fdx_cap', '10hdx_cap', 'lp_autoneg_cap', 'lp_100T4_cap', 'lp_100fdx_cap', 'lp_100hdx_cap', 'lp_10fdx_cap', 'lp_10hdx_cap' ); my( $int, $num, $who ); my( @lines, $line, $ct ); ############################################################ sub GetVal #( $param ) { my( $param ) = @_; my( $r ); $r = `$ndd $dev $param`; chomp( $r ); return $r; } ############################################################ sub Download #( $inst ) { my( $inst ) = @_; my( %vals, $v ); system( "$ndd -set $dev instance $inst" ); foreach $v ( @fields ) { $vals{$v} = GetVal( $v ); } return %vals; } ############################################################ sub DumpInfo #( $ins, $ext ) { my( $ins, $ext ) = @_; my( %val ) = Download( $ins ); print "hme$ins: "; if( $val{'link_status'} ) { print "using "; print "RJ-45 at " if( $val{'transceiver_inuse'} == 0 ); print "MII at " if( $val{'transceiver_inuse'} == 1 ); print "10 Mbps " if( $val{'link_speed'} == 0 ); print "100 Mbps " if( $val{'link_speed'} == 1 ); print "half-duplex\n" if( $val{'link_mode'} == 0 ); print "full-duplex\n" if( $val{'link_mode'} == 1 ); } else { my( $ln ); open( IFC, "$ifc hme$ins |" ); $ln = ; close( IFC ); print "DOWN - "; if( $ln =~ /UP/ ) { print "(Cable/Link problem)\n"; } else { print "(Configured Down)\n"; } } if( $ext ) { my( $l ); $l = ' * RJ-45 Hardware supports: ' if( $val{'transceiver_inuse'} == 0 ); $l = ' * MII Hardware supports: ' if( $val{'transceiver_inuse'} == 1 ); $l .= " auto-neg," if( $val{'autoneg_cap'} ); $l .= " 100-T4," if( $val{'100T4_cap'} ); $l .= " 100-full," if( $val{'100fdx_cap'} ); $l .= " 100-half," if( $val{'100hdx_cap'} ); $l .= " 10-full," if( $val{'10fdx_cap'} ); $l .= " 10-half," if( $val{'10hdx_cap'} ); chop( $l ); print "$l\n"; print ' * Auto-negotiation is: '; print "ON\n" if( $val{'adv_autoneg_cap'} == 1 ); print "OFF\n" if( $val{'adv_autoneg_cap'} == 0 ); $l = ' * Enabled modes: '; $l .= " 100-T4," if( $val{'100T4_cap'} ); $l .= " 100-full," if( $val{'adv_100fdx_cap'} ); $l .= " 100-half," if( $val{'adv_100hdx_cap'} ); $l .= " 10-full," if( $val{'adv_10fdx_cap'} ); $l .= " 10-half," if( $val{'adv_10hdx_cap'} ); chop( $l ); print "$l\n"; $l = ' * Link Partner supports: '; if( $val{'adv_autoneg_cap'} == 0 ) { $l .= ' UNKNOWN - interface not in auto-negotiation mode '; } elsif( $val{'link_status'} == 0 ) { $l .= ' UNKNOWN - link down '; } else { if( $val{'lp_autoneg_cap'}== 0 ) { $l .= ' UNKNOWN - link partner does not appear to be auto-negotiating'; } $l .= " auto-neg," if( $val{'lp_autoneg_cap'} ); $l .= " 100-T4," if( $val{'lp_100T4_cap'} ); $l .= " 100-full," if( $val{'lp_100fdx_cap'} ); $l .= " 100-half," if( $val{'lp_100hdx_cap'} ); $l .= " 10-full," if( $val{'lp_10fdx_cap'} ); $l .= " 10-half," if( $val{'lp_10hdx_cap'} ); } chop( $l ); print "$l\n"; if( $val{'use_int_xcvr'} ) { print " * Ignorning MII Tranceiver\n"; } print "\n"; } } ############################################################ sub AdjustAuto #( $inst, $action, $param ) { my( $inst, $action, $param ) = @_; my( $p, $v ) = ( 'err', -1 ); my( $ln, $isup ); my( %val ); system( "$ndd -set $dev instance $inst" ); open( IFC, "$ifc hme$inst |" ); $ln = ; close( IFC ); $isup = 0; $isup = 1 if( $ln =~ /UP/ ); $v = 1 if( $action eq 'force' ); $v = 0 if( $action eq 'deny' ); DoError( ) if( $v == -1 ); $p = 'adv_autoneg_cap' if( $param eq 'auto-neg' ); DoError( ) if( $p eq 'err' ); %val = Download( $inst ); if( ( $v == 1 )and ( $val{'adv_100fdx_cap'} == 0 )and ( $val{'adv_10fdx_cap'} == 0 ) ) { if( not AreYouSure( " You have asked to turn on auto-negotiation, but have no half-duplex modes currently enabled. If the other side of the link is not also in auto-negotiation mode (even if it can do full-duplex), the interface will not come back up." ) ) { print "Action aborted.\n"; exit; } } system( "$ifc hme$inst down" ) if( $isup ); system( "$ndd -set $dev $p $v" ); system( "$ifc hme$inst up" ) if( $isup ); } ############################################################ sub AdjustSettings #( $inst, $action, $param ) { my( $inst, $action, $param ) = @_; my( $p, $v ) = ( 'err', -1 ); my( $ln, $isup ); system( "$ndd -set $dev instance $inst" ); open( IFC, "$ifc hme$inst |" ); $ln = ; close( IFC ); $isup = 0; $isup = 1 if( $ln =~ /UP/ ); $v = 1 if( $action eq 'enable' ); $v = 0 if( $action eq 'disable' ); DoError( ) if( $v == -1 ); $p = 'adv_100T4_cap' if( $param eq '100-T4' ); $p = 'adv_100fdx_cap' if( $param eq '100-full' ); $p = 'adv_100hdx_cap' if( $param eq '100-half' ); $p = 'adv_10fdx_cap' if( $param eq '10-full' ); $p = 'adv_10hdx_cap' if( $param eq '10-half' ); if( $param eq 'MII' ) { $p = 'use_int_xcvr'; $v = 0 if( $action eq 'enable' ); $v = 1 if( $action eq 'disable' ); } if( $param eq 'all' ) { if( ( $v == 0 )and( not AreYouSure( " You are about to disable all modes on interface hme$inst. The interface will not come back up." ) ) ) { print "Action aborted.\n"; exit; } system( "$ifc hme$inst down" ) if( $isup ); system( "$ndd -set $dev adv_100fdx_cap $v" ); system( "$ndd -set $dev adv_100hdx_cap $v" ); system( "$ndd -set $dev adv_10fdx_cap $v" ); system( "$ndd -set $dev adv_10hdx_cap $v" ); system( "$ifc hme$inst up" ) if( $isup ); exit; } DoError( ) if( $p eq 'err' ); system( "$ifc hme$inst down" ) if( $isup ); system( "$ndd -set $dev $p $v" ); system( "$ifc hme$inst up" ) if( $isup ); } ############################################################ sub AreYouSure #( $str ) { my( $str ) = @_; my( $l ); print STDERR "$str\n"; print STDERR "\n"; print STDERR "Are you sure you want to do this? (y/[n]): "; $l = ; print STDERR "\n"; return 1 if( $l =~ /^y/ ); return 0; } ############################################################ sub GenSystem #( $inst ) { my( $inst ) = @_; my( %val ); %val = Download( $inst ); print "*************************************************\n"; print "* Settings to configure network interface hme$inst\n"; print "*************************************************\n"; print "set hme:hme_instance=$inst\n"; print "set hme:hme_use_int_xcvr=$val{'use_int_xcvr'}\n"; print "set hme:hme_adv_autoneg_cap=$val{'adv_autoneg_cap'}\n"; print "set hme:hme_adv_100T4_cap=$val{'adv_100T4_cap'}\n"; print "set hme:hme_adv_100fdx_cap=$val{'adv_100fdx_cap'}\n"; print "set hme:hme_adv_100hdx_cap=$val{'adv_100hdx_cap'}\n"; print "set hme:hme_adv_10fdx_cap=$val{'adv_10fdx_cap'}\n"; print "set hme:hme_adv_10hdx_cap=$val{'adv_10hdx_cap'}\n"; print "*************************************************\n"; print "\n"; } ############################################################ sub DoError #( ) { my( $m ); $m = "\n"; $m .= "USAGE: hmeconfig [ ]\n"; $m .= " - displays configuration for one or all hme interfaces.\n"; $m .= "\n"; $m .= " hmeconfig force auto-neg\n"; $m .= " deny\n"; $m .= " - forces or denys the use of auto-negotiation\n"; $m .= "\n"; $m .= " hmeconfig enable 100-full\n"; $m .= " disable 100-half\n"; $m .= " 10-full\n"; $m .= " 10-half\n"; $m .= " all # all of above\n"; $m .= " MII\n"; $m .= " - enables or disables various link modes\n"; $m .= "\n"; $m .= " hmeconfig [ ] system\n"; $m .= " - generates text for /etc/system file\n"; $m .= "\n"; print STDERR $m; exit 1; } ############################################################ $who = `/usr/ucb/whoami`; chomp( $who ); if( $who ne 'root' ) { print STDERR "ERROR: You must be root to use hmeconfig.\n"; exit; } open( GRP, '/usr/bin/grep hme /etc/path_to_inst|' ); @lines = ; close( GRP ); $int = @lines; if( @ARGV == 0 ) { print "\n"; for( $ct=0 ; $ct<$int ; $ct++ ) { DumpInfo( $ct, 1 ); } exit; } if( $ARGV[0] eq 'system' ) { print "\n"; print "* Copy these lines into /etc/system\n"; for( $ct=0 ; $ct<$int ; $ct++ ) { print "\n"; GenSystem( $ct ); } exit; } elsif( not $ARGV[0] =~ /^hme(\d{1,2})$/ ) { DoError( ); } $num = $1; if( $num > ( $int - 1 ) ) { DoError( ); } if( @ARGV == 1 ) { print "\n"; DumpInfo( $num, 1 ); exit; } if( ( $ARGV[1] eq 'force' )or( $ARGV[1] eq 'deny' ) ) { DoError( ) if( @ARGV != 3 ); AdjustAuto( $num, $ARGV[1], $ARGV[2] ); exit; } if( ( $ARGV[1] eq 'enable' )or( $ARGV[1] eq 'disable' ) ) { DoError( ) if( @ARGV != 3 ); AdjustSettings( $num, $ARGV[1], $ARGV[2] ); exit; } if( $ARGV[1] eq 'system' ) { DoError( ) if( @ARGV != 2 ); print "\n"; print "* Copy these lines into /etc/system\n"; print "\n"; GenSystem( $num ); exit; } DoError( );