add drop down menu for interfaces with IPX active

This commit is contained in:
Mario Fetka
2026-05-21 17:11:06 +02:00
parent 6aec044c52
commit ec32733dab

View File

@@ -34,6 +34,95 @@ sub html_escape( $ )
return $s;
}
sub kernel_network_interfaces()
{
my %interfaces = ();
if( opendir( my $dh, '/sys/class/net' ) )
{
foreach my $ifname ( readdir( $dh ) )
{
next if $ifname =~ /^\./;
next if $ifname =~ /[^-_\.A-Za-z0-9]/;
$interfaces{$ifname} = 1;
}
closedir( $dh );
}
return %interfaces;
}
sub ipx_enabled_interfaces()
{
my %ipx_interfaces = ();
# Modern Linux IPX procfs format:
# Network Node_Address Primary Device Frame_Type
# AC100B98 000000000001 Yes Internal None
# 00000022 508140F6AC45 No enp46s0u1u3u3 802.2
if( open( my $fh, '<', '/proc/net/ipx/interface' ) )
{
while( my $line = <$fh> )
{
chomp( $line );
$line =~ s/^\s+//;
$line =~ s/\s+$//;
next if $line eq '';
next if $line =~ /^Network\s+Node_Address\s+Primary\s+Device\s+Frame_Type/i;
my @fields = split( /\s+/, $line );
# Device is the fourth column. Do not scan all tokens, otherwise
# Network/Node/Frame_Type values can accidentally be treated as names.
next if scalar( @fields ) < 5;
my $dev = $fields[3];
next if ! defined( $dev );
next if $dev eq '';
next if lc( $dev ) eq 'internal';
next if $dev =~ /[^-_\.A-Za-z0-9]/;
# Only show real Linux network interfaces.
next if ! -e '/sys/class/net/' . $dev;
$ipx_interfaces{$dev} = 1;
}
close( $fh );
}
# Fallback for older distributions/tools, if present. This parser is kept
# deliberately conservative and still verifies /sys/class/net/<device>.
if( open( my $fh, '<', '/proc/net/ipx_interfaces' ) )
{
while( my $line = <$fh> )
{
chomp( $line );
$line =~ s/^\s+//;
$line =~ s/\s+$//;
next if $line eq '';
next if $line =~ /^(Network|Net|Address|Node|Interface|Device)\b/i;
foreach my $dev ( split( /\s+/, $line ) )
{
next if ! defined( $dev );
next if $dev eq '';
next if lc( $dev ) eq 'internal';
next if $dev =~ /[^-_\.A-Za-z0-9]/;
next if ! -e '/sys/class/net/' . $dev;
$ipx_interfaces{$dev} = 1;
}
}
close( $fh );
}
return sort keys %ipx_interfaces;
}
sub network_interface_options( $ )
{
my $current = $_[0];
@@ -43,17 +132,14 @@ sub network_interface_options( $ )
$current = '' unless defined $current;
if( opendir( my $dh, '/sys/class/net' ) )
# Only show interfaces where IPX is currently active. The current value is
# still preserved below, so an existing config entry is not lost if the
# interface is temporarily down or IPX is not loaded at display time.
foreach my $ifname ( ipx_enabled_interfaces() )
{
foreach my $ifname ( sort readdir( $dh ) )
{
next if $ifname =~ /^\./;
next if $ifname =~ /[^-_\.A-Za-z0-9]/;
next if $seen{$ifname};
push( @interfaces, $ifname );
$seen{$ifname} = 1;
}
closedir( $dh );
next if $seen{$ifname};
push( @interfaces, $ifname );
$seen{$ifname} = 1;
}
# Keep special/manual values usable even if they are not real kernel interfaces.
@@ -69,7 +155,7 @@ sub network_interface_options( $ )
{
my $selected = ( $ifname eq $current ) ? ' SELECTED' : '';
my $label = $ifname;
$label = '* (all interfaces)' if $ifname eq '*';
$label = '* (all IPX interfaces)' if $ifname eq '*';
$label = 'auto' if $ifname eq 'auto';
$html .= '\t\t\t\t<OPTION VALUE="' . html_escape( $ifname ) . '"' . $selected . '>' . html_escape( $label ) . '</OPTION>\n';
}