Can set a netmask for ip watch.
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Mon, 31 Mar 2008 15:31:27 +0000 (17:31 +0200)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Mon, 31 Mar 2008 15:31:27 +0000 (17:31 +0200)
-> the mask does not affect the content of the page admin/ipwatch (SQL limitations)
-> DO NOT use ip2long: this function sucks and can return negative numbers o_O

Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
include/xorg.misc.inc.php
modules/admin.php
templates/admin/ipwatcher.tpl
upgrade/0.9.16/04_ip.sql

index 6447ddb..0f5bae9 100644 (file)
@@ -234,7 +234,14 @@ function make_forlife($prenom, $nom, $promo)
  */
 function ip_to_uint($ip)
 {
-    return ip2long($ip);
+    $part = explode('.', $ip);
+    $v = 0;
+    $fact = 0x1000000;
+    for ($i = 0 ; $i < 4 ; ++$i) {
+        $v += $fact * $part[$i];
+        $fact >>= 8;
+    }
+    return $v;
 }
 
 /** Convert uint to ip (to build a human understandable ip)
@@ -261,14 +268,16 @@ function check_ip($level)
         }
         $ips[] = $_SERVER['REMOTE_ADDR'];
         foreach ($ips as &$ip) {
-            $ip = "ip = " . ip_to_uint($ip);
+            $ip = '(ip & mask) = (' . ip_to_uint($ip) . '& mask)';
         }
-        $res = XDB::query('SELECT  state
+        $res = XDB::query('SELECT  state, description
                              FROM  ip_watch
                             WHERE  ' . implode(' OR ', $ips) . '
                          ORDER BY  state DESC');
         if ($res->numRows()) {
-            $_SESSION['check_ip'] = $res->fetchOneCell();
+            $state = $res->fetchOneAssoc();
+            $_SESSION['check_ip'] = $state['state'];
+            $_SESSION['check_ip_desc'] = $state['description'];
         } else {
             $_SESSION['check_ip'] = 'safe';
         }
index c4b352d..ef9fa0e 100644 (file)
@@ -1101,17 +1101,18 @@ class AdminModule extends PLModule
         switch (Post::v('action')) {
         case 'create':
             if (trim(Post::v('ipN')) != '') {
-                Xdb::execute('INSERT IGNORE INTO ip_watch (ip, state, detection, last, uid, description)
-                                          VALUES ({?}, {?}, CURDATE(), NOW(), {?}, {?})',
-                             ip_to_uint(trim(Post::v('ipN'))), Post::v('stateN'), S::i('uid'), Post::v('descriptionN'));
+                Xdb::execute('INSERT IGNORE INTO ip_watch (ip, mask, state, detection, last, uid, description)
+                                          VALUES ({?}, {?}, {?}, CURDATE(), NOW(), {?}, {?})',
+                             ip_to_uint(trim(Post::v('ipN'))), ip_to_uint(trim(Post::v('maskN'))),
+                             Post::v('stateN'), S::i('uid'), Post::v('descriptionN'));
             };
             break;
 
         case 'edit':
             Xdb::execute('UPDATE ip_watch
-                             SET state = {?}, last = NOW(), uid = {?}, description = {?}
+                             SET state = {?}, last = NOW(), uid = {?}, description = {?}, mask = {?}
                            WHERE ip = {?}', Post::v('stateN'), S::i('uid'), Post::v('descriptionN'),
-                          ip_to_uint(Post::v('ipN')));
+                          ip_to_uint(Post::v('maskN')), ip_to_uint(Post::v('ipN')));
             break;
 
         default:
@@ -1128,7 +1129,7 @@ class AdminModule extends PLModule
             $sql = "SELECT  w.ip, IF(s.ip IS NULL,
                                      IF(w.ip = s2.ip, s2.host, s2.forward_host),
                                      IF(w.ip = s.ip, s.host, s.forward_host)),
-                             w.detection, w.state, a.alias AS forlife
+                            w.mask, w.detection, w.state, a.alias AS forlife
                       FROM  ip_watch        AS w
                  LEFT JOIN  logger.sessions AS s  ON (s.ip = w.ip)
                  LEFT JOIN  logger.sessions AS s2 ON (s2.forward_ip = w.ip)
@@ -1139,13 +1140,15 @@ class AdminModule extends PLModule
 
             $table = array();
             $props = array();
-            while (list($ip, $host, $date, $state, $forlife) = $it->next()) {
+            while (list($ip, $host, $mask, $date, $state, $forlife) = $it->next()) {
                 $ip = uint_to_ip($ip);
+                $mask = uint_to_ip($mask);
                 if (count($props) == 0 || $props['ip'] != $ip) {
                     if (count($props) > 0) {
                         $table[] = $props;
                     }
                     $props = array('ip'        => $ip,
+                                   'mask'      => $mask,
                                    'host'      => $host,
                                    'detection' => $date,
                                    'state'     => $state,
@@ -1159,7 +1162,7 @@ class AdminModule extends PLModule
             }
             $page->assign('table', $table);
         } elseif ($action == 'edit') {
-            $sql = "SELECT  w.detection, w.state, w.last, w.description,
+            $sql = "SELECT  w.detection, w.state, w.last, w.description, w.mask,
                             a1.alias AS edit, a2.alias AS forlife, s.host
                       FROM  ip_watch        AS w
                  LEFT JOIN  aliases         AS a1 ON (a1.id = w.uid AND a1.type = 'a_vie')
@@ -1171,9 +1174,10 @@ class AdminModule extends PLModule
             $it = Xdb::iterRow($sql, ip_to_uint($ip));
 
             $props = array();
-            while (list($detection, $state, $last, $description, $edit, $forlife, $host) = $it->next()) {
+            while (list($detection, $state, $last, $description, $mask, $edit, $forlife, $host) = $it->next()) {
                 if (count($props) == 0) {
                     $props = array('ip'          => $ip,
+                                   'mask'        => uint_to_ip($mask),
                                    'host'        => $host,
                                    'detection'   => $detection,
                                    'state'       => $state,
index 947c86c..ae30afc 100644 (file)
@@ -41,7 +41,7 @@
   {foreach from=$table item=ip}
   <tr class="{cycle values="pair,impair"}">
     <td>
-      <strong>{$ip.ip}</strong><br />
+      <strong>{$ip.ip}/{$ip.mask}</strong><br />
       <small>{$ip.host}</small><br />
       Ajoutée le {$ip.detection|date_format}
     </td>
   {/if}
   </tr>
   <tr class="pair">
+    <td class="titre">Masque d'influence</td>
+    <td><input type="text" name="maskN" value="{$ip.mask}" /></td>
+  </tr>
+  <tr class="pair">
     <td class="titre">Danger</td>
     <td>
       <select name="stateN">
index 4fcd93a..4f292aa 100644 (file)
@@ -37,6 +37,10 @@ ALTER TABLE ip_watch
 DROP PRIMARY KEY,
 DROP COLUMN ip,
 CHANGE COLUMN ip2 ip INT(11) UNSIGNED NOT NULL,
-ADD PRIMARY KEY ip (ip);
+ADD COLUMN mask uint(11) NOT NULL DEFAULT 4294967295,
+ADD PRIMARY KEY ip (ip)
+ADD INDEX network (ip, mask);
+
+ALTER TABLE ip_watch ADD COLUMN mask uint(11) NOT NULL DEFAULT 4294967295;
 
 # vim:set syntax=mysql: