diff '--exclude=.svn' '--exclude=logs' '--exclude=edited' '--exclude=config.php' '--exclude=.index' '--exclude=observium.log' '--exclude=rrd' -urN ../observium-trunk/html/pages/addhost.inc.php ./html/pages/addhost.inc.php
--- ../observium-trunk/html/pages/addhost.inc.php	2012-03-06 15:21:41.328183283 +0100
+++ ./html/pages/addhost.inc.php	2012-03-30 13:20:30.183079833 +0200
@@ -14,14 +14,39 @@
   {
     $hostname = mres($_POST['hostname']);
 
-    if ($_POST['community'])
+    if ($_POST['snmpver'] === "v2c" or $_POST['snmpver'] === "v1")
     {
-      $config['snmp']['community'] = array($_POST['community']);
+      if ($_POST['community'])
+      {
+        $config['snmp']['community'] = array($_POST['community']);
+      }
+
+      $snmpver = mres($_POST['snmpver']);
+      if ($_POST['port']) { $port = mres($_POST['port']); } else { $port = "161"; }
+      print_message("Adding host $hostname communit" . (count($config['snmp']['community']) == 1 ? "y" : "ies") . " "  . implode(', ',$config['snmp']['community']) . " port $port");
     }
+    elseif ($_POST['snmpver'] === "v3")
+    {
+      $v3 = array (
+        'authlevel' => mres($_POST['authlevel']),
+        'authname' => mres($_POST['authname']),
+        'authpass' => mres($_POST['authpass']),
+        'authalgo' => mres($_POST['authalgo']),
+        'cryptopass' => mres($_POST['cryptopass']),
+        'cryptoalgo' => mres($_POST['cryptoalgo']),
+      );
+
+      array_push($config['snmp']['v3'], $v3);
+      
+      $snmpver = "v3";
 
-    $snmpver = mres($_POST['snmpver']);
-    if ($_POST['port']) { $port = mres($_POST['port']); } else { $port = "161"; }
-    print_message("Adding host $hostname communit" . (count($config['snmp']['community']) == 1 ? "y" : "ies") . " "  . implode(', ',$config['snmp']['community']) . " port $port");
+      if ($_POST['port']) { $port = mres($_POST['port']); } else { $port = "161"; }
+      print_message("Adding SNMPv3 host $hostname port $port");
+    }
+    else
+    {
+      print_error("Unsupported SNMP Version. There was a dropdown menu, how did you reach this error ?");
+    }
     $result = addHost($hostname, $snmpver, $port);
     if ($result)
     {
@@ -45,20 +70,68 @@
         <td><strong>Hostname</strong></td>
         <td><input type="text" name="hostname" size="32"></td>
       </tr>
-        <td><strong>Community</strong></td>
-        <td><input type="text" name="community" size="32"></td>
-      </tr>
       <tr>
         <td><strong>SNMP Version</strong></td>
         <td>
           <select name="snmpver">
             <option value="v1">v1</option>
             <option value="v2c" selected>v2c</option>
+            <option value="v3">v3</option>
           </select>
           &nbsp;<strong>Port</strong> <input type="text" name="port" size="16">
         </td>
       </tr>
       <tr>
+        <td colspan=2><strong>SNMPv1/2c Configuration</strong></td>
+      </tr>
+      <tr>
+        <td><strong>Community</strong></td>
+        <td><input type="text" name="community" size="32"></td>
+      </tr>
+      <tr>
+        <td colspan=2><strong>SNMPv3 Configuration</strong></td>
+      </tr>
+      <tr>
+        <td><strong>Auth Level</strong></td>
+        <td>
+          <select name="authlevel">
+            <option value="noAuthNoPriv" selected>NoAuthNoPriv</option>
+            <option value="authNoPriv">AuthNoPriv</option>
+            <option value="authPriv">AuthPriv</option>
+          </select>
+        </td>
+      </tr>
+      <tr>
+        <td><strong>Auth User Name</strong></td>
+        <td><input type="text" name="authname" size="32"></td>
+      </tr>
+      <tr>
+        <td><strong>Auth Password</strong></td>
+        <td><input type="text" name="authpass" size="32"></td>
+      </tr>
+      <tr>
+        <td><strong>Auth Algorithm</strong></td>
+        <td>
+          <select name="authalgo">
+            <option value="MD5" selected>MD5</option>
+            <option value="SHA1">SHA1</option>
+          </select>
+        </td>
+      </tr>
+      <tr>
+        <td><strong>Crypto Password</strong></td>
+        <td><input type="text" name="cryptopass" size="32"></td>
+      </tr>
+      <tr>
+        <td><strong>Crypto Algorithm</strong></td>
+        <td>
+          <select name="cryptoalgo">
+            <option value="AES" selected>AES</option>
+            <option value="DES">DES</option>
+          </select>
+        </td>
+      </tr>
+      <tr>
         <td></td><td><input type="submit" class="submit" name="Submit" value="Add Host"></td>
       </tr>
     </table>
diff '--exclude=.svn' '--exclude=logs' '--exclude=edited' '--exclude=config.php' '--exclude=.index' '--exclude=observium.log' '--exclude=rrd' -urN ../observium-trunk/html/pages/device/edit/snmp.inc.php ./html/pages/device/edit/snmp.inc.php
--- ../observium-trunk/html/pages/device/edit/snmp.inc.php	2012-03-06 15:21:40.832183275 +0100
+++ ./html/pages/device/edit/snmp.inc.php	2012-03-30 19:16:47.451419699 +0200
@@ -9,11 +9,28 @@
     $port = mres($_POST['port']);
     $timeout = mres($_POST['timeout']);
     $retries = mres($_POST['retries']);
-
-    #FIXME needs more sanity checking! and better feedback
-    $update = array('community' => $_POST['community'], 'snmpver' => $_POST['snmpver'], 'port' => $_POST['port']);
-    if ($_POST['timeout']) { $update['timeout'] = $_POST['timeout']; } else { $update['timeout'] = array('NULL'); }
-    if ($_POST['retries']) { $update['retries'] = $_POST['retries']; } else { $update['retries'] = array('NULL'); }
+    $v3 = array (
+      'authlevel' => mres($_POST['authlevel']),
+      'authname' => mres($_POST['authname']),
+      'authpass' => mres($_POST['authpass']),
+      'authalgo' => mres($_POST['authalgo']),
+      'cryptopass' => mres($_POST['cryptopass']),
+      'cryptoalgo' => mres($_POST['cryptoalgo'])
+    );
+
+    #FIXME needs better feedback
+    $update = array(
+      'community' => $community, 
+      'snmpver' => $snmpver, 
+      'port' => $port
+    );
+
+    if ($_POST['timeout']) { $update['timeout'] = $timeout; } 
+      else { $update['timeout'] = array('NULL'); }
+    if ($_POST['retries']) { $update['retries'] = $retries; } 
+      else { $update['retries'] = array('NULL'); }
+    
+    $update = array_merge($update, $v3);
 
     $rows_updated = dbUpdate($update, 'devices', '`device_id` = ?',array($device['device_id']));
 
@@ -47,23 +64,75 @@
   <input type=hidden name='editing' value='yes'>
   <table width='500' border='0'>
     <tr>
+      <td><div align=right>SNMP Version</div></td>
+      <td>
+        <select name='snmpver'>
+          <option value='v1'>v1</option>
+          <option value='v2c' " . ($device['snmpver'] == 'v2c' ? 'selected' : '') . ">v2c</option>
+          <option value='v3' " . ($device['snmpver'] == 'v3' ? 'selected' : '') . ">v3</option>
+        </select>
+      </td>
+    </tr>
+  <div id='snmpv12'>
+  <!-- To be able to hide it -->
+    <tr>
+      <td colspan='2'><strong>SNMPv1/v2c Configuration</strong></td>
+    </tr>
+    <tr>
       <td width='150'><div align='right'>SNMP Community</div></td>
-      <td><input name='community' size='20' value='" . $device['community'] . "' />
+      <td><input name='community' size='32' value='" . $device['community'] . "' />
       </td>
     </tr>
+  </div>
+  <div id='snmpv3'>
+  <!-- To be able to hide it -->
     <tr>
-    <td><div align=right>SNMP Version</div></td>
-    <td><select name='snmpver'>
-          <option value='v1'>v1</option>
-          <option value='v2c'" . ($device['snmpver'] == 'v2c' ? 'selected=selected' : '') . ">v2c</option>
+      <td colspan='2'><strong>SNMPv3 Configuration</strong></td>
+    </tr>
+    <tr>
+      <td width='150'><div align='right'>Auth Level</div></td>
+      <td>
+        <select name='authlevel'>
+          <option value='NoAuthNoPriv'>NoAuthNoPriv</option>
+          <option value='AuthNoPriv' " . ($device['authlevel'] == "authNoPriv" ? 'selected' : '') . ">AuthNoPriv</option>
+          <option value='AuthPriv' " . ($device['authlevel'] == "authPriv" ? 'selected' : '') . ">AuthPriv</option>
         </select>
       </td>
     </tr>
     <tr>
-      <td><div align='right'>SNMP Port</div></td>
-      <td><input name='port' size='20' value='" . $device['port'] . "' />
+      <td width='150'><div align='right'>Auth User Name</div></td>
+      <td><input type='text' name='authname' size='32' value='" . $device['authname']  . "'></td>
+    </tr>
+    <tr>
+      <td width='150'><div align='right'>Auth Password</div></td>
+      <td><input type='text' name='authpass' size='32' value='" . $device['authpass']  . "'></td>
+    </tr>
+    <tr>
+      <td width='150'><div align='right'>Auth Algorithm</strong></td>
+      <td>
+        <select name='authalgo'>
+          <option value='MD5'>MD5</option>
+          <option value='SHA1' " . ($device['authalgo'] === "SHA1" ? 'selected' : '') . ">SHA1</option>
+        </select>
+      </td>
+    </tr>
+    <tr>
+      <td width='150'><div align='right'>Crypto Password</div></td>
+      <td><input type='text' name='cryptopass' size='32' value='" . $device['cryptopass']  . "'></td>
+    </tr>
+    <tr>
+      <td width='150'><div align='right'>Crypto Algorithm</div></td>
+      <td>
+        <select name='cryptoalgo'>
+          <option value='AES'>AES</option>
+          <option value='DES' " . ($device['cryptoalgo'] === "DES" ? 'selected' : '') . ">DES</option>
+        </select>
       </td>
     </tr>
+  </div>
+    <tr>
+      <td colspan='2'><strong>SNMP Connectivity</strong></td>
+    </tr>
     <tr>
       <td><div align='right'>SNMP Transport</div></td>
       <td>
@@ -80,14 +149,19 @@
       </td>
     </tr>
     <tr>
+      <td><div align='right'>SNMP Port</div></td>
+      <td><input name='port' size='32' value='" . $device['port'] . "' />
+      </td>
+    </tr>
+    <tr>
       <td><div align='right'>SNMP Timeout</div></td>
-      <td><input name='timeout' size='20' value='" . ($device['timeout'] ? $device['timeout'] : '') . "' />&nbsp;
+      <td><input name='timeout' size='32' value='" . ($device['timeout'] ? $device['timeout'] : '') . "' />&nbsp;
       <em>(milli)seconds</em>
       </td>
     </tr>
     <tr>
       <td><div align='right'>SNMP Retries</div></td>
-      <td colspan='3'><input name='retries' size='20' value='" . ($device['timeout'] ? $device['retries'] : '') . "' />
+      <td colspan='3'><input name='retries' size='32' value='" . ($device['timeout'] ? $device['retries'] : '') . "' />
       </td>
     </tr>");
  
diff '--exclude=.svn' '--exclude=logs' '--exclude=edited' '--exclude=config.php' '--exclude=.index' '--exclude=observium.log' '--exclude=rrd' -urN ../observium-trunk/includes/defaults.inc.php ./includes/defaults.inc.php
--- ../observium-trunk/includes/defaults.inc.php	2012-03-30 14:26:35.167142868 +0200
+++ ./includes/defaults.inc.php	2012-03-30 14:26:19.899142637 +0200
@@ -79,9 +79,22 @@
 ### SNMP Settings - Timeouts/Retries disabled as default
 #$config['snmp']['timeout'] = 1;            # timeout in seconds
 #$config['snmp']['retries'] = 5;            # how many times to retry the query
-$config['snmp']['community'][0] = "public"; # Communities to try during adding hosts and discovery
 $config['snmp']['transports'] = array('udp', 'udp6', 'tcp', 'tcp6');
 
+$config['snmp']['version'] = "v2c";         # Default version to use
+
+# SNMPv1/2c default settings
+$config['snmp']['community'][0] = "public"; # Communities to try during adding hosts and discovery
+
+# SNMPv3 default settings
+# The array can be expanded to give another set of parameters
+$config['snmp']['v3'][0]['authlevel'] = "noAuthNoPriv";  # noAuthNoPriv | authNoPriv | authPriv
+$config['snmp']['v3'][0]['authname'] = "observium";      # User Name (required even for noAuthNoPriv)
+$config['snmp']['v3'][0]['authpass'] = "";               # Auth Passphrase
+$config['snmp']['v3'][0]['authalgo'] = "MD5";            # MD5 | SHA1
+$config['snmp']['v3'][0]['cryptopass'] = "";             # Privacy (Encryption) Passphrase
+$config['snmp']['v3'][0]['cryptoalgo'] = "AES";          # AES | DES
+
 ### Autodiscovery Settings
 
 $config['autodiscovery']['xdp']            = true; ## Autodiscover hosts via discovery protocols
diff '--exclude=.svn' '--exclude=logs' '--exclude=edited' '--exclude=config.php' '--exclude=.index' '--exclude=observium.log' '--exclude=rrd' -urN ../observium-trunk/includes/functions.php ./includes/functions.php
--- ../observium-trunk/includes/functions.php	2012-03-29 15:14:08.021814593 +0200
+++ ./includes/functions.php	2012-03-30 13:15:56.911075488 +0200
@@ -177,29 +177,59 @@
       if (isPingable($host))
       {
         $added = 0;
-        /// try each community from config
-        foreach ($config['snmp']['community'] as $community)
+        if ($snmpver === "v3")
         {
-          $device = deviceArray($host, $community, $snmpver, $port, $transport);
-          if (isSNMPable($device))
+          // Try each set of parameters from config
+          foreach ($config['snmp']['v3'] as $v3)
           {
-            print_message("Trying community $community");
-            $snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB");
-            if ($snmphost == "" || ($snmphost && ($snmphost == $host || $hostshort = $host)))
+            $device = deviceArray($host, NULL, $snmpver, $port, $transport, $v3);
+            if (isSNMPable($device))
             {
-              $device_id = createHost ($host, $community, $snmpver, $port, $transport);
-              return $device_id;
+              print_message("Trying v3 parameters ... ");
+              $snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB");
+              if (empty($snmphost) or ($snmphost == $host || $hostshort = $host))
+              {
+                $device_id = createHost ($host, NULL, $snmpver, $port, $transport, $v3);
+                return $device_id;
+              } else {
+                print_error("Given hostname does not match SNMP-read hostname ($snmphost)!");
+              }
             } else {
-              print_error("Given hostname does not match SNMP-read hostname ($snmphost)!");
+              print_error("No reply with SNMPv3 " . $v3['authlevel'] . " " . $v3['authname'].".");
             }
-          } else {
-            print_error("No reply on community $community");
           }
         }
+        elseif ($snmpver === "v2c" or $snmpver === "v1")
+        {
+          /// try each community from config
+          foreach ($config['snmp']['community'] as $community)
+          {
+            $device = deviceArray($host, $community, $snmpver, $port, $transport, NULL);
+            if (isSNMPable($device))
+            {
+              print_message("Trying community $community");
+              $snmphost = snmp_get($device, "sysName.0", "-Oqv", "SNMPv2-MIB");
+              if ($snmphost == "" || ($snmphost && ($snmphost == $host || $hostshort = $host)))
+              {
+                $device_id = createHost ($host, $community, $snmpver, $port, $transport);
+                return $device_id;
+              } else {
+                print_error("Given hostname does not match SNMP-read hostname ($snmphost)!");
+              }
+            } else {
+              print_error("No reply on community $community");
+            }
+          }
+        }
+        else
+        {
+          print_error("Unsupported SNMP Version");
+        }
         if (!$device_id)
         {
           /// Failed SNMP
-          print_error("Could not reach $host with given SNMP community");
+          if ($snmpver === "v3") {print_error("Could not reach $host with given SNMPv3 credentials.");}
+            else {print_error("Could not reach $host with given SNMP community.");}
         }
       } else {
         /// failed Reachability
@@ -228,15 +258,28 @@
   } else { fclose($handle); return 0; }
 }
 
-function deviceArray($host, $community, $snmpver, $port = 161, $transport = 'udp')
+function deviceArray($host, $community, $snmpver, $port = 161, $transport = 'udp', $v3)
 {
   $device = array();
   $device['hostname'] = $host;
   $device['port'] = $port;
-  $device['community'] = $community;
-  $device['snmpver'] = $snmpver;
   $device['transport'] = $transport;
 
+  $device['snmpver'] = $snmpver;
+  if ($snmpver === "v2c" or $snmpver === "v1")
+  {
+    $device['community'] = $community;
+  }
+  elseif ($snmpver === "v3")
+  {
+    $device['authlevel']  = $v3['authlevel'];
+    $device['authname']   = $v3['authname'];
+    $device['authpass']   = $v3['authpass'];
+    $device['authalgo']   = $v3['authalgo'];
+    $device['cryptopass'] = $v3['cryptopass'];
+    $device['cryptoalgo'] = $v3['cryptoalgo'];
+  }
+
   return $device;
 }
 
@@ -329,7 +372,7 @@
   return $sec + $usec;
 }
 
-function createHost($host, $community, $snmpver, $port = 161, $transport = 'udp')
+function createHost($host, $community = NULL, $snmpver, $port = 161, $transport = 'udp', $v3 = array())
 {
   $host = trim(strtolower($host));
 
@@ -339,7 +382,10 @@
                   'port' => $port,
                   'transport' => $transport,
                   'status' => '1',
-                  'snmpver' => $snmpver);
+                  'snmpver' => $snmpver
+            );
+
+  $device = array_merge($device, $v3);
 
   $device['os'] = getHostOS($device);
 
diff '--exclude=.svn' '--exclude=logs' '--exclude=edited' '--exclude=config.php' '--exclude=.index' '--exclude=observium.log' '--exclude=rrd' -urN ../observium-trunk/includes/polling/ipSystemStats.inc.php ./includes/polling/ipSystemStats.inc.php
--- ../observium-trunk/includes/polling/ipSystemStats.inc.php	2012-03-06 15:21:50.616183431 +0100
+++ ./includes/polling/ipSystemStats.inc.php	2012-03-20 16:18:37.025570646 +0100
@@ -98,4 +98,4 @@
 
 echo("\n");
 
-?>
\ No newline at end of file
+?>
diff '--exclude=.svn' '--exclude=logs' '--exclude=edited' '--exclude=config.php' '--exclude=.index' '--exclude=observium.log' '--exclude=rrd' -urN ../observium-trunk/includes/snmp.inc.php ./includes/snmp.inc.php
--- ../observium-trunk/includes/snmp.inc.php	2012-03-30 14:26:35.171142870 +0200
+++ ./includes/snmp.inc.php	2012-03-30 14:13:36.603130627 +0200
@@ -1,5 +1,7 @@
 <?php
 
+// If anybody has again the idea to implement the PHP internal library calls,
+// be aware that it was tried and banned by lead dev Adam
 
 function string_to_oid($string)
 {
@@ -34,7 +36,9 @@
     $device['transport'] = "udp";
   }
 
-  $cmd = $config['snmpget'] . " -" . $device['snmpver'] . " -c " . $device['community'] . " ";
+  $cmd  = $config['snmpget']; 
+  $cmd .= snmp_gen_auth ($device);
+
   if ($options) { $cmd .= " " . $options; }
   if ($mib) { $cmd .= " -m " . $mib; }
   if ($mibdir) { $cmd .= " -M " . $mibdir; } else { $cmd .= " -M ".$config['mibdir']; }
@@ -42,20 +46,16 @@
   if (isset($timeout)) { $cmd .= " -t " . $timeout; }
   if (isset($retries)) { $cmd .= " -r " . $retries; }
 
-  $cmd .= " ".$device['transport'].":".$device['hostname'].":".$device['port']." ".$oids;
+  $cmd .= " ".$device['transport'].":".$device['hostname'].":".$device['port'];
+  $cmd .= " ".$oids;
   if (!$debug) { $cmd .= " 2>/dev/null"; }
   $data = trim(external_exec($cmd));
   $runtime_stats['snmpget']++;
   foreach (explode("\n", $data) as $entry)
   {
-    list($oid,$value) = explode("=", $entry);
-    $oid = trim($oid); $value = trim($value);
-    list($oid, $index) = explode(".", $oid);
-    if (!strstr($value, "at this OID") && isset($oid) && isset($index))
-    {
-      $array[$index][$oid] = $value;
-    }
+    $array[$index][$oid] = $value;
   }
+
   return $array;
 }
 
@@ -88,20 +88,24 @@
     echo("Please report this to the Observium team.");
   }
 
-  $cmd = $config['snmpget'] . " -" . $device['snmpver'] . " -c " . $device['community'] . " ";
+  $cmd  = $config['snmpget']; 
+  $cmd .= snmp_gen_auth ($device);
 
   if ($options) { $cmd .= " " . $options; }
   if ($mib) { $cmd .= " -m " . $mib; }
-  if ($mibdir) { $cmd .= " -M " . $mibdir; } else { $cmd .= " -M ".$config['mibdir']; }
+  if ($mibdir) { $cmd .= " -M " . $mibdir; } 
+    else { $cmd .= " -M ".$config['mibdir']; }
   if (isset($timeout)) { $cmd .= " -t " . $timeout; }
   if (isset($retries)) { $cmd .= " -r " . $retries; }
-
-  $cmd .= " ".$device['transport'].":".$device['hostname'].":".$device['port']." ".$oid;
+  $cmd .= " " . $device['transport'].":".$device['hostname'].":".$device['port'];
+  $cmd .= " " . $oid;
+     
   if (!$debug) { $cmd .= " 2>/dev/null"; }
   $data = trim(external_exec($cmd));
 
   $runtime_stats['snmpget']++;
-  if (is_string($data) && (preg_match("/No Such Instance/i", $data) || preg_match("/No Such Object/i", $data) || preg_match("/No more variables left/i", $data)))
+
+  if (is_string($data) && (preg_match("/(No Such Instance|No Such Object|No more variables left|Authentication failure)/i", $data)))
   {
     return false;
   }
@@ -132,7 +136,6 @@
     $device['transport'] = "udp";
   }
 
-  // php has no bulkwalk functionality, so use binary for this.
   if ($device['snmpver'] == 'v1' || $config['os'][$device['os']]['nobulk'])
   {
     $snmpcommand = $config['snmpwalk'];
@@ -141,8 +144,11 @@
   {
     $snmpcommand = $config['snmpbulkwalk'];
   }
+  
+  $cmd = $snmpcommand;
+
+  $cmd .= snmp_gen_auth ($device);
 
-  $cmd = $snmpcommand . " -" . $device['snmpver'] . " -c " . $device['community'] . " ";
   if ($options) { $cmd .= " $options "; }
   if ($mib) { $cmd .= " -m $mib"; }
   if ($mibdir) { $cmd .= " -M " . $mibdir; } else { $cmd .= " -M ".$config['mibdir']; }
@@ -202,7 +208,10 @@
     $snmpcommand = $config['snmpbulkwalk'];
   }
 
-  $cmd = $snmpcommand . " -O snQ -" . $device['snmpver'] . " -c " . $device['community'] . " ";
+  $cmd = $snmpcommand;
+  $cmd .= snmp_gen_auth ($device);
+
+  $cmd .= " -O snQ"; 
   if ($mib) { $cmd .= " -m $mib"; }
   $cmd .= " -M ".$config['install_dir']."/mibs";
   if (isset($timeout)) { $cmd .= " -t " . $timeout; }
@@ -268,8 +277,11 @@
     $snmpcommand = $config['snmpbulkwalk'];
   }
 
-  $cmd = $snmpcommand . " -O Qs -" . $device['snmpver'] . " -c " . $device['community'] . " ";
-  $cmd .= " -M ".$config['install_dir']."/mibs";
+  $cmd = $snmpcommand;
+  $cmd .= snmp_gen_auth ($device);
+
+  $cmd .= " -O Qs"; 
+  $cmd .= " -M " . $config['install_dir']."/mibs";
   $cmd .= " -m IF-MIB ifIndex";
 
   if (isset($timeout)) { $cmd .= " -t " . $timeout; }
@@ -410,7 +422,11 @@
   {
     $snmpcommand = $config['snmpbulkwalk'];
   }
-  $cmd = $snmpcommand . " -O QUs -" . $device['snmpver'] . " -c " . $device['community'] . " ";
+
+  $cmd = $snmpcommand;
+  $cmd .= snmp_gen_auth ($device);
+
+  $cmd .= " -O QUs";
   $cmd .= " -M ".$config['install_dir']."/mibs";
   if ($mib) { $cmd .= " -m $mib"; }
   if (isset($timeout)) { $cmd .= " -t " . $timeout; }
@@ -467,7 +483,10 @@
     $snmpcommand = $config['snmpbulkwalk'];
   }
 
-  $cmd = $snmpcommand . " -O QUs -" . $device['snmpver'] . " -c " . $device['community'] . " ";
+  $cmd = $snmpcommand;
+  $cmd .= snmp_gen_auth ($device);
+
+  $cmd .= " -O QUs";
   $cmd .= " -M ".$config['install_dir']."/mibs";
   if ($mib) { $cmd .= " -m $mib"; }
   if (isset($timeout)) { $cmd .= " -t " . $timeout; }
@@ -524,7 +543,10 @@
     $snmpcommand = $config['snmpbulkwalk'];
   }
 
-  $cmd = $snmpcommand . " -O QUs -" . $device['snmpver'] . " -c " . $device['community'] . " ";
+  $cmd = $snmpcommand;
+  $cmd .= snmp_gen_auth ($device);
+
+  $cmd .= " -O QUs"; 
   if ($mib) { $cmd .= " -m $mib"; }
   $cmd .= " -M ".$config['install_dir']."/mibs";
   if (isset($timeout)) { $cmd .= " -t " . $timeout; }
@@ -583,7 +605,10 @@
     $string .= " $oid.$port";
   }
 
-  $cmd = $config['snmpget'] . " -O vq -" . $device['snmpver'] . " -c " . $device['community'] . " ";
+  $cmd = $config['snmpget'];
+  $cmd .= snmp_gen_auth ($device);
+
+  $cmd .= " -O vq"; 
   if (isset($timeout)) { $cmd .= " -t " . $timeout; }
   if (isset($retries)) { $cmd .= " -r " . $retries; }
   $cmd .= " -M ".$config['install_dir']."/mibs";
@@ -629,7 +654,10 @@
     $device['transport'] = "udp";
   }
 
-  $cmd = $config['snmpwalk'] . " -CI -m CISCO-STACK-MIB -O q -" . $device['snmpver'] . " -c " . $device['community'] . " ";
+  $cmd = $config['snmpwalk'];
+  $cmd .= snmp_gen_auth ($device);
+
+  $cmd .= " -CI -m CISCO-STACK-MIB -O q"; 
   $cmd .= " -M ".$config['install_dir']."/mibs";
   if (isset($timeout)) { $cmd .= " -t " . $timeout; }
   if (isset($retries)) { $cmd .= " -r " . $retries; }
@@ -673,7 +701,10 @@
     $device['transport'] = "udp";
   }
 
-  $cmd = $config['snmpwalk'] . " -CI -m CISCO-STACK-MIB -O Qs -" . $device['snmpver'] . " -c " . $device['community'] . " ";
+  $cmd = $config['snmpwalk'];
+  $cmd .= snmp_gen_auth ($device);
+
+  $cmd .= " -CI -m CISCO-STACK-MIB -O Qs"; 
   $cmd .= " -M ".$config['install_dir']."/mibs";
   if (isset($timeout)) { $cmd .= " -t " . $timeout; }
   if (isset($retries)) { $cmd .= " -r " . $retries; }
@@ -698,4 +729,53 @@
   return $array;
 }
 
+function snmp_gen_auth (&$device)
+{
+  global $debug;
+
+  $cmd = "";
+
+  if ($device['snmpver'] === "v3")
+  {
+    $cmd = " -v3 -n \"\" -l " . $device['authlevel'];
+
+    if ($device['authlevel'] === "noAuthNoPriv")
+    {
+      // We have to provide a username anyway (see Net-SNMP doc)
+      $cmd .= " -u observium";
+    }
+    elseif ($device['authlevel'] === "authNoPriv")
+    {
+      $cmd .= " -a " . $device['authalgo'];
+      $cmd .= " -A \"" . $device['authpass'] . "\"";
+      $cmd .= " -u " . $device['authname'];
+    }
+    elseif ($device['authlevel'] === "authPriv")
+    {
+      $cmd .= " -a " . $device['authalgo'];
+      $cmd .= " -A \"" . $device['authpass'] . "\"";
+      $cmd .= " -u " . $device['authname'];
+      $cmd .= " -x " . $device['cryptoalgo'];
+      $cmd .= " -X \"" . $device['cryptopass'] . "\"";
+    }
+    else
+    {
+      if ($debug) { print "DEBUG: " . $device['snmpver'] ." : Unsupported SNMPv3 AuthLevel (wtf have you done ?)\n"; }
+    }
+  }
+  elseif ($device['snmpver'] === "v2c" or $device['snmpver'] === "v1")
+  {
+    $cmd  = " -" . $device['snmpver'];
+    $cmd .= " -c " . $device['community'];
+  }
+  else
+  {
+    if ($debug) { print "DEBUG: " . $device['snmpver'] ." : Unsupported SNMP Version (wtf have you done ?)\n"; }
+  }
+
+  if ($debug) { print "DEBUG: SNMP Auth options = $cmd\n"; }
+
+  return $cmd;
+}
+
 ?>
diff '--exclude=.svn' '--exclude=logs' '--exclude=edited' '--exclude=config.php' '--exclude=.index' '--exclude=observium.log' '--exclude=rrd' -urN ../observium-trunk/sql-schema/012.sql ./sql-schema/012.sql
--- ../observium-trunk/sql-schema/012.sql	1970-01-01 01:00:00.000000000 +0100
+++ ./sql-schema/012.sql	2012-03-29 11:12:51.381584436 +0200
@@ -0,0 +1,6 @@
+ALTER TABLE `devices` ADD `authlevel` ENUM("noAuthNoPriv", "authNoPriv", "authPriv") NULL DEFAULT NULL AFTER `community`;
+ALTER TABLE `devices` ADD `authname` VARCHAR(64) NULL DEFAULT NULL AFTER `authlevel`;
+ALTER TABLE `devices` ADD `authpass` VARCHAR(64) NULL DEFAULT NULL AFTER `authname`;
+ALTER TABLE `devices` ADD `authalgo` ENUM("MD5", "SHA1") NULL DEFAULT NULL AFTER `authpass`;
+ALTER TABLE `devices` ADD `cryptopass` VARCHAR(64) NULL DEFAULT NULL AFTER `authalgo`;
+ALTER TABLE `devices` ADD `cryptoalgo` ENUM("AES", "DES") NULL DEFAULT NULL AFTER `cryptopass`;
