Code

Updated listing
[gosa.git] / gosa-si / gosa-si-bus
index bec214a3f4520948ba25842d081c6e8cf5fe494d..a5d50f1d2429bbd1db64e2b82ba3daeb49cdb56c 100755 (executable)
@@ -36,11 +36,9 @@ use Cwd;
 use File::Spec;
 use GOSA::GosaSupportDaemon;
 use GOSA::DBsqlite;
-#use IPC::Shareable qw( :lock);
-#IPC::Shareable->clean_up_all;
 
 my ($cfg_file, $default_cfg_file, %cfg_defaults, $foreground, $verbose);
-my ($bus_activ, $bus_passwd, $bus_ip, $bus_port, $bus_address, $bus, $bus_mac_address);
+my ($bus_activ, $bus_passwd, $bus_ip, $bus_port, $bus_address, $bus, $bus_mac_address, $network_interface);
 my ($pid_file, $procid, $pid, $log_file, $my_own_address);
 my (%free_child, %busy_child, $child_max, $child_min, %child_alive_time, $child_timeout);
 my ($bus_known_server_db, $bus_known_server_file_name);
@@ -60,6 +58,7 @@ $foreground = 0 ;
 "bus" =>
     {"bus_activ" => [\$bus_activ, "on"],
     "bus_passwd" => [\$bus_passwd, ""],
+    "bus_ip" => [\$bus_ip, "0.0.0.0"],
     "bus_port" => [\$bus_port, "20080"],
     }
     );
@@ -107,7 +106,7 @@ sub daemon_log {
             print STDERR "cannot open $log_file: $!";
             return }
         chomp($msg);
-        if($level <= $verbose){
+        if($level && $verbose && $level <= $verbose){
             print LOG_HANDLE $msg."\n";
             if(defined $foreground) { print $msg."\n" }
         }
@@ -230,33 +229,126 @@ sub sig_int_handler {
 }
 $SIG{INT} = \&sig_int_handler;
 
+#===  FUNCTION  ================================================================
+#         NAME:  get_interface_for_ip
+#   PARAMETERS:  ip address (i.e. 192.168.0.1)
+#      RETURNS:  array: list of interfaces if ip=0.0.0.0, matching interface if found, undef else
+#  DESCRIPTION:  Uses proc fs (/proc/net/dev) to get list of interfaces.
+#===============================================================================
+sub get_interface_for_ip {
+        my $result;
+        my $ip= shift;
+        if ($ip && length($ip) > 0) {
+                my @ifs= &get_interfaces();
+                if($ip eq "0.0.0.0") {
+                        $result = "all";
+                } else {
+                        foreach (@ifs) {
+                                my $if=$_;
+                                if(get_ip($if) eq $ip) {
+                                        $result = $if;
+                                }
+                        }
+                }
+        }
+        return $result;
+}
 
 #===  FUNCTION  ================================================================
-#         NAME:  get_ip_and_mac 
-#   PARAMETERS:  nothing
-#      RETURNS:  (ip, mac) 
-#  DESCRIPTION:  executes /sbin/ifconfig and parses the output, the first occurence 
-#                of a inet address is returned as well as the mac address in the line
-#                above the inet address
+#         NAME:  get_interfaces 
+#   PARAMETERS:  none
+#      RETURNS:  (list of interfaces) 
+#  DESCRIPTION:  Uses proc fs (/proc/net/dev) to get list of interfaces.
 #===============================================================================
-sub get_ip_and_mac {
-    my $ip = "0.0.0.0.0"; # Defualt-IP
-    my $mac_address = "00:00:00:00:00:00";  # Default-MAC
-    my @ifconfig = qx(/sbin/ifconfig);
-    foreach(@ifconfig) {
-        if (/Hardware Adresse (\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2})/) {
-            $mac_address = "$1:$2:$3:$4:$5:$6";
-            next;
+sub get_interfaces {
+        my @result;
+        my $PROC_NET_DEV= ('/proc/net/dev');
+
+        open(PROC_NET_DEV, "<$PROC_NET_DEV")
+                or die "Could not open $PROC_NET_DEV";
+
+        my @ifs = <PROC_NET_DEV>;
+
+        close(PROC_NET_DEV);
+
+        # Eat first two line
+        shift @ifs;
+        shift @ifs;
+
+        chomp @ifs;
+        foreach my $line(@ifs) {
+                my $if= (split /:/, $line)[0];
+                $if =~ s/^\s+//;
+                push @result, $if;
         }
-        if (/inet Adresse:(\d+).(\d+).(\d+).(\d+)/) {
-            $ip = "$1.$2.$3.$4";
-            last;
+
+        return @result;
+}
+
+#===  FUNCTION  ================================================================
+#         NAME:  get_mac 
+#   PARAMETERS:  interface name (i.e. eth0)
+#      RETURNS:  (mac address) 
+#  DESCRIPTION:  Uses ioctl to get mac address directly from system.
+#===============================================================================
+sub get_mac {
+        my $ifreq= shift;
+        my $result;
+        if ($ifreq && length($ifreq) > 0) {
+                if($ifreq eq "all") {
+                        $result = "00:00:00:00:00:00";
+                } else {
+                        my $SIOCGIFHWADDR= 0x8927;     # man 2 ioctl_list
+
+                        # A configured MAC Address should always override a guessed value
+                        if ($bus_mac_address and length($bus_mac_address) > 0) {
+                                return $bus_mac_address;
+                        }
+
+                        socket SOCKET, PF_INET, SOCK_DGRAM, getprotobyname('ip')
+                                or die "socket: $!";
+
+                        if(ioctl SOCKET, $SIOCGIFHWADDR, $ifreq) {
+                                my ($if, $mac)= unpack 'h36 H12', $ifreq;
+
+                                if (length($mac) > 0) {
+                                        $mac=~ m/^([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$/;
+                                        $mac= sprintf("%s:%s:%s:%s:%s:%s", $1, $2, $3, $4, $5, $6);
+                                        $result = $mac;
+                                }
+                        }
+                }
         }
-    }
-    return ($ip, $mac_address);
+        return $result;
 }
 
+#===  FUNCTION  ================================================================
+#         NAME:  get_ip 
+#   PARAMETERS:  interface name (i.e. eth0)
+#      RETURNS:  (ip address) 
+#  DESCRIPTION:  Uses ioctl to get ip address directly from system.
+#===============================================================================
+sub get_ip {
+        my $ifreq= shift;
+        my $result= "";
+        my $SIOCGIFADDR= 0x8915;       # man 2 ioctl_list
+        my $proto= getprotobyname('ip');
+
+        socket SOCKET, PF_INET, SOCK_DGRAM, $proto
+                or die "socket: $!";
+
+        if(ioctl SOCKET, $SIOCGIFADDR, $ifreq) {
+                my ($if, $sin)    = unpack 'a16 a16', $ifreq;
+                my ($port, $addr) = sockaddr_in $sin;
+                my $ip            = inet_ntoa $addr;
+
+                if ($ip && length($ip) > 0) {
+                        $result = $ip;
+                }
+        }
 
+        return $result;
+}
 
 #===  FUNCTION  ================================================================
 #         NAME:  activating_child
@@ -1170,8 +1262,20 @@ if(-e $log_file ) { unlink $log_file }
 daemon_log(" ", 1);
 daemon_log("$0 started!", 1);
 
+# forward error messages to logfile
+if( ! $foreground ) {
+       open(STDERR, '>>', $log_file);
+       open(STDOUT, '>>', $log_file);
+}
+
 # Just fork, if we"re not in foreground mode
-if( ! $foreground ) { $pid = fork(); }
+if( ! $foreground ) {
+       chdir '/'                 or die "Can't chdir to /: $!";
+       $pid = fork;
+       setsid                    or die "Can't start a new session: $!";
+       umask 0;
+}
+
 else { $pid = $$; }
 
 # Do something useful - put our PID into the pid_file
@@ -1189,10 +1293,9 @@ $bus_known_server_db->create_table('bus_known_server', \@server_col_names);
 
 
 # detect own ip and mac address
-($bus_ip, $bus_mac_address) = &get_ip_and_mac(); 
-if (not defined $bus_ip) {
-    die "EXIT: ip address of $0 could not be detected";
-}
+$network_interface= &get_interface_for_ip($bus_ip);
+$bus_mac_address= &get_mac($network_interface);
+
 daemon_log("bus ip address detected: $bus_ip", 1);
 daemon_log("bus mac address detected: $bus_mac_address", 1);