A Quick-to-code Internet Access System

A typical Internet access scenario at a college Internet access point — say the lab:

  • Misuse of Bandwidth
  • Demand more than supply

Well, Internet access, and more specifically bandwidth, has been the major cause of pain for everyone in our college — I’ve just appeared for my final semester college examination. Since I’ve heard this often, what good is a final-year CS project if it’s not useful for anyone anywhere — I took up on the job of doing something about the Internet issues at the campus.

What I needed to do was to develop a program that allotted a time limit to all students for internet access per day — time limit means, less misuse ;-)

The requirement was to plug in a access gateway system between the Internet access terminals and the world wide web. My choice of OS for this system was obviously Linux — nothing beats IPTables if you ask me, which is what I used for writing custom timer/access rules.

The workflow was simple: The first time a user points his/her browser to a website, instead of the website he gets to a Internet access login page. If the user doesn’t already have an account, he needs to sign up.

Having been using PHP for various personal projects, I quickly scripted the login/signup UI using PHP. With the help of PHP, I could easily balance time with the help of IPTables and could store all the required details — viz., time used by user, authentication, and whether the user belongs to the “student” or “faculty” group.

What’s going on behind the scenes that provides the college that kind of control over your internet?

Let’s begin an example an elaborate whole process.

Step 1:  Network Configuration of User Machine

Since all desktops query our college network using DHCP for an IP address, I made the following changes in the systems:

We needed to make some change on /etc/dhcpd.conf

ddns-update-style interim;
ignore client-updates;
subnet 192.168.50.0 netmask 255.255.255.0 {
# --- default gateway
option routers 192.168.50.10;
option subnet-mask 255.255.255.0;
# option nis-domain "domain.org";
# option domain-name "domain.org";
option domain-name-servers 192.168.50.10;

option time-offset -18000; # Eastern Standard Time
# option ntp-servers 192.168.1.1;
# option netbios-name-servers 192.168.1.1;
# --- Selects point-to-point node (default is hybrid). Don't change this unless
# -- you understand Netbios very well
# option netbios-node-type 2;
range dynamic-bootp 192.168.50.20 192.168.50.40;
default-lease-time 21600;
max-lease-time 43200;
# we want the nameserver to appear at a fixed address
# host ns {
# next-server marvin.redhat.com;
# hardware ethernet 12:34:56:78:AB:CD;
# fixed-address 207.175.42.254;
# }
}

Step 2: Get Internet Access Control Interface

Now, that our client machines have an IP address and gateway, a user should be able to send packets through the gateway. Assuming the user types http://www.google.com in the browser, the first time our server finds any new packet it stamps 0x63 on it — with the help of this command:

-A PREROUTING -j MARK --set-mark 0x63

In the next rule, we check if there is any packet that’s stamped 0x63, redirect on 80 port of the server, where our interface application is working.

-A PREROUTING -i eth1 -p tcp -m mark --mark 0x63 -m tcp --dport 80 -j REDIRECT --to-ports 80

Likewise, the server hijacks the http requests and provides a login page to the user. If user is able to successfully login — he is able access Internet.

Now, what happens on the backend? Whenever a user logs in to our system the following iptables rule plays an important role:

iptables -t mangle -I PREROUTING -m mac --mac-source '00:34:21:d2:2e:dw' -j RETURN

This basically copies the MAC address of the user machine and set this rule. Thus, the user is able to access Internet.

At logout time, it deletes the MAC using the following rule:

iptables -t mangle -D PREROUTING -m mac --mac-source '00:34:21:d2:2e:dw' -j RETURN

Step 3: The Final Application

Now that the IPTables rules are in place, I needed to program the per-day time-limit rules for users that ensured once the limit is over, Internet access is denied to the user.

This is where another custom PHP script kicks in. Allow me to produce the whole script here — it’s well commented so that you get the drift:

<?php

# we use a DB to save required info. The following is for connecting the DB
$con = mysql_connect("localhost","dbuser","dbpassword");
if (!$con)
    {
    die('Could not connect: ' . mysql_error());
    }

#  database connection
mysql_select_db("dbname", $con);

#  Figure out who all are the currently-logged in users
#  Let us also store the data in a table

$i=0;
$macresult=mysql_query('select * from tablename',$_DATABASE['link']);
while($row=mysql_fetch_array($macresult)){

# Array to store all the currently-logged in user IDs
        $id[$i]=$row['UID'];

# Array to store all the currently-logged in users' MAC addresses
        $r[$i]=$row['MAC'];
        $i++;
}

#  For convenience let's also store the login time, time limit, remaining time of user

for($k=0;$k<sizeof($id);$k++){
    $result1=mysql_query('select * from tablename where Reg_No="'.$id["$k"].'"',$_DATABASE['link']);
    $check=mysql_fetch_array($result1);

# If a used logs in, we store the value in the following array.
if(is_array($check)){

# the following variable stores the value of the user MAC address
$macaddress=$r["$k"];

# The following variables stores the current date and time
$now = date( 'Y-m-d H:i:s' );
$currenttime=preg_split('/ /',$now);

$result=mysql_query('select * from tablename where MAC="'.$macaddress.'" and Login_Status="1"',$_DATABASE['link']);
$row=mysql_fetch_array($result);

    if(is_array($row)){

# Following calculates the difference between the current time, and the time the user logged in
    $diff = strtotime($now) - strtotime($row['Login_Time']);

    $years   = floor($diff / (365*60*60*24));
    $months  = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
    $days    = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));
    $hours   = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24)/ (60*60));

# Finally, the following variable shows the current time status of user
    $minuts  = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24 - $hours*60*60)/ 60);

# Now, here we get the userid with the help of which we find out remaining time
    $result1=mysql_query('select * from tablename where Reg_No="'.$row["UID"].'"',$_DATABASE['link']);
    $row1=mysql_fetch_array($result1);

        if(is_array($row1)){
                $remtime=$row1['remtime'];
                $aloginid=$row1['Reg_No'];
        } else {
                echo 'no';
        }

# Finally, compare if login minutes are greater than remaining time..
# This is to make the IPTable rule let the user access Internt or block him for the day

        if($minuts>$remtime){
                $ACommandExec = '/usr/bin/sudo /sbin/iptables -t mangle -D PREROUTING -m mac --mac-source '.$macaddress.' -j RETURN';
                system($ACommandExec);

                $result = mysql_query("UPDATE tablename SET Logout_Time='$now' WHERE UID='$aloginid'and login_status='1'", $_DATABASE['link']) ;
        $result = mysql_query("UPDATE tablename SET login_status='false' WHERE UID='$aloginid'and login_status='1'", $_DATABASE['link']);

        $result = mysql_query("DELETE FROM tablename WHERE UID='$aloginid'",$_DATABASE['link']);

        $result = mysql_query('UPDATE tablename SET totaltime="0",remtime="0",usedtime="0" where Reg_No="'.$aloginid.'"', $_DATABASE['link']);

        } else {
        }

    } else {
        echo "No, currently in use error";
    }

    } else {
    echo "No Login error ";
    }
}

?>

That’s all. Easy and useful college project, isn’t it?

One Comment

  1. smslån says:

    My brother recommended I might like this blog. He was entirely right.
    This post truly made my day. You can not imagine simply how much time I had spent for this information!

    Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *