Quantcast
Channel: Syed Jahanzaib – Personal Blog to Share Knowledge !
Viewing all 409 articles
Browse latest View live

C# PPPoE Dialer Application Code

$
0
0

vc.png

Video of code working is available at YT !
> https://youtu.be/SlryR7ykSqw

[Watch in 720p HD or above to view proper text]


~ Sharing Knowledge ~
~ For Any One Who Wants to Learn ~

 

On few requests, I have made an an PPPoE Dialer program in Visual C Sharp. This code/program can create / dial a broadband pppoe connection on Windows base Operating System. I have added many functions according to the local requirements. It was all built for my local lab testing purposes therefore there is a lot of room for improvements in it. Just to remind myself, I am not even a programmer, but a simple low level network support personnel. This is my first Try code in C# programming. It took me around one week to develop this code. Google search and Stack-overflow discussion forums helped a lot.

Very Sadly ! Most of the programmers / knowledgeable persons I know in my  contact clearly denied to share any code / working solution with the public & advised me NOT to share such code freely/publicly, like the Joker once said in a movie scene.

if u r good.png

If you are Good at something, never do it for free

But denying the above Joker statement, here I am. sharing my basic knowledge for anyone who wants to learn from IT ~


Components Used:

  • OS: Windows 7 (64bit)
  • Launching Pad: Visual Studio 2012
  • Language: C Sharp (C#)
  • Support Libraries: Dotras 1.3 (https://dotras.codeplex.com/)
  • .Net Framework 4.x Library for Dotras

// Code Working Workflow Example //

  • Username / Password Boxes: This must be filled first time, & the code will save it in registry, so next time the dialer is launched , it will be read automatically to avoid entering credentials again)
  • Dial Button: which will basically dial the pppoe connection, it will also check if dialer is already connected.
  • Disconnect Button: You know what disconnect means :). It will disconnect the dialer only if the dialer is really connected.
  • Exit: This will close this application.
  • Create internet Dialer Button: This will create pppoe dialer connection in Network Connections plus its shortcut on current user desktop, and if connection already exists, then delete, and re-create.
  • Dialer LAN Status Button: It will check if the dialer is connected or not. Just to refresh the status.
  • Internet Access Button: It will check ping to specific HOST (8.8.8.8) and if ping success/fails, set status accordingly.
  • Balloon Texts / Notifications: When application is minimized to System Tray
  • Auto Minimize: on connect / manual disconnect
  • Tray Icon Menu Strip Menu Context to Show/Exit app. Example to show function.
  • The code will keep checking the dialer status (every 5sec) /net status  (every 10sec) and update eh text label accordingly.

I have NOT added auto – redial , but you can easily add it in raswatcher section ,if you like 🙂 , i may be missing some other functions like data counters, will add more later, or you can add your own functions too.

I will update more later if get the chance…

Ok lets hit the Road , and view the code …


the CODE!

// C# program for pppoe dialer with DotRas Support
// 20th March - 2017
// By Syed.Jahanzaib
// aacable at hotmail dot com
// http://aacable dot wordpress dot com
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DotRas;
using Microsoft.Win32;
using System.Net;
using System.IO;
using System.Net.NetworkInformation;
using System.Net.Sockets;

namespace pppoe_dialer___zaib_last
{
 public partial class Form1 : Form
 {

int lanInterval = 5; //5 sec
 int netInterval = 10; //10 sec

 //private bool willClose;
 private bool connected;
 private RasHandle handle = null;
 private RasHandle Rashandler = null;
 private RasConnection connection = null;
 public Form1()
 {
 InitializeComponent();
 Timer t = new Timer();
 t.Interval = 1000; //1 sec
 t.Tick += new EventHandler(t_Tick);
 t.Start();
 }
 void t_Tick(object sender, EventArgs e)
 {
 lanInterval--;
 netInterval--;

if (lanInterval == 0)
 {
 checkpppstatus();
 lanInterval = 5; //reset to base value
 }

if (netInterval == 0)
 {
 checknetstatus();
 netInterval = 10; //reset to base value
 }
 }
 protected void checkpppstatus()
 {
 this.Invoke((MethodInvoker)delegate
 {
 var conns = RasConnection.GetActiveConnections();
 var conn = conns.FirstOrDefault(o => o.EntryName == "pppoe2");
 if (conn != null)
 {
 connstatus.Text = "Dialer Connection Status: Connected!";
 connstatus.ForeColor = System.Drawing.Color.Green;
 }
 else
 {
 connstatus.Text = "Dialer Connection Status: Disconnected!";
 connstatus.ForeColor = System.Drawing.Color.Red;
 }

});
 }

protected void checknetstatus()
 {
 if (IsOnline(textBox1.Text) == true)
 {
 internetStatus.ForeColor = System.Drawing.Color.Green;
 string Status = "Internet Stauts: UP";
 internetStatus.Text = Status;
 }
 else
 {
 internetStatus.ForeColor = System.Drawing.Color.Red;
 string Status = "Internet Stauts: DOWN";
 internetStatus.Text = Status;
 }
 }

protected void Displaynotify()
 {
 try
 {
 notifyIcon1.BalloonTipTitle = "You have successfully connected to the Internet ...";
 notifyIcon1.BalloonTipText = "Internet Connected ...";
 notifyIcon1.Visible = true;
 notifyIcon1.ShowBalloonTip(5000);
 }
 catch (Exception ex)
 {
 }
 }

 protected void Displaynotifyfordisconnect()
 {
 try
 {
 notifyIcon1.BalloonTipTitle = "My PPPoE Dialer DISCONNECTED !!!";
 notifyIcon1.BalloonTipText = "Internet Disconnected !!!";
 notifyIcon1.Visible = true;
 notifyIcon1.ShowBalloonTip(5000);
 {
 this.Invoke((MethodInvoker)delegate
 {
 this.StatusTextBox.AppendText(string.Format("{0}\r\n\r\n", "\r\nDialer Disconnected!"));
 });
 }
 }
 catch (Exception ex)
 {
 }
 }

 private void saveCredential(string username, string password, bool remember, bool auto)
 {
 RegistryKey hkcu = Registry.CurrentUser;
 RegistryKey software = hkcu.OpenSubKey("Software", true);
 RegistryKey zaib = software.CreateSubKey("zaib");
 zaib.SetValue("username", username, RegistryValueKind.String);
 zaib.SetValue("password", password, RegistryValueKind.String);
 zaib.Close();
 }

 private void readCredential()
 {
 RegistryKey hkcu = Registry.CurrentUser;
 RegistryKey software = hkcu.OpenSubKey("Software", true);
 RegistryKey zaib = software.CreateSubKey("zaib");
 try
 {
 textBox1.Text = (string)zaib.GetValue("username", "");
 textBox2.Text = (string)zaib.GetValue("password", "");
 }
 catch (Exception ex)
 {
 // never saved
 }
 zaib.Close();
 }

 private void Form1_Move_1(object sender, EventArgs e)
 {
 if (this.WindowState == FormWindowState.Minimized)
 {
 this.Hide();
 notifyIcon1.ShowBalloonTip(2000, "My PPPoE Dialer", "The App has be moved to the tray.", ToolTipIcon.Info);
 checkpppstatus();
 }
 }

 private void button1_Click(object sender, EventArgs e)
 {
 string path;
 path = RasPhoneBook.GetPhoneBookPath(RasPhoneBookType.User);
 using (RasPhoneBook pbk = new RasPhoneBook())
 {
 pbk.Open(path);
 RasEntry entry = RasEntry.CreateBroadbandEntry("pppoe2", RasDevice.GetDeviceByName("PPPOE", RasDeviceType.PPPoE, false));
 // Configure any options for your entry here via entry.Options
 entry.RedialCount = 99;
 // Finally Add the PPPOE Dialer in the network connection , hurrahhhh , zaib
 // If Preiovus Entry found, delete, and reacreate
 var conns = RasConnection.GetActiveConnections();
 var conn = conns.FirstOrDefault(o => o.EntryName == "pppoe2");
 if (conn != null)
 {
 MessageBox.Show("Dialer Already Connected! Disconnect it first to re-create.");
 return;
 }
 pbk.Entries.Clear();
 rasDialer1.Credentials = new System.Net.NetworkCredential(textBox1.Text, textBox2.Text);
 rasDialer1.AllowUseStoredCredentials = true;

pbk.Entries.Add(entry);
 // If Dialer Create, show successfull message.
 MessageBox.Show("Internet Dialer created Successfully.");
 saveCredential("test", "test", true, true);
 ///// Create PPPOE Dialer SHORTCUT on desktop begins

string destDir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
 string destFileName = @"Connect To My Internet Dialer.lnk";

// Create .lnk file
 string path2 = System.IO.Path.Combine(destDir, destFileName);
 FileStream fs = File.Create(path2);
 fs.Close();

// Instantiate a ShellLinkObject that references the .lnk we created
 Shell32.Shell shell = new Shell32.Shell();
 Shell32.Folder shellFolder = shell.NameSpace(destDir);
 Shell32.FolderItem shellFolderItem = shellFolder.Items().Item(destFileName);
 Shell32.ShellLinkObject shellLinkObject = (Shell32.ShellLinkObject)shellFolderItem.GetLink;

// Set .lnk properties
 shellLinkObject.Arguments = "-d pppoe2";
 shellLinkObject.Description = "pppoe2";
 shellLinkObject.Path = @"%windir%\System32\rasphone.exe";
 shellLinkObject.WorkingDirectory = "%windir%";

shellLinkObject.Save(path2);
 //// SHORTCUT END

}
 }

private void Form1_Load(object sender, EventArgs e)
 {

}
 private void textBox1_TextChanged(object sender, EventArgs e)
 {
 }
 private void textBox2_TextChanged(object sender, EventArgs e)
 {
 }
 private void textBox1_Click(object sender, EventArgs e)
 {
 // textBox1.Clear();
 }
 private void Button2_Click(object sender, EventArgs e)
 {
 this.Close();
 }
 private void textBox2_Click(object sender, EventArgs e)
 {
 //textBox2.Clear();
 }
 private void label1_Click_1(object sender, EventArgs e)
 {
 System.Diagnostics.Process.Start("https://aacable.wordpress.com");
 }
 private void pictureBox2_Click(object sender, EventArgs e)
 {
 System.Diagnostics.Process.Start("https://aacable.wordpress.com");
 }
 private void button2_Click_1(object sender, EventArgs e)
 {

RasHandle handle = null;
 using (RasDialer dialer = new RasDialer())
 {
 dialer.StateChanged += new EventHandler<StateChangedEventArgs>(rasDialer1_StateChanged);
 dialer.EntryName = ("pppoe2");
 {
 };

//this.StatusTextBox.AppendText(string.Format("{0}\r\n\r\n", "Connection in progress ...", "{0}\r\n\r\n"));
 dialer.StateChanged += new EventHandler<StateChangedEventArgs>(rasDialer1_StateChanged);
 dialer.EntryName = ("pppoe2");
 string username = textBox1.Text;
 string passwd = textBox2.Text;
 dialer.Credentials = new System.Net.NetworkCredential(textBox1.Text, textBox2.Text);
 dialer.PhoneBookPath = RasPhoneBook.GetPhoneBookPath(RasPhoneBookType.User);
 dialer.Timeout = 1000;
 dialer.AllowUseStoredCredentials = true;
 dialer.EntryName = ("pppoe2");
 rasDialer1.EntryName = ("pppoe2");
 rasDialer1.Credentials = new System.Net.NetworkCredential(textBox1.Text, textBox2.Text);
 rasDialer1.PhoneBookPath = RasPhoneBook.GetPhoneBookPath(RasPhoneBookType.User);

// If username or password window is empty , post error
 if (string.IsNullOrWhiteSpace(textBox1.Text))
 {
 this.StatusTextBox.AppendText(string.Format("{0}\r\n\r", "You must enter username/password in order to dial", "{0}\r\n"));
 //MessageBox.Show("Enter username.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
 return;
 }
 //
 var conns = RasConnection.GetActiveConnections();
 var conn = conns.FirstOrDefault(o => o.EntryName == "pppoe2");
 if (conn != null)
 MessageBox.Show("Dialer - Already connected!");
 else
 handle = rasDialer1.DialAsync();

}
 }

private void StatusTextBox_TextChanged(object sender, EventArgs e)
 {
 }

private void rasDialer1_StateChanged(object sender, StateChangedEventArgs e)
 {
 this.Invoke((MethodInvoker)delegate
 {
 this.StatusTextBox.AppendText(string.Format(e.State.ToString() + "\r\n"));
 checkpppstatus();
 });
 }

 private void rasDialer1_DialCompleted(object sender, DialCompletedEventArgs e)
 {
 {
 if (e.Cancelled)
 {
 MessageBox.Show("Cancelled");
 }
 else if (e.TimedOut)
 {
 MessageBox.Show("Time out");
 }
 else if (e.Error != null)
 {
 MessageBox.Show(e.Error.ToString(), "Error");
 }
 else if (e.Connected)
 {
 var conn = RasConnection.GetActiveConnections().Where(c => c.EntryName == "pppoe2").FirstOrDefault();
 RasIPInfo ipAddresses = (RasIPInfo)conn.GetProjectionInfo(RasProjectionType.IP);
 this.StatusTextBox.AppendText(string.Format("{0}\r\n", "Your internet ip is", ipAddresses.IPAddress.ToString()));
 this.StatusTextBox.AppendText(string.Format("{0} ", ipAddresses.IPAddress.ToString()));
 saveCredential("test", "test", true, true);
 ShowInTaskbar = true;
 this.Hide();
 }
 }
 }

 private void dcButton_Click(object sender, EventArgs e)
 {
 try
 {
 var conns = RasConnection.GetActiveConnections();
 var conn = conns.FirstOrDefault(o => o.EntryName == "pppoe2");
 if (conn != null)
 {
 conn.HangUp();

 this.StatusTextBox.AppendText(string.Format("{0}\r\n\r\n", "\r\nDisconnected on user request !"));
 connstatus.ForeColor = Color.Red;
 checkpppstatus();
 this.Hide();
 Displaynotifyfordisconnect();
 }
 }
 catch (Exception ex)
 {

MessageBox.Show(ex.Message);
 }
 }

private void rasDialer1_Error(object sender, System.IO.ErrorEventArgs e)
 {
//
 }

private void Form1_Resize(object sender, EventArgs e)
 {
 notifyIcon1.Text = "My Internet Dialer";
 }

private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
 {
 this.Show();
 this.WindowState = FormWindowState.Normal;
 }

 private void notifyIcon1_MouseDoubleClick_1(object sender, MouseEventArgs e)
 {
 Show();
 WindowState = FormWindowState.Normal;
 }

private void notifyIcon1_MouseMove(object sender, MouseEventArgs e)
 {
 notifyIcon1.Text = "My Internet Dialer";
 }

private void notifyIcon1_BalloonTipClicked(object sender, EventArgs e)
 {

}

 private void Form1_FormClosing(object sender, FormClosingEventArgs e)
 {

 }

private void notifyIcon1_BalloonTipShown(object sender, EventArgs e)
 {
 }

private void Form1_Load_1(object sender, EventArgs e)
 {
 readCredential();
 checkpppstatus();

Timer MyTimer = new Timer();
 MyTimer.Interval = 5000;
 MyTimer.Tick += new EventHandler(MyTimer_Tick);
 MyTimer.Start();

Timer MyTimer10 = new Timer();
 MyTimer10.Interval = 5000;
 MyTimer10.Tick += new EventHandler(MyTimer_Tick);
 MyTimer10.Start();
 }
 private void MyTimer_Tick(object sender, EventArgs e)
 {
 //checkpppstatus();
 }
 private void MyTimer10_Tick(object sender, EventArgs e)
 {
 // checknetstatus();
 }

 private void contextMenuStrip1_DoubleClick(object sender, EventArgs e)
 {
 this.Show();
 }

private void showToolStripMenuItem_Click(object sender, EventArgs e)
 {
 this.Show();
 }

private void exitToolStripMenuItem_Click(object sender, EventArgs e)
 {
 Application.Exit();
 }

private void notifyIcon1_Click(object sender, EventArgs e)
 {
 this.Show();
 WindowState = FormWindowState.Normal;
 }

private void label3_Click(object sender, EventArgs e)
 {
}

private void connstatus_Click(object sender, EventArgs e)
 {
}

private void connstatus_Click_1(object sender, EventArgs e)
 {

}

private void refreshButton_Click(object sender, EventArgs e)
 {
 checkpppstatus();
 }

private void rasDialDialog1_Error(object sender, RasErrorEventArgs e)
 {
 }

private void rasConnectionWatcher1_Disconnected(object sender, RasConnectionEventArgs e)
 {
 checkpppstatus();
 Displaynotifyfordisconnect();
 }

private void rasConnectionWatcher1_Connected(object sender, RasConnectionEventArgs e)
 {
 Displaynotify();
 }

private void rasConnectionWatcher1_Error(object sender, ErrorEventArgs e)
 {
 MessageBox.Show("ERR");
 }

private void rasPhoneBookDialog1_ChangedEntry(object sender, RasPhoneBookDialogEventArgs e)
 {
 MessageBox.Show("ENTRY CHANGED");
 }

 // Tafreeh start

public bool IsOnline(string website)
 {
 Ping x = new Ping();
 PingReply reply = x.Send(IPAddress.Parse("8.8.8.8")); //enter ip of the machine
 if (reply.Status == IPStatus.Success) // here we check for the reply status if it is success it means the host is reachable
 {
 return true;
 // status.Text = "Available. And Round Trip Time of the packet is:" + reply.RoundtripTime.ToString();
 }
 else //if host is not reachable.
 return false;
 // status.Text = "Not available";
 }
 //}

private void test1_Click(object sender, EventArgs e)
 {
 if (IsOnline(textBox1.Text) == true)
 {
 internetStatus.ForeColor = System.Drawing.Color.Green;
 string Status = "Internet Stauts: UP";
 internetStatus.Text = Status;
 }
 else
 {
 internetStatus.ForeColor = System.Drawing.Color.Red;
 string Status = "Internet Stauts: DOWN";
 internetStatus.Text = Status;
 }

}

private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
 {
 System.Diagnostics.Process.Start("https://aacable.wordpress.com");
 }
 }
}


 

I will upload the complete package with code/debug/exe package later …

I am pretty sure that above code will help you in many parts when you will create your own project. I faced many challenges duet first time programming but your situation may be different if you have already working example in ahead of you 🙂

I will be more then happy if someone posts some more advance level of this dialer code for all.


Regard’s

Syed Jahanzaib
https://aacable.wordpress.com
Email: aacable@hotmail.com
Allah Hafiz !


Filed under: Programming

C# Active Directory Management using custom built App!

$
0
0

c

This is just another reference example post, on how you can use C# code to connect with active directory in order to perform some basic tasks , using one window operation approach. It’s simple, fast, and works well enough to cater the OP requirements. You can add your own functions in it as required. You can use use/modify/redistribute this code freely. no obligations.

stackoverflow


Task:

A simple program which can display all Active Directory users in a Drop down List menu, and based on the selection, it can perform various actions like

  • Check Status of User
  • Disable Account
  • Enable Account
  • While preventing any access to Admin account(s)

Something like below …

logo

Requirements:

  • Target framework is 4.x. [Latest is good because of its extensive support for various  enormous operations.]
  • Reference of Active Directory Modules

To add refrence to proect, Goto PROJECTS > ADD REFERENCE  > FRAMEWORK

Add following …

  • System.DirectoryServices
  • System.DirectoryServices.ActiveDirectory
  • System.DirectoryServices.AccountManagement

reference.PNG

The program must be run via Administrator account or account with admin privileges

CODE:

Here is the full code. Based on this code, we can add many other functions, this is just for example purposes.

Form1.cs


// C# code to manage Active Directory functions
// like enable/disable user account via drop down menu list
// Syed Jahanzaib / aacable at hotmail dot com
// March, 2017
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.DirectoryServices.AccountManagement;
using System.Configuration;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
new ToolTip().SetToolTip(comboBox1, "Click here to see user list");
}
private void button1_Click(object sender, EventArgs e)
{
String _ADUserName = comboBox1.Text; // <-- The textbox you enter your username?
if (string.IsNullOrEmpty(comboBox1.Text) || comboBox1.Text == "0")
{
this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - Please Enter Username!\n\r");
return;
}
PrincipalContext context = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, comboBox1.Text.Trim());
if (comboBox1.Text == "ADMIN1" | comboBox1.Text == "ADMIN2")
{
this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - Dont get over smart. You are 'NOT' authorized to change admin accounts state!\n\r");
return;
}
if (user == null)
{
this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - not found in AD!\n\r");
return;
}
if (user.Enabled == false)
{
this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - User is already DISABLED.\n\r");
return;
}
if (user.Enabled == true)
DiableADUserUsingUserPrincipal(_ADUserName);
this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - is now DISABLED.\n\r");
}
private static bool DiableADUserUsingUserPrincipal(string username)
{
try
{
PrincipalContext principalContext = new PrincipalContext(ContextType.Domain);
UserPrincipal userPrincipal = UserPrincipal.FindByIdentity
(principalContext, username);
userPrincipal.Enabled = false;
userPrincipal.Save();
return true;
}
catch (Exception ex)
{
//Console.WriteLine(ex.Message);
}
return false;
}
private static bool EnableADUserUsingUserPrincipal(string username)
{
try
{
PrincipalContext principalContext = new PrincipalContext(ContextType.Domain);
UserPrincipal userPrincipal = UserPrincipal.FindByIdentity
(principalContext, username);
userPrincipal.Enabled = true;
userPrincipal.Save();
return true;
}
catch (Exception ex)
{
//Console.WriteLine(ex.Message);
}
return false;
}
private void button2_Click(object sender, EventArgs e)
{
{
String _ADUserName = comboBox1.Text; // <-- The textbox you enter your username?
if (string.IsNullOrEmpty(comboBox1.Text) || comboBox1.Text == "0")
{
this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - Please Enter Username!\n\r");
return;
}
PrincipalContext context = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, comboBox1.Text.Trim());

if (comboBox1.Text == "ADMIN1" | comboBox1.Text == "ADMIN2")
{
this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - Dont get over smart. You are 'NOT' authorized to change admin accounts state!\n\r");
return;
}
if (user == null)
{
this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - not found in AD!\n\r");
return;
}
if (user.Enabled == true)
{
this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - User is already ENABLED.\n\r");
return;
}
if (user.Enabled == false)
EnableADUserUsingUserPrincipal(_ADUserName);
this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - is now ENABLED.\n\r");
}
}
private void UserStatusButton_Click(object sender, EventArgs e)

{
String _ADUserName = comboBox1.Text; // <-- The textbox you enter your username?
if (string.IsNullOrEmpty(comboBox1.Text) || comboBox1.Text == "0")
{
this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - Please Enter Username!\n\r");
return;
}
PrincipalContext context = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, comboBox1.Text.Trim());

if (comboBox1.Text == "ADMIN1" | comboBox1.Text == "ADMIN2")
{
this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - Dont get over smart. You are 'NOT' authorized to change admin accounts state!\n\r");
return;
}
if (user.Enabled == true) this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - Status is ENABLED.\n\r");
else this.StatusTextBox.AppendText("\r\n" + _ADUserName + " - Status is DISABLED.\n\r"); ;
}
private void Form1_Load(object sender, EventArgs e)
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal qbeUser = new UserPrincipal(ctx);
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
foreach (var found in srch.FindAll())
{
UserPrincipal foundUser = found as UserPrincipal;
if (foundUser != null)
{
comboBox1.Items.Add(foundUser.SamAccountName);
}
}
}
private void linkLabel1_Click(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("https://aacable.wordpress.com");
}

private void comboBox1_MouseHover(object sender, EventArgs e)
{
//ToolTip tt = new ToolTip();
//tt.Show("Click here to see user list", this.comboBox1, 2000);
}
}
}
// Code Ends Here. Take Care

Form1.Designer.cs


namespace WindowsFormsApplication2
{
partial class Form1
{
///
<summary>
/// Required designer variable.
/// </summary>

private System.ComponentModel.IContainer components = null;

///
<summary>
/// Clean up any resources being used.
/// </summary>

/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

///
<summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>

private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.StatusTextBox = new System.Windows.Forms.TextBox();
this.UserStatusButton = new System.Windows.Forms.Button();
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.linkLabel1 = new System.Windows.Forms.LinkLabel();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(157, 70);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(88, 23);
this.button1.TabIndex = 0;
this.button1.Text = "Disable User";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(157, 41);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(88, 23);
this.button2.TabIndex = 2;
this.button2.Text = "Enable User";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// StatusTextBox
//
this.StatusTextBox.BackColor = System.Drawing.Color.Black;
this.StatusTextBox.Cursor = System.Windows.Forms.Cursors.Arrow;
this.StatusTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.StatusTextBox.ForeColor = System.Drawing.SystemColors.Window;
this.StatusTextBox.Location = new System.Drawing.Point(263, 12);
this.StatusTextBox.Margin = new System.Windows.Forms.Padding(1);
this.StatusTextBox.Multiline = true;
this.StatusTextBox.Name = "StatusTextBox";
this.StatusTextBox.ReadOnly = true;
this.StatusTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.StatusTextBox.Size = new System.Drawing.Size(276, 216);
this.StatusTextBox.TabIndex = 3;
this.StatusTextBox.Text = "Status Box ...";
//
// UserStatusButton
//
this.UserStatusButton.Location = new System.Drawing.Point(157, 12);
this.UserStatusButton.Name = "UserStatusButton";
this.UserStatusButton.Size = new System.Drawing.Size(88, 23);
this.UserStatusButton.TabIndex = 4;
this.UserStatusButton.Text = "Check Status";
this.UserStatusButton.UseVisualStyleBackColor = true;
this.UserStatusButton.Click += new System.EventHandler(this.UserStatusButton_Click);
//
// comboBox1
//
this.comboBox1.AllowDrop = true;
this.comboBox1.BackColor = System.Drawing.SystemColors.Info;
this.comboBox1.DropDownHeight = 215;
this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox1.ForeColor = System.Drawing.Color.Black;
this.comboBox1.FormattingEnabled = true;
this.comboBox1.IntegralHeight = false;
this.comboBox1.ItemHeight = 13;
this.comboBox1.Location = new System.Drawing.Point(6, 12);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(136, 21);
this.comboBox1.Sorted = true;
this.comboBox1.TabIndex = 5;
this.comboBox1.MouseHover += new System.EventHandler(this.comboBox1_MouseHover);
//
// linkLabel1
//
this.linkLabel1.AutoSize = true;
this.linkLabel1.Location = new System.Drawing.Point(260, 232);
this.linkLabel1.Name = "linkLabel1";
this.linkLabel1.Size = new System.Drawing.Size(279, 13);
this.linkLabel1.TabIndex = 7;
this.linkLabel1.TabStop = true;
this.linkLabel1.Text = "Management of Active Directory in C# by Syed.Jahanzaib";
this.linkLabel1.Click += new System.EventHandler(this.linkLabel1_Click);
//
// pictureBox1
//
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(6, 156);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(239, 72);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox1.TabIndex = 6;
this.pictureBox1.TabStop = false;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(544, 248);
this.Controls.Add(this.linkLabel1);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.comboBox1);
this.Controls.Add(this.UserStatusButton);
this.Controls.Add(this.StatusTextBox);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "Form1";
this.Text = "Active Directory Management Panel !";
this.Load += new System.EventHandler(this.Form1_Load);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();

}

#endregion

private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.TextBox StatusTextBox;
private System.Windows.Forms.Button UserStatusButton;
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.LinkLabel linkLabel1;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.ToolTip toolTip1;
}
}


0fb310fdff985ec27edf24c236b1e2f3

Regard’s
Syed Jahanzaib


Contact !

[contact-form]

 


Filed under: Programming

Short Notes for C#

$
0
0

Following are few snippets / tips for C# used in various applications I made for personnel usage.

 


Declare Global Variables


namespace WindowsFormsApplication3
{

public partial class Form1 : Form
{

public class Globals
{

// defining File name in a folder

public static string LISTFILEPATH = @"C:\temp\list.txt";

// defining General variable to hold any result

public static string NETSTATUS = "";
}


Check if app is already running, if yes, then inform accordingly and EXIT the app !


private void Form1_Load(object sender, EventArgs e)
{
Process aProcess = Process.GetCurrentProcess();
string aProcName = aProcess.ProcessName;
if (Process.GetProcessesByName(aProcName).Length > 1)
{

MessageBox.Show("This APP is already running. Close previously running instance first!", "This APP  App Already Running !",
MessageBoxButtons.OK, MessageBoxIcon.Error);
System.Windows.Forms.Application.Exit();
Application.ExitThread();
Application.Exit();
}


Check for Folder / file, if not exists then create


// Check if directory exists
if (Directory.Exists(@"C:\temp\)"))
{
// IF IT EXISTS, DO NOTHING
}
else
// IF ITS NOT , CREATE IT
{
Directory.CreateDirectory(@"C:\temp\");
}
// IF IT EXISTS, DO NOTHING
if (File.Exists(Globals.LISTFILEPATH))
{
// Do nothing
}
else
// IF ITS NOT , CREATE IT
{
//File.Create(Globals.LISTFILEPATH);
using (StreamWriter sw = new StreamWriter(Globals.LISTFILEPATH, true))
{
//
}
}

Add some colors to your output text


// Some coloring fun
private void ColorRed()
{
StatusTextBox.SelectionColor = Color.Red;
}


Adding Bold Text


StatusTextBox.SelectionFont = new Font(StatusTextBox.Font, StatusTextBox.Font.Style | FontStyle.Bold);
this.StatusTextBox.AppendText("\r\n- Processing ...\r\n");
StatusTextBox.SelectionFont = new Font(StatusTextBox.Font, StatusTextBox.Font.Style | FontStyle.Regular);


Multiple IF Statement matching


if ((Globals.Variable1 == "0") && (Globals.Variable2 == "0"))

// then do this or that


Message Box with Warning sign & OK button

MessageBox.Show("Error on ping:", MessageBoxButtons.OK, MessageBoxIcon.Warning);

Running thread separately without hanging UI

await Task.Run(() =>
{

// your task

});
}

Testing Remote TCP Port Status

{
using(TcpClient tcpClient = new TcpClient())

try {
tcpClient.Connect("1.1.1.1", 80);
// Succeed OK ! show the result, you can update text box, variable etc anything of your choice

} catch (Exception) {
// FAILED ! show the result, you can update text box, variable etc anything of your choice
}
}

Getting Default Gateway(s) bypassing few types of interfaces


foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{
if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet);
{
if ((ni.Description.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Loopback", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Loopback", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Isatap", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Isatap", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Tunnel", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Tunnel", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Microsoft 6to4 Adapter", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Microsoft 6to4 Adapter", StringComparison.OrdinalIgnoreCase) >= 0))
continue;

this.StatusTextBox.AppendText("\r\n" + ni.Name + "\r\n");
foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
{
if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
// Console.WriteLine(ip.Address.ToString());
this.StatusTextBox.AppendText("\r\n" + ip.Address.ToString() + "\r\n");
}
}
}
}


 ~iBBi – Pinger  ¯\_(ツ)_/¯   – Customized Ping App  for My 3 Kids ~

iBBi PINGER application code I made to continuously ping any remote host by ip or dns name, and output any error with some style colors and images. I made it for my kids who uses computers and occasionally my PTCL Evo gets hangs or internet stopped working and the kids have no idea whats going on this application runs in background and popup yellow or green icon and iconic message so kids can understand internet is not working. the task was very simple and it worked ok, but later I was bitten by an dangerous animal as known as ‘curiosity‘ which forcefully made to add do some late night testings to add/enhance some additional features which were totally useless or not required 😛 lol.

Following is unfinished product and contains some bugs as well. Still posting it as reference for myself , just in case I managed to burn my PC.


// iBBi Pinger program, small app that can ping remote host
// and shows any error in fancy style , colors, icons, trayicon notifications, etc etc
// April, 2017

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using System.Net;
using System.Net.NetworkInformation;
using System.IO;
using System.Runtime.InteropServices;
using System.Net.Sockets;
using System.Reflection;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text.RegularExpressions;

namespace WindowsFormsApplication3
{

public partial class Form1 : Form
{

public class Globals
{

public static string LISTFILEPATH = @"C:\temp\list.txt";
public static string DnsError = "0";
public static string currentNetStatus = "0";
public static string TCP_STATUS = "0";
public static string TCP_PORT = "80";
public static string GHOST = "";
public static string GOPING = "";
public static string PIP = "";
public static string LAN = "";
public static string NETSTATUS = "";
public static string DGW = "";
}

public Form1()
{
InitializeComponent();
Globals.NETSTATUS = "0";
StatusTextBox.SelectionColor = Color.Black;
pictureBox1.Image = null;
timer1.Stop();
timer2.Stop();
timer1.Enabled = false;
}
private void Form1_Load(object sender, EventArgs e)
{
Process aProcess = Process.GetCurrentProcess();
string aProcName = aProcess.ProcessName;
if (Process.GetProcessesByName(aProcName).Length > 1)
{

MessageBox.Show("Pinger is already running. Close previously running instance first!", "Pinger App Already Running !",
MessageBoxButtons.OK, MessageBoxIcon.Error);
System.Windows.Forms.Application.Exit();
Application.ExitThread();
Application.Exit();
}

// Check if directory exists
if (Directory.Exists(@"C:\temp\)"))
{
// Do nothing
}
else
{
Directory.CreateDirectory(@"C:\temp\");
}
if (File.Exists(Globals.LISTFILEPATH))
{
// Do nothing
}
else
{
//File.Create(Globals.LISTFILEPATH);
using (StreamWriter sw = new StreamWriter(Globals.LISTFILEPATH, true))
{
//
}
}
string[] lineOfContents = File.ReadAllLines(Globals.LISTFILEPATH);
foreach (var line in lineOfContents)
{
string[] tokens = line.Split(',');
if (!comboBox1.Items.Contains(tokens[0]))
comboBox1.Items.Add(tokens[0]);
}
}
// Some coloring fun
private void ColorRed()
{
this.Invoke((MethodInvoker)delegate
{
StatusTextBox.SelectionColor = Color.Red;
});
}
private void ColorBlack()
{
this.Invoke((MethodInvoker)delegate
{
StatusTextBox.SelectionColor = Color.Black;
});
}
private void ColorBlue()
{
StatusTextBox.SelectionColor = Color.Blue;
}
private void ColorGreen()
{
StatusTextBox.SelectionColor = Color.Green;
}
private void ColorOrange()
{
StatusTextBox.SelectionColor = Color.Orange;
}
private async void PingButton_Click(object sender, EventArgs e)
{
Globals.GOPING = "1";
pictureBox1.Image = null;
ProgressPictureBox1.Image = null;
Globals.GHOST = comboBox1.Text;
StatusTextBox.SelectionFont = new Font(StatusTextBox.Font, StatusTextBox.Font.Style | FontStyle.Bold);
this.StatusTextBox.AppendText("\r\n- Processing ...\r\n");
StatusTextBox.SelectionFont = new Font(StatusTextBox.Font, StatusTextBox.Font.Style | FontStyle.Regular);
if (!comboBox1.Text.Contains('.'))
{
ColorRed();
this.StatusTextBox.AppendText("\r\n" + "Somethign missing ! Please select or enter valid Hostname or IP address !\r\n");
ColorBlack();
return;
}

{
if (string.IsNullOrEmpty(comboBox1.Text) || (comboBox1.Text == "Seleact or type Destination"))
{
ColorRed();
this.StatusTextBox.AppendText("\r\n" + "Please select or enter valid Hostname or IP address !\r\n");
ColorBlack();
pictureBox1.Image = null;
return;
}
else
{
PingButton.Enabled = false;
PingButton.Text = "Pinging...";
// IsNetworkAvailable();
//if (Globals.LAN == "")
//{
//this.StatusTextBox.AppendText("\r\n-PINGBUTTON CHECK- LAN DISCONNECTED!\r\n");
// TIMER_STOP_FUNC();
//return;
// }

//else
//{
//this.StatusTextBox.AppendText("\r\n-LAN OK!\r\n");
//}

TIMER_START_FUNC();
}
}
}




private void OnApplicationExit(object sender, EventArgs e)
{
try
{
if (notifyIcon1 != null)
{
notifyIcon1.Visible = false;
notifyIcon1.Icon = null;
notifyIcon1.Dispose();
notifyIcon1 = null;
}
}
catch { }
}
private void notifyIcon1_DoubleClick(object sender, EventArgs e)
{
this.Show();
this.WindowState = FormWindowState.Normal;
}
private void restoreToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Show();
this.WindowState = FormWindowState.Normal;
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
TIMER_STOP_FUNC();
notifyIcon1.Visible = false;
notifyIcon1.Icon = null;
notifyIcon1.Dispose();
notifyIcon1 = null;
Application.Exit();
}
private void menuStrip1_Click(object sender, EventArgs e)
{
}
private void menuStrip1_MouseClick(object sender, MouseEventArgs e)
{
this.Show();
WindowState = FormWindowState.Normal;
}
private void Form1_Move(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
{
if ((Globals.currentNetStatus == "0") && (Globals.TCP_STATUS == "0"))
{
this.notifyIcon1.Icon = Properties.Resources.icon_standby;
}
else
{
this.notifyIcon1.Icon = Properties.Resources.icon_online;
}
this.Hide();
}
}
private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
{
TIMER_STOP_FUNC();
notifyIcon1.Visible = false;
notifyIcon1.Icon = null;
notifyIcon1.Dispose();
notifyIcon1 = null;
Application.Exit();
}
private void StopPing_Click(object sender, EventArgs e)
{
this.notifyIcon1.Icon = Properties.Resources.icon_standby;
ProgressPictureBox1.Image = null;
pictureBox1.Image = null;
if (timer1.Enabled == false)
//if (!timer1.Enabled)
{
StatusTextBox.SelectionColor = Color.Red;
this.StatusTextBox.AppendText("\r\n" + "Ping is not running !\r\n");
StatusTextBox.SelectionColor = Color.Black;
}
if (timer1.Enabled == true)
{
TIMER_STOP_FUNC();
ColorBlue();
StatusTextBox.SelectionFont = new Font(StatusTextBox.Font, StatusTextBox.Font.Style | FontStyle.Bold);
this.StatusTextBox.AppendText("\r\n" + "Stopped on User Request !\r\n");
StatusTextBox.SelectionFont = new Font(StatusTextBox.Font, StatusTextBox.Font.Style | FontStyle.Regular);
ColorBlack();
this.notifyIcon1.Icon = Properties.Resources.icon_standby;
ProgressPictureBox1.Image = null;
PingButton.Enabled = true;
PingButton.Text = "Start Ping";
pictureBox1.Image = null;
}
}
//}
private void SaveComboList_Click(object sender, EventArgs e)
{
using (StreamWriter writer = new StreamWriter(Globals.LISTFILEPATH, true))
{
try
{
if (comboBox1.Items.Contains(comboBox1.Text))
{
MessageBox.Show("The task '" + comboBox1.Text + "' already exist in list", "Task already exists");
}
else
{
comboBox1.Items.Add(comboBox1.Text);
writer.WriteLine(comboBox1.Text);
writer.Flush();
writer.Dispose();
}
}
catch
{
MessageBox.Show("The file '" + comboBox1.Text + "' could not be located", "File could not be located");
}
}
}
private void exitToolStripMenuItem1_Click_1(object sender, EventArgs e)
{
TIMER_STOP_FUNC();
notifyIcon1.Visible = false;
notifyIcon1.Icon = null;
notifyIcon1.Dispose();
notifyIcon1 = null;
Application.Exit();
}
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.Show();
this.WindowState = FormWindowState.Normal;
}
private void exitToolStripMenuItem2_Click(object sender, EventArgs e)
{
TIMER_STOP_FUNC();
notifyIcon1.Visible = false;
notifyIcon1.Icon = null;
notifyIcon1.Dispose();
notifyIcon1 = null;
Application.Exit();
}
private void exitToolStripMenuItem3_Click(object sender, EventArgs e)
{
TIMER_STOP_FUNC();
notifyIcon1.Visible = false;
notifyIcon1.Icon = null;
notifyIcon1.Dispose();
notifyIcon1 = null;
Application.Exit();
}
private void restoreToolStripMenuItem_Click_1(object sender, EventArgs e)
{
this.Show();
WindowState = FormWindowState.Normal;
}

private void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(string.Format("Ping failed: {0}", e.Error.ToString()),
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
((AutoResetEvent)e.UserState).Set();
}
DisplayReply(e.Reply);
((AutoResetEvent)e.UserState).Set();
}
public void DisplayReply(PingReply reply)
{
if (timer1.Enabled)
{
string host = Globals.GHOST;
Ping ping = new Ping();
var pingSender = new Ping();
try
{
if (reply.Status == IPStatus.Success)
{
this.Invoke((MethodInvoker)delegate
{
ColorGreen();
this.StatusTextBox.AppendText(string.Format("{0}\r\n", reply.Status + " -- delay ms > " + reply.RoundtripTime.ToString() + " for > " + comboBox1.Text + " - " + Globals.PIP));
ColorBlack();
Globals.currentNetStatus = "1";
pictureBox1.Image = Properties.Resources.online_image;
this.notifyIcon1.Icon = Properties.Resources.icon_online;
});
}
else
{
Globals.currentNetStatus = "0";
Globals.TCP_STATUS = "0";
TestTCPConn();
this.textBox1.Text = Globals.currentNetStatus;
this.textBox2.Text = Globals.TCP_STATUS;
if ((Globals.currentNetStatus == "0") && (Globals.TCP_STATUS == "1"))
{
this.Invoke((MethodInvoker)delegate
{
this.StatusTextBox.AppendText(string.Format("\r\n Ping Timeout but PORT " + Globals.TCP_PORT + " responding > " + comboBox1.Text + " - " + Globals.PIP));
pictureBox1.Image = Properties.Resources.online_image;
});
//this.notifyIcon1.Icon = Properties.Resources.icon_online;
}
if ((Globals.currentNetStatus == "0") && (Globals.TCP_STATUS == "0"))
//}
if ((Globals.currentNetStatus == "0") && (Globals.TCP_STATUS == "0"))
if (timer1.Enabled)
{
this.Invoke((MethodInvoker)delegate
{
pictureBox1.Image = Properties.Resources.offline_image;
this.notifyIcon1.Icon = Properties.Resources.icon_standby;
this.StatusTextBox.AppendText(string.Format("PING + PORT test Failed > " + comboBox1.Text + " - " + Globals.PIP + "\r\n"));
});
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error on ping:" + ex.Message, "Error on ping!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}

private void timer1_Tick(object sender, EventArgs e)
{
IsNetworkAvailable();
if (Globals.LAN == "")
{
this.StatusTextBox.AppendText("\r\n-Timer1_TICK Section: No Active Local Network Found. Exiting ...\r\n");
this.ProgressPictureBox1.Image = Properties.Resources.ProgressPictureBox1;
gdnslabel.Text = "Warning: LAN is disconnected ...";
Globals.currentNetStatus = "0";
Globals.TCP_STATUS = "0";
pictureBox1.Image = Properties.Resources.lan_disconnected;
//this.notifyIcon1.Icon = Properties.Resources.icon_standby;
return;
}
else
{
TestPInger();
}
}
protected void TIMER_STOP_FUNC()
{
comboBox1.Enabled = true;
Globals.PIP = "";
timer1.Stop();
timer2.Stop();
gdnslabel.Text = null;
timer1.Enabled = false;
ProgressPictureBox1.Image = null;
pictureBox1.Image = null;
PingButton.Enabled = true;
PingButton.Text = "Start Ping";
}
protected void TIMER_START_FUNC()
{
this.Invoke((MethodInvoker)delegate
{
comboBox1.Enabled = false;
PingButton.Enabled = false;
PingButton.Text = "Pinging ...";
ProgressPictureBox1.Image = Properties.Resources.ProgressPictureBox1;
timer1.Start();
//timer2.Start();
});
}
private static IPAddress GetIpFromHost(ref string host)
{
string errMessage = string.Empty;
IPAddress address = null;
try
{
address = Dns.GetHostByName(host).AddressList[0];
}
catch (SocketException ex)
{
}
return address;
}

private void RemoveList_Click(object sender, EventArgs e)
{
comboBox1.Items.Clear();
File.Create(Globals.LISTFILEPATH).Close();
}
private void ExitImage_Click(object sender, EventArgs e)
{
TIMER_STOP_FUNC();
notifyIcon1.Visible = false;
notifyIcon1.Icon = null;
notifyIcon1.Dispose();
notifyIcon1 = null;
Application.Exit();
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
TIMER_STOP_FUNC();
Application.Exit();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
timer1.Start();
}
private async void TestPInger()
{
//MessageBox.Show(Globals.LAN);
IsNetworkAvailable();
if (Globals.LAN == "")
{
this.StatusTextBox.AppendText("\r\n-Testpinger Section: No Active Local Network Found. Exiting ...\r\n");
this.ProgressPictureBox1.Image = Properties.Resources.ProgressPictureBox1;
gdnslabel.Text = "Warning: Disconnected ...";
Globals.currentNetStatus = "0";
Globals.TCP_STATUS = "0";
pictureBox1.Image = Properties.Resources.lan_disconnected;
//this.notifyIcon1.Icon = Properties.Resources.icon_standby;
return;
}
else
{
//gdnslabel.Text = "INFO: LAN is Connected.";
pictureBox1.Image = null;
}

CheckDGW();
if (Globals.DGW == "")
{
//this.StatusTextBox.AppendText("\r\n- testpinger - OOOOOOOOO No IPV4 Gateway found\r\n");
//TIMER_STOP_FUNC();
return;
}
else
{
//this.StatusTextBox.AppendText("\r\n- LAN Ok. proceeding further ...\r\n");
this.pictureBox1.Image = null;
}
{
await Task.Run(() =>
{
try
{
string host = Globals.GHOST;
int timeout = 1000;
var pingSender = new Ping();
AutoResetEvent waiter = new AutoResetEvent(false);
if (Globals.PIP == "")
{
IPAddress hostAddress = Dns.GetHostByName(host).AddressList[0];
Globals.PIP = hostAddress.ToString();
}
else
{
pingSender.PingCompleted += PingCompletedCallback;
pingSender.SendAsync(Globals.PIP, timeout, waiter);
}
}
catch (SocketException ex)
{
this.notifyIcon1.Icon = Properties.Resources.icon_standby;
this.Invoke((MethodInvoker)delegate
{
ColorRed();
this.StatusTextBox.AppendText("\r\n-DNS ERROR: unable to resolve > " + Globals.GHOST + " - Retrying in few seconds! \r\n");
ProgressPictureBox1.Image = Properties.Resources.ProgressPictureBox1;
pictureBox1.Image = Properties.Resources.dnsproblem_image;
Globals.currentNetStatus = "0";
Globals.TCP_STATUS = "0";
ColorBlack();
});
}
});
}
}
private void TestTCPConn()
{
using(TcpClient tcpClient = new TcpClient())

try {
tcpClient.Connect(Globals.GHOST, 80);
Globals.TCP_STATUS = "1";
} catch (Exception) {
Globals.TCP_STATUS = "0";
}
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
}
private void comboBox1_KeyDown(object sender, KeyEventArgs e)
{
Keys key = e.KeyCode;
if (key == Keys.Space)
{
e.Handled = true;
}
base.OnKeyDown(e);
}
private void comboBox1_Leave(object sender, EventArgs e)
{
string str = comboBox1.Text;
comboBox1.Text = str.Replace(" ", String.Empty);
//MessageBox.Show("Don't accept Space char in your name");
this.Focus();
}
private void StatusTextBox_TextChanged_1(object sender, EventArgs e)
{
StatusTextBox.SelectionStart = StatusTextBox.Text.Length;
StatusTextBox.ScrollToCaret();
}
public static class ThreadHelperClass
{
delegate void SetTextCallback(Form f, Control ctrl, string text);
public static void SetText(Form form, Control ctrl, string text)
{
if (ctrl.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
form.Invoke(d, new object[] { form, ctrl, text });
}
else
{
ctrl.Text += text;
}
}
}
private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
}
private void timer2_Tick(object sender, EventArgs e)
{
IsOnline();
if (timer1.Enabled)
// if ((Globals.currentNetStatus == "0") && (Globals.TCP_STATUS == "1"))
if (Globals.currentNetStatus == "1")
{
this.notifyIcon1.Icon = Properties.Resources.icon_online;
}
if (timer1.Enabled)
if (Globals.TCP_STATUS == "1")
{
this.notifyIcon1.Icon = Properties.Resources.icon_online;
}
if (timer1.Enabled)
if ((Globals.currentNetStatus == "0") && (Globals.TCP_STATUS == "0"))
{
this.notifyIcon1.Icon = Properties.Resources.icon_standby;
}
}
public static IPAddress GetDefaultGateway()
{
//IsNetworkAvailable();
IPAddress result = null;
var cards = NetworkInterface.GetAllNetworkInterfaces().ToList();
if (cards.Any())
{
foreach (var card in cards)
{
var props = card.GetIPProperties();
if (props == null)
continue;

var gateways = props.GatewayAddresses;
if (!gateways.Any())
continue;
var gateway =
gateways.FirstOrDefault(g => g.Address.AddressFamily.ToString() == "InterNetwork");
if (gateway == null)
continue;
result = gateway.Address;
MessageBox.Show(result.ToString());
//MessageBox.Show(result.ToString());
if (result == null)
//MessageBox.Show("NO GW");
MessageBox.Show(result.ToString());
break;
};
}
// var dgw = result.ToString();
// if (dgw == null)
MessageBox.Show(result.ToString());
return result;
}

public static bool IsNetworkAvailable()
{
return IsNetworkAvailable(0);
}

protected async void IsOnline()
{
IsNetworkAvailable();
if (Globals.LAN == "")
{
ColorRed();
this.StatusTextBox.AppendText("\r\\nIsNetworkAvailable section: WARNING: No Active Local Network Found.");
ColorBlack();
Globals.currentNetStatus = "0";
Globals.TCP_STATUS = "0";
//return;
}
else
{
CheckDGW();
if (Globals.LAN == "")
{
ColorRed();
this.StatusTextBox.AppendText("\r\nisnetworkavailable section: WARNING: No Active Local Network Found...");
ColorBlack();
Globals.currentNetStatus = "0";
Globals.TCP_STATUS = "0";
TIMER_STOP_FUNC();
}
else

if (Globals.DGW == "")
{
this.StatusTextBox.AppendText("\r\n-Error: Cannot continue without valid IPV4 Gateway! Please verify your network settings & make sure it is connected with working network.\r\n");
//TIMER_START_FUNC();
//zaib
return;
}

await Task.Run(() =>
{
{
{
if (Globals.LAN == "" | Globals.DGW == "")
return;
}
try
{
Ping x = new Ping();
PingReply reply = x.Send("8.8.8.8");
if (reply.Status == IPStatus.Success)
{
//return true;
Globals.NETSTATUS = "1";
this.Invoke((MethodInvoker)delegate
{
gdnslabel.Text = "INFO: Google DNS is reachable by ICMP protocol.";
});
}
else
{
//if host is not reachable.
// return false;
Globals.NETSTATUS = "0";
this.Invoke((MethodInvoker)delegate
{
gdnslabel.Text = "Warning: Google DNS is NOT reachable by ICMP protocol!";
});
}
}
catch (SocketException ex)
{
{
//this.notifyIcon1.Icon = Properties.Resources.icon_standby;
}
}
}
});
}
}

public static bool IsNetworkAvailable(long minimumSpeed)
{
//Form1 frm1 = new Form1();
if (!NetworkInterface.GetIsNetworkAvailable())
return false;
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{
if ((ni.OperationalStatus != OperationalStatus.Up) ||
(ni.NetworkInterfaceType == NetworkInterfaceType.Loopback) ||
// (ni.NetworkInterfaceType == NetworkInterfaceType.vir) ||
(ni.NetworkInterfaceType == NetworkInterfaceType.Tunnel))

continue;
if (ni.Speed < minimumSpeed)
continue;

if (ni.Description.Equals("Microsoft Loopback Adapter", StringComparison.OrdinalIgnoreCase))
continue;

if ((ni.Description.IndexOf("Network Bridge", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Network Bridge", StringComparison.OrdinalIgnoreCase) >= 0))
continue;

if ((ni.Description.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0))
continue;

if ((ni.Description.IndexOf("Loopback", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Loopback", StringComparison.OrdinalIgnoreCase) >= 0))
continue;

if ((ni.Description.IndexOf("Isatap", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Isatap", StringComparison.OrdinalIgnoreCase) >= 0))
continue;

if ((ni.Description.IndexOf("Tunnel", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Tunnel", StringComparison.OrdinalIgnoreCase) >= 0))
continue;

if ((ni.Description.IndexOf("Microsoft 6to4 Adapter", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Microsoft 6to4 Adapter", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
//MessageBox.Show("LAN FOUND");
Globals.LAN = "1";
//Form1 frm1 = new Form1();
//this.StatusTextBox.AppendText("\r\n- Section: LAN is ok ...\r\n");
return true;
}
//MessageBox.Show("LAN NOT FOUND");
Form1 frm1 = new Form1();
frm1.StatusTextBox.AppendText("\r\nIsNetworkAvailable(long minimumSpeed) Section: WARNING: No Active Local Network Found...");
frm1.StatusTextBox.AppendText("\r\n-Error: Cannot conitnue without valid IPV4 Gateway/! Please verify your network settings & make sure it is connected with working network.\r\n");
Globals.LAN = "0";
return false;

}

protected async void CheckDGW()
{
IPAddress result = null;
var cards = NetworkInterface.GetAllNetworkInterfaces().ToList();
if (cards.Any())
{
foreach (var card in cards)
{
var props = card.GetIPProperties();
if (props == null)
continue;

var gateways = props.GatewayAddresses;
if (!gateways.Any())
continue;
var gateway =
gateways.FirstOrDefault(g => g.Address.AddressFamily.ToString() == "InterNetwork");
if (gateway == null)
// Globals.DGW = "";
//this.StatusTextBox.AppendText("\r\n- No Network or IPV4 Gateway found. Cannot continue without them!\r\n");
//this.StatusTextBox.AppendText("if gw is null entry Your IPV4 Gateway is >" + Globals.DGW + "\r\n");
continue;

result = gateway.Address;
Globals.DGW = result.ToString();
// this.StatusTextBox.AppendText("Your IPV4 Gateway is >" + Globals.DGW + "\r\n");
break;
//MessageBox.Show("GATEWAY IS NULL2");
};
}
//if (Globals.DGW == "")
// ColorRed();
//this.StatusTextBox.AppendText("\r\n- No Network or IPV4 Gateway found. Cannot continue without them!\r\n");
//ColorBlack();
//return;
//return result;
var regx = new Regex("[:]");
if (regx.IsMatch(Globals.DGW))
{
this.StatusTextBox.AppendText("\r\n- ipv6 detected!\r\n");
MessageBox.Show("IPV6 detected");
Globals.DGW = "";
}
//MessageBox.Show(Globals.DGW);
if (Globals.DGW == "")
{

//this.StatusTextBox.AppendText("NULL Gateway >" + Globals.DGW + "\r\n");
//MessageBox.Show("GATEWAY IS NULL");
Globals.DGW = "";
// TIMER_STOP_FUNC();
//return;

}
else
{
//this.StatusTextBox.AppendText("Your IPV4 Gateway is >" + Globals.DGW + "\r\n");
}
}

private void button2_Click_2(object sender, EventArgs e)
{
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{
if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet);
{
if ((ni.Description.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Loopback", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Loopback", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Isatap", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Isatap", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Tunnel", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Tunnel", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Network Bridge", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Network Bridge", StringComparison.OrdinalIgnoreCase) >= 0))
continue;

if ((ni.Description.IndexOf("Microsoft 6to4 Adapter", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Microsoft 6to4 Adapter", StringComparison.OrdinalIgnoreCase) >= 0))
continue;

this.StatusTextBox.AppendText("\r\n" + ni.Name + "\r\n");
foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
{
if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
// Console.WriteLine(ip.Address.ToString());
this.StatusTextBox.AppendText("\r\n" + ip.Address.ToString() + "\r\n");
}
}
}
}

}

private void button1_Click(object sender, EventArgs e)
{
using (TcpClient tcpClient = new TcpClient())
{
try
{
tcpClient.Connect("dell.com", 80);
Console.WriteLine("Port open");
}
catch (Exception)
{
Console.WriteLine("Port closed");
}
}
}

private void button3_Click(object sender, EventArgs e)
{

}

private void button2_Click_1(object sender, EventArgs e)
{
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{
if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet);
{
if ((ni.Description.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Vmware", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Loopback", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Loopback", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Isatap", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Isatap", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Tunnel", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Tunnel", StringComparison.OrdinalIgnoreCase) >= 0))
continue;
if ((ni.Description.IndexOf("Network Bridge", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Network Bridge", StringComparison.OrdinalIgnoreCase) >= 0))
continue;

if ((ni.Description.IndexOf("Microsoft 6to4 Adapter", StringComparison.OrdinalIgnoreCase) >= 0) ||
(ni.Name.IndexOf("Microsoft 6to4 Adapter", StringComparison.OrdinalIgnoreCase) >= 0))
continue;

this.StatusTextBox.AppendText("\r\n" + ni.Name + "\r\n");
foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
{
if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
// Console.WriteLine(ip.Address.ToString());
this.StatusTextBox.AppendText("\r\n" + ip.Address.ToString() + "\r\n");
}
}
}
}

}

}

}

 


Filed under: Programming

iBBi Switcher – Cisco Management Tool

$
0
0

 


 

iBBi Switcher – Cisco Monitoring Tool

 

 

This is another application I made in C# using Visual Studio 2012. I generally use Cisco Configuration Assistant tool to Manage/Monitor our Cisco switches. Its great , works flawlessly, but still sometimes I need some thing quick to just monitor port status without  using full sized apps , above all the biggest advantage for our local environment is that I can give this app to local support staff and technician easily without giving them any further access to any panel.

Development is Powerful & Fun as well ~

Functions:

This app uses SNMPSHARPNET  library to query remove device by SNMP. It performs following actions …

  • Once Start button is pressed, It will first check if remote device or its SNMP is responding, if not give error (without freezing User Interface), If Response is OK, then continue further
  • Query all 24 ports with there description dynamically, Update the labels and Up/Down image according to the status.
  • Update Timer Label to see when last update on ports were made
  • Strip Menu for info/Exit Function.
  • Exit button on top right corner to exit the app immediately
  • Display progress bar to indicate process is active
  • Once START button is pushed, disable it to prevent duplication, added error as well.
  • STOP button to stop monitoring and timer and revert labels/images to default.
  • In Status Box window, display any ports UP / DOWN Status As showed in the image below

port down


the Code:

First download SNMPSHARPNET library and import it.

// C# / VS2012
// This is another application I made in C# using Visual Studio 2012.
// I generally use Cisco Configuration Assistant tool to Manage/Monitor our Cisco switches.
// Its great , works flawlessly, but still sometimes I need some thing quick to just monitor port status without using full sized apps
// above all the biggest advantage for our local environment is that I can give this app to local support staff and technician easily
// without giving them any further access to any panel.
// Make sure to download the SNMPSHARPNET library before using this code.
// Syed Jahanzaib
// aacable at hotmail dot com
// http:// aacable dot wordpress dot com
// 27-April-2017
using System;
using System.Net;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using SnmpSharpNet;
using System.Threading.Tasks;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public class Globals
{
public static string P1 = "";
public static string P2 = "";
public static string P3 = "";
public static string P4 = "";
public static string P5 = "";
public static string P6 = "";
public static string P7 = "";
public static string P8 = "";
public static string P9 = "";
public static string P10 = "";
public static string P11 = "";
public static string P12 = "";
public static string P13 = "";
public static string P14 = "";
public static string P15 = "";
public static string P16 = "";
public static string P17 = "";
public static string P18 = "";
public static string P19 = "";
public static string P20 = "";
public static string P21 = "";
public static string P22 = "";
public static string P23 = "";
public static string P24 = "";
public static string PL1 = "";
public static string PL2 = "";
public static string PL3 = "";
public static string PL4 = "";
public static string PL5 = "";
public static string PL6 = "";
public static string PL7 = "";
public static string PL8 = "";
public static string PL9 = "";
public static string PL10 = "";
public static string PL11 = "";
public static string PL12 = "";
public static string PL13 = "";
public static string PL14 = "";
public static string PL15 = "";
public static string PL16 = "";
public static string PL17 = "";
public static string PL18 = "";
public static string PL19 = "";
public static string PL20 = "";
public static string PL21 = "";
public static string PL22 = "";
public static string PL23 = "";
public static string PL24 = "";
}
public Form1()
{
InitializeComponent();
timer1.Stop();
timer1.Enabled = false;
}
private void Form1_Load(object sender, EventArgs e)
{
portReset();
datelabel.Text = DateTime.Now.ToLongDateString();
timelabel.Text = DateTime.Now.ToLongTimeString();
}
private void portReset()
{
port1.Image = Properties.Resources.port_nostatus;
port2.Image = Properties.Resources.port_nostatus;
port3.Image = Properties.Resources.port_nostatus;
port4.Image = Properties.Resources.port_nostatus;
port5.Image = Properties.Resources.port_nostatus;
port6.Image = Properties.Resources.port_nostatus;
port7.Image = Properties.Resources.port_nostatus;
port8.Image = Properties.Resources.port_nostatus;
port9.Image = Properties.Resources.port_nostatus;
port10.Image = Properties.Resources.port_nostatus;
port11.Image = Properties.Resources.port_nostatus;
port12.Image = Properties.Resources.port_nostatus;
port13.Image = Properties.Resources.port_nostatus;
port14.Image = Properties.Resources.port_nostatus;
port15.Image = Properties.Resources.port_nostatus;
port16.Image = Properties.Resources.port_nostatus;
port17.Image = Properties.Resources.port_nostatus;
port18.Image = Properties.Resources.port_nostatus;
port19.Image = Properties.Resources.port_nostatus;
port20.Image = Properties.Resources.port_nostatus;
port21.Image = Properties.Resources.port_nostatus;
port22.Image = Properties.Resources.port_nostatus;
port23.Image = Properties.Resources.port_nostatus;
port24.Image = Properties.Resources.port_nostatus;
p1textBox1.Text = null;
p2textBox1.Text = null;
p3textBox1.Text = null;
p4textBox1.Text = null;
p5textBox1.Text = null;
p6textBox1.Text = null;
p7textBox1.Text = null;
p8textBox1.Text = null;
p9textBox1.Text = null;
p10textBox1.Text = null;
p11textBox1.Text = null;
p12textBox1.Text = null;
p13textBox1.Text = null;
p14textBox1.Text = null;
p15textBox1.Text = null;
p16textBox1.Text = null;
p17textBox1.Text = null;
p18textBox1.Text = null;
p19textBox1.Text = null;
p20textBox1.Text = null;
p21textBox1.Text = null;
p22textBox1.Text = null;
p23textBox1.Text = null;
p24textBox1.Text = null;
plabel1.Text = null;
plabel2.Text = null;
plabel3.Text = null;
plabel4.Text = null;
plabel5.Text = null;
plabel6.Text = null;
plabel7.Text = null;
plabel8.Text = null;
plabel9.Text = null;
plabel10.Text = null;
plabel11.Text = null;
plabel12.Text = null;
plabel13.Text = null;
plabel14.Text = null;
plabel15.Text = null;
plabel16.Text = null;
plabel17.Text = null;
plabel18.Text = null;
plabel19.Text = null;
plabel20.Text = null;
plabel21.Text = null;
plabel22.Text = null;
plabel23.Text = null;
plabel24.Text = null;
StatusTextBox1.Text = String.Empty;
this.statusLoadinBar.Image = null;
}
private async void snmpGetFunc()
{
timer1.Enabled = true;
this.Invoke((MethodInvoker)delegate
{
lastUpdateLabel.Text = "Last Updated @" + DateTime.Now.ToLongDateString() + DateTime.Now.ToLongTimeString();
});
OctetString community = new OctetString("PUBLIC");
AgentParameters param = new AgentParameters(community);
param.Version = SnmpVersion.Ver2;
IpAddress agent = new IpAddress("10.0.0.1");
UdpTarget target = new UdpTarget((IPAddress)agent, 161, 1000, 1);
Pdu pdu = new Pdu(PduType.Get);
// Make SNMP request to test if device is responding or not
try
{
//Query Switch name, just for testing if SNMP/Device is reponding or NOT : ~ D / zaib
//pdu.VbList.Add(".1.3.6.1.2.1.1.5.0");
SnmpV2Packet result = (SnmpV2Packet)target.Request(pdu, param);
}
catch (SnmpException ex)
{
this.Invoke((MethodInvoker)delegate
{
this.StatusTextBox1.AppendText("\r\n" + ex.Message + "Either Device or SNMP not responding. Retrying again ...");
});
target.Dispose();
return;
}
if (timer1.Enabled == true)
{
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10101");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10102");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10103");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10104");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10105");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10106");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10107");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10108");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10109");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10110");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10111");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10112");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10113");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10114");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10115");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10116");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10117");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10118");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10119");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10120");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10121");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10122");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10123");
pdu.VbList.Add("1.3.6.1.2.1.2.2.1.8.10605");
// Ports End
// Now quering switch port names related data
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10101");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10102");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10103");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10104");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10105");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10106");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10107");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10108");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10109");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10110");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10111");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10112");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10113");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10114");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10115");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10116");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10117");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10118");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10119");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10120");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10121");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10122");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10123");
pdu.VbList.Add("1.3.6.1.2.1.31.1.1.1.18.10605");
// Get all data by SNMP query
SnmpV2Packet result = (SnmpV2Packet)target.Request(pdu, param);
// End
// Update Global Variables that will be used for few other functions
Globals.P1 = result.Pdu.VbList[0].Value.ToString();
Globals.P2 = result.Pdu.VbList[1].Value.ToString();
Globals.P3 = result.Pdu.VbList[2].Value.ToString();
Globals.P4 = result.Pdu.VbList[3].Value.ToString();
Globals.P5 = result.Pdu.VbList[4].Value.ToString();
Globals.P6 = result.Pdu.VbList[5].Value.ToString();
Globals.P7 = result.Pdu.VbList[6].Value.ToString();
Globals.P8 = result.Pdu.VbList[7].Value.ToString();
Globals.P9 = result.Pdu.VbList[8].Value.ToString();
Globals.P10 = result.Pdu.VbList[9].Value.ToString();
Globals.P11 = result.Pdu.VbList[10].Value.ToString();
Globals.P12 = result.Pdu.VbList[11].Value.ToString();
Globals.P13 = result.Pdu.VbList[12].Value.ToString();
Globals.P14 = result.Pdu.VbList[13].Value.ToString();
Globals.P15 = result.Pdu.VbList[14].Value.ToString();
Globals.P16 = result.Pdu.VbList[15].Value.ToString();
Globals.P17 = result.Pdu.VbList[16].Value.ToString();
Globals.P18 = result.Pdu.VbList[17].Value.ToString();
Globals.P19 = result.Pdu.VbList[18].Value.ToString();
Globals.P20 = result.Pdu.VbList[19].Value.ToString();
Globals.P21 = result.Pdu.VbList[20].Value.ToString();
Globals.P22 = result.Pdu.VbList[21].Value.ToString();
Globals.P23 = result.Pdu.VbList[22].Value.ToString();
Globals.P24 = result.Pdu.VbList[23].Value.ToString();
Globals.PL1 = result.Pdu.VbList[24].Value.ToString();
Globals.PL2 = result.Pdu.VbList[25].Value.ToString();
Globals.PL3 = result.Pdu.VbList[26].Value.ToString();
Globals.PL4 = result.Pdu.VbList[27].Value.ToString();
Globals.PL5 = result.Pdu.VbList[28].Value.ToString();
Globals.PL6 = result.Pdu.VbList[29].Value.ToString();
Globals.PL7 = result.Pdu.VbList[30].Value.ToString();
Globals.PL8 = result.Pdu.VbList[31].Value.ToString();
Globals.PL9 = result.Pdu.VbList[32].Value.ToString();
Globals.PL10 = result.Pdu.VbList[33].Value.ToString();
Globals.PL11 = result.Pdu.VbList[34].Value.ToString();
Globals.PL12 = result.Pdu.VbList[35].Value.ToString();
Globals.PL13 = result.Pdu.VbList[36].Value.ToString();
Globals.PL14 = result.Pdu.VbList[37].Value.ToString();
Globals.PL15 = result.Pdu.VbList[38].Value.ToString();
Globals.PL16 = result.Pdu.VbList[39].Value.ToString();
Globals.PL17 = result.Pdu.VbList[40].Value.ToString();
Globals.PL18 = result.Pdu.VbList[41].Value.ToString();
Globals.PL19 = result.Pdu.VbList[42].Value.ToString();
Globals.PL20 = result.Pdu.VbList[43].Value.ToString();
Globals.PL21 = result.Pdu.VbList[44].Value.ToString();
Globals.PL22 = result.Pdu.VbList[45].Value.ToString();
Globals.PL23 = result.Pdu.VbList[46].Value.ToString();
Globals.PL24 = result.Pdu.VbList[47].Value.ToString();
this.Invoke((MethodInvoker)delegate
{
//Update Port Description / Names Text Labels
plabel1.Text = Globals.PL1;
plabel2.Text = Globals.PL2;
plabel3.Text = Globals.PL3;
plabel4.Text = Globals.PL4;
plabel5.Text = Globals.PL5;
plabel6.Text = Globals.PL6;
plabel7.Text = Globals.PL7;
plabel8.Text = Globals.PL8;
plabel9.Text = Globals.PL9;
plabel10.Text = Globals.PL10;
plabel11.Text = Globals.PL11;
plabel12.Text = Globals.PL12;
plabel13.Text = Globals.PL13;
plabel14.Text = Globals.PL14;
plabel15.Text = Globals.PL15;
plabel16.Text = Globals.PL16;
plabel17.Text = Globals.PL17;
plabel18.Text = Globals.PL18;
plabel19.Text = Globals.PL19;
plabel20.Text = Globals.PL20;
plabel21.Text = Globals.PL21;
plabel22.Text = Globals.PL22;
plabel23.Text = Globals.PL23;
plabel24.Text = Globals.PL24;
//});
if (Globals.P1 == "1")
{
port1.Image = Properties.Resources.port_up;
p1textBox1.Text = Globals.P1;
}
else
{
port1.Image = Properties.Resources.port_down;
}
if (Globals.P2 == "1")
{
port2.Image = Properties.Resources.port_up;
p2textBox1.Text = Globals.P2;
}
else
{
port2.Image = Properties.Resources.port_down;
}
if (Globals.P3 == "1")
{
port3.Image = Properties.Resources.port_up;
p3textBox1.Text = Globals.P3;
}
else
{
port3.Image = Properties.Resources.port_down;
}
if (Globals.P4 == "1")
{
port4.Image = Properties.Resources.port_up;
p4textBox1.Text = Globals.P4;
}
else
{
port4.Image = Properties.Resources.port_down;
}
if (Globals.P5 == "1")
{
port5.Image = Properties.Resources.port_up;
p5textBox1.Text = Globals.P5;
}
else
{
port5.Image = Properties.Resources.port_down;
}
if (Globals.P6 == "1")
{
port6.Image = Properties.Resources.port_up;
p6textBox1.Text = Globals.P6;
}
else
{
port6.Image = Properties.Resources.port_down;
}
if (Globals.P7 == "1")
{
port7.Image = Properties.Resources.port_up;
}
else
{
port7.Image = Properties.Resources.port_down;
}
if (Globals.P8 == "1")
{
port8.Image = Properties.Resources.port_up;
}
else
{
port8.Image = Properties.Resources.port_down;
}
if (Globals.P9 == "1")
{
port9.Image = Properties.Resources.port_up;
}
else
{
port9.Image = Properties.Resources.port_down;
}
if (Globals.P10 == "1")
{
port10.Image = Properties.Resources.port_up;
}
else
{
port10.Image = Properties.Resources.port_down;
}
if (Globals.P11 == "1")
{
port11.Image = Properties.Resources.port_up;
}
else
{
port11.Image = Properties.Resources.port_down;
}
if (Globals.P12 == "1")
{
port12.Image = Properties.Resources.port_up;
}
else
{
port12.Image = Properties.Resources.port_down;
}
if (Globals.P13 == "1")
{
port13.Image = Properties.Resources.port_up;
}
else
{
port13.Image = Properties.Resources.port_down;
}
if (Globals.P14 == "1")
{
port14.Image = Properties.Resources.port_up;
}
else
{
port14.Image = Properties.Resources.port_down;
}
if (Globals.P15 == "1")
{
port15.Image = Properties.Resources.port_up;
}
else
{
port15.Image = Properties.Resources.port_down;
}
if (Globals.P16 == "1")
{
port16.Image = Properties.Resources.port_up;
}
else
{
port16.Image = Properties.Resources.port_down;
}
if (Globals.P17 == "1")
{
port17.Image = Properties.Resources.port_up;
}
else
{
port17.Image = Properties.Resources.port_down;
}
if (Globals.P18 == "1")
{
port18.Image = Properties.Resources.port_up;
}
else
{
port18.Image = Properties.Resources.port_down;
}
if (Globals.P19 == "1")
{
port19.Image = Properties.Resources.port_up;
}
else
{
port19.Image = Properties.Resources.port_down;
}
if (Globals.P20 == "1")
{
port20.Image = Properties.Resources.port_up;
}
else
{
port20.Image = Properties.Resources.port_down;
}
if (Globals.P21 == "1")
{
port21.Image = Properties.Resources.port_up;
}
else
{
port21.Image = Properties.Resources.port_down;
}
if (Globals.P22 == "1")
{
port22.Image = Properties.Resources.port_up;
}
else
{
port22.Image = Properties.Resources.port_down;
}
if (Globals.P23 == "1")
{
port23.Image = Properties.Resources.port_up;
}
else
{
port23.Image = Properties.Resources.port_down;
}
if (Globals.P24 == "1")
{
port24.Image = Properties.Resources.port_up;
p24textBox1.Text = Globals.P24;
}
else
{
port24.Image = Properties.Resources.port_down;
p24textBox1.Text = Globals.P24;
}
});
ClearTextBox1TimeOnly();
}
}
private static bool isRun = false;
private static readonly object syncLock = new object();
public void ClearTextBox1TimeOnly()
{
lock (syncLock)
{
if (!isRun)
{
this.Invoke((MethodInvoker)delegate
{
StatusTextBox1.Text = String.Empty;
this.StatusTextBox1.Text += string.Format("Starting monitoring of Cisco Switch Ports. Activated [5 sec delay] ... \r\n");
});
isRun = true;
}
}
}
// Start the app. start button
private async void button1_Click(object sender, EventArgs e)
{
if (timer1.Enabled == true)
{
this.StatusTextBox1.Text += string.Format("Monitoring already started. Stop it to first to start new instance !\r\n");
}
else
{
startButton.Enabled = false;
isRun = false;
timer1.Enabled = true;
timer1.Start();
this.statusLoadinBar.Image = Properties.Resources.loading_gif;
//await Task.Run(() =>
//{
//await Task.Run(() => snmpGetFunc();
//});
Task.Factory.StartNew(() => snmpGetFunc());
this.StatusTextBox1.Text += string.Format("Starting monitoring of Cisco Switch Ports. \r\n");
}
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void timer4dt_Tick(object sender, EventArgs e)
{
timelabel.Text = DateTime.Now.ToLongTimeString();
timer4dt.Start();
}
private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
}
private void stopButton_Click(object sender, EventArgs e)
{
if (timer1.Enabled == true)
{
startButton.Enabled = true;
timer1.Enabled = false;
timer1.Stop();
portReset();
this.StatusTextBox1.AppendText("\r\nMonitoring of switch have been Stopped on user request \r\n");
}
else
{
this.StatusTextBox1.AppendText("\r\nMonitoring not started yet !\r\n");
startButton.Enabled = true;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
Task.Factory.StartNew(() => snmpGetFunc());
}
private void exitButton_Click(object sender, EventArgs e)
{
this.statusLoadinBar.Image = null;
timer1.Stop();
portReset();
this.StatusTextBox1.AppendText("\r\nExiting on user request \r\n");
Application.Exit();
}
private void StatusTextBox1_TextChanged(object sender, EventArgs e)
{
StatusTextBox1.SelectionStart = StatusTextBox1.Text.Length;
StatusTextBox1.ScrollToCaret();
}
private void p1textBox1_TextChanged(object sender, EventArgs e)
{
if (Globals.P1 == "1")
this.StatusTextBox1.AppendText("\r\nPort 1 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 1 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}

private void p2textBox1_TextChanged(object sender, EventArgs e)
{
if (Globals.P2 == "1")
this.StatusTextBox1.AppendText("\r\nPort 2 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 2 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}

private void p3textBox1_TextChanged(object sender, EventArgs e)
{
if (Globals.P3 == "1")
this.StatusTextBox1.AppendText("\r\nPort 3 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 3 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}

private void p4textBox1_TextChanged(object sender, EventArgs e)
{
if (Globals.P4 == "1")
this.StatusTextBox1.AppendText("\r\nPort 4 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 4 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}

private void p5textBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P5 == "1")
this.StatusTextBox1.AppendText("\r\nPort 5 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 5 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}
private void p6textBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P6 == "1")
this.StatusTextBox1.AppendText("\r\nPort 6 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 6 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}
private void p7textBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P7 == "1")
this.StatusTextBox1.AppendText("\r\nPort 7 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 7 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}
private void p8textBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P8 == "1")
this.StatusTextBox1.AppendText("\r\nPort 8 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 8 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}
private void p9textBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P9 == "1")
this.StatusTextBox1.AppendText("\r\nPort 9 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 9 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}
private void p10textBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P10 == "1")
this.StatusTextBox1.AppendText("\r\nPort 10 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 10 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}

private void p11textBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P11 == "1")
this.StatusTextBox1.AppendText("\r\nPort 11is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 11is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}

private void p12TextBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P12 == "1")
this.StatusTextBox1.AppendText("\r\nPort 12 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 12 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}

private void p13TextBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P13 == "1")
this.StatusTextBox1.AppendText("\r\nPort 13 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 13 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}
private void p14TextBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P14 == "1")
this.StatusTextBox1.AppendText("\r\nPort 14 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 14 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}
private void p15TextBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P15 == "1")
this.StatusTextBox1.AppendText("\r\nPort 15 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 15 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}
private void p17TextBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P17 == "1")
this.StatusTextBox1.AppendText("\r\nPort 17 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 17 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}
private void p18TextBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P18 == "1")
this.StatusTextBox1.AppendText("\r\nPort 18 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 18 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}

private void p19TextBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P19 == "1")
this.StatusTextBox1.AppendText("\r\nPort 19 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 19 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}
private void p20TextBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P20 == "1")
this.StatusTextBox1.AppendText("\r\nPort 20 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 20 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}
private void p21TextBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P21 == "1")
this.StatusTextBox1.AppendText("\r\nPort 21 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 21 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}
private void p22TextBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P22 == "1")
this.StatusTextBox1.AppendText("\r\nPort 22 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 22 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}
private void p23TextBox1_TextChanged_1(object sender, EventArgs e)
{
if (Globals.P23 == "1")
this.StatusTextBox1.AppendText("\r\nPort 23 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 23 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}

private void p24textBox1_TextChanged(object sender, EventArgs e)
{
if (Globals.P24 == "1")
this.StatusTextBox1.AppendText("\r\nPort 24 is now UP @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
else
this.StatusTextBox1.AppendText("\r\nPort 24 is now DOWN! @" + DateTime.Now.ToLongDateString() + " / " + DateTime.Now.ToLongTimeString());
}

}
}


Regard’s
Syed Jahanzaib


Filed under: Cisco Related

Howto bypass specific client from PCC & route to specific WAN link [Part-2]

$
0
0

Distribution.jpg


Scenario:

Since many asked the same query, so rather to reply individually, here is one method I used at one OP & it works fine. You may opt for others solution which ever is easy for you. the thing is it should work thats it:)]

We have configured Mikrotik as 3 wan load balancer [DSL links]. PPPoE Server is configured as well. All working Good. Now we have introduced premium package for dedicated users & we want to route them via newly added 4th WAN link only so there service should work smoothly even in peak times as well. therefore we need to bypass this group from the PCC & route them to 4th WAN link which has dedicated CIR bandwidth.

Solution:

There are always different ways to achieve any task. It depends on the Operator expertise, & network scenario as well.

Copy Paste WILL Not work !

Every network is different ~ I am sharing this code so you should learn concepts. Minimize copy paste culture, invent your solutions by understanding logic’s & implement it by modifying or creating code. 

Drink Wiki & you shall succeed 😀

~ zaiB

In this example I am showing one example, [You may opt for others which ever is easy for you. the thing is it should work that’s it:) ]

  1. make pppoe pool-1 in address list. [This one for general clients = 172,16.0.1-172,16.0.255 ]
  2. make pppoe pool-2 in address list  [This one for dedicated clients = 172,16.1.1-172,16.1.255 ]
  3. when you will create normal users , assign them pppoe pool-1
  4. when you will create dedicated users , assign them pppoe pool-2
  5. In your Mangle rules, where you mark connections (classifier section] , make sure you specify pppoe pool-1 list in source address list. Also you need to duplicate this rule, and in source address list, select pool-2, basically we will mark connections for both pools, and assign them different marking connection name.
  6. now in mark routing section, repeat above, and mark routing for both marked connections.
  7. in Nat, create natting rules so traffic can be natted by all 4 wan links. you can trim this by single rule as well 🙂
  8. in Routes, create rules for all marked packets, for normal clients, user wan1-3, for dedicated clients marked packets, route them specific wan link [like wan4]

* Working Example


/ip pool
# General users pppoe profile pool, which will be routed in 3 wan links
add name=pool-1 ranges=172.16.0.1-172.16.0.254
# Dedicated users pppoe profile pool, which will be routed via wan-4 link only
add name=pool-2 ranges=172.16.1.1-172.16.1.254

/ip firewall address-list
# General users pool list, which will be routed in 3 wan links
add address=172.16.0.1-172.16.0.255 list=pool-1
# Dedicated users pool list , which will be routed via wan-4 link only
add address=172.16.1.1-172.16.1.255 list=pool-2

/ip firewall mangle

add action=accept chain=prerouting comment=PCC in-interface=pppoe-out-1
add action=accept chain=prerouting comment=PCC in-interface=pppoe-out-2
add action=accept chain=prerouting comment=PCC in-interface=pppoe-out-3
add action=accept chain=prerouting comment=PCC in-interface=pppoe-out-4

# Marking connections for dedicated clients from pool-2 address list, to be routed via WAN-3 link only
add action=mark-connection chain=prerouting comment="Mark pool-2 dedicated Users Connections" new-connection-mark=pool2-conn passthrough=yes src-address-list=15mb-pool-list
add action=mark-routing chain=prerouting comment="Mark pool-2 dedicated Users Routing Pkts" connection-mark=pool2-conn dst-address-type="" log-prefix=20mb_ new-routing-mark=pool2-route passthrough=yes

# Marking connections for general users clients from pool-1 address list, to be distributed among 3 wan link
add action=mark-connection chain=prerouting comment=PCC_MARK_CONNECTION dst-address-type=!local new-connection-mark=wan1_conn passthrough=yes per-connection-classifier=src-address:3/0 src-address-list=pool-1
add action=mark-connection chain=prerouting comment=PCC_MARK_CONNECTION dst-address-type=!local new-connection-mark=wan2_conn passthrough=yes per-connection-classifier=src-address:3/1 src-address-list=pool-1
add action=mark-connection chain=prerouting comment=PCC_MARK_CONNECTION dst-address-type=!local new-connection-mark=wan3_conn passthrough=yes per-connection-classifier=src-address:3/2 src-address-list=pool-1

# Marking routing form above marked conections, for general users
add action=mark-routing chain=prerouting comment=PCC_MARK_ROUTING connection-mark=wan1_conn new-routing-mark=to_wan1 passthrough=yes
add action=mark-routing chain=prerouting comment=PCC_MARK_ROUTING connection-mark=wan2_conn new-routing-mark=to_wan2 passthrough=yes
add action=mark-routing chain=prerouting comment=PCC_MARK_ROUTING connection-mark=wan3_conn new-routing-mark=to_wan3 passthrough=yes

/ip firewall nat
# Allow natting for dedicated clients, to be nat via wan-4
add action=masquerade chain=srcnat comment="ALLOW NATTING FOR POOL-2 Dedicated USERS " out-interface=pppoe-out-4 src-address-list=pool-2
# Allow natting for general clients, to be nat via wan link number 1-2-3
add action=masquerade chain=srcnat comment=NATTING_DSL_1 out-interface=pppoe-out-1 src-address-list="pool-1"
add action=masquerade chain=srcnat comment=NATTING_DSL_2 out-interface=pppoe-out-2 src-address-list="pool-1"
add action=masquerade chain=srcnat comment=NATTING_DSL_3 out-interface=pppoe-out-3 src-address-list="pool-1"

/ip route
# Route for general users marked traffic - to be passed via 3 wan links
add check-gateway=ping distance=1 gateway=pppoe-out-1 routing-mark=to_wan1
add check-gateway=ping distance=1 gateway=pppoe-out-2 routing-mark=to_wan2
add check-gateway=ping distance=1 gateway=pppoe-out-3 routing-mark=to_wan3

# Route for dedicated users marked traffic - to be passed via wan-4 link only
add comment="Route Rule for dedicated users to go via WAN-4 only " distance=1 gateway=pppoe-out-4 routing-mark=pool2-route


Regard’s
Syed Jahanzaib


Filed under: Mikrotik Related

Howto install DMASoftlab Radius Manager in Centos 7 – 64bit

$
0
0

centos7

dma415

No doubt, Radius billing is one of the most important point of focus in any ISP network. ISP finance depends on this system to work smoothly. There are various ready made radius application based on LINUX are available in the market to cater different requirements of various operators. Among many, Dmasoftlab radius manager is one of the most cheapest but feature rich radius candidate. It provide variety of options for any ISP. Its full features can be viewed at Radius Manager web site. It required very little resources to run, provide plenty of user administration functions, backup / restoration / management is quite simple as well. plus in background you can accompany it with many scripting of your own to perform various customized functions.

We all know that cloud is every where now and almost all hosting providers are now providing latest versions of operating system like Centos 7. Some of us are well aware that DMA Radius Manager is quite comfortable with following flavors of nix …

  • Ubuntu 12.4 / 32bit [*** Best OS & my personnel choice, as recovery & troubleshooting is much easier in this variant]
  • Centos 6.5/6.6

But now a days many operators are switching to cloud where hosting providers are not providing older versions of centos/ubuntu. As i had to do few installation on cloud for few clients & I had to recall all the bits & bytes to do the installation every time, therefore I am posting step by step copy paste friendly version of guide on howto install Radius Manager in Centos 7. I posted ready made scripts for Ubuntu 12 Installation Script &Centos 6 in previous guides but This one is for Centos 7 to make installation quicker. I will make its script but better to do it manually as Centos 7 is a bit tricky which will give you some tough time in various aspects

  • OS Used in this guide = CentOS Linux release 7.3.1611 (Core)

Steps:

1# Disabling Firewall to avoid interruption

First we will update YUM & install nano for easy text editing, as many of us are not much comfortable with VI. NANO is better …

yum install update
yum -y install nano

* Disable IPTABLES

service iptables stop
chkconfig iptables off

* Disable SELINUX

So that it may not interfere with our installation/accessing. To disable builtin firewall permanently in centos, edit following

nano /etc/selinux/config

and change the

SELINUX=enforcing

to

SELINUX=disabled

Save & Exit .

*Disable Firewall(Daemon)

Now Disable Firewall’Daemon’ so that it may not interfere with our installation/accessing

systemctl status firewalld
systemctl stop firewalld
systemctl disable firewalld

Reboot system to take effect.


2# Installing various supporting modules !

1- Installing EPEL Repo to download various other supporting packages like mysql,apache etc

rpm -ivh https://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-9.noarch.rpm
yum -y install mc wget crontabs make gcc libtool-ltdl curl mysql-devel php php-mysql php-gd php-snmp php-process ntp alpine mariadb-server mariadb php-mcrypt cronie wget net-tools psmisc
yum -y install glibc.i686 libgcc_s.so.1
systemctl start mariadb.service
systemctl enable mariadb.service

3# Configuring Mysql Section

Now initiate mysql initial setup

mysql_secure_installation

Above command will ask few queries, read and select accordingly. ** Make sure to setup mysql root password **

*Now start / enable APACHE services 

systemctl start httpd.service
systemctl enable httpd.service

4# Adding IONCUBE module in PHP

Verify your PHP version  by php -v & copy the iocube load accordingly.
At my station, I had `PHP 5.4.16 (cli) (built: Nov  6 2016 00:29:02)` version installed by YUM.

wget http://downloads3.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz
tar -xvzf ioncube_loaders_lin_x86-64.tar.gz
cd ioncube
mv ioncube_loader_lin_5.4.so /usr/lib64/php/modules/
chmod 777 /usr/lib64/php/modules/ioncube_loader_lin_5.4.so

Now add ioncube library in php

nano /etc/php.ini

and add following line after [PHP] heading, usually this heading is in first line.

zend_extension = /usr/lib64/php/modules/ioncube_loader_lin_5.4.so

& restart APACHE service so it can load the new module

systemctl restart httpd.service

re-run ​​’php -v to verify you have something like [if successfull]

PHP 5.4.16 (cli) (built: Nov 6 2016 00:29:02)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
with the ionCube PHP Loader (enabled) + Intrusion Protection from ioncube24.com unconfigured) v6.1.0 (), Copyright (c) 2002-2017, by ionCube Ltd.

5# Download FREERADIUS & compile.

cd /temp
wget http://www.dmasoftlab.com/cont/download/freeradius-server-2.2.0-dma-patch-2.tar.gz
tar -xvzf freeradius-server-2.2.0-dma-patch-2.tar.gz
cd freeradius-server-2.2.0
./configure
make
make install

Above may take some time to compile. After its done, issue following command to initiate radius

radiusd -X

If you get error in first attempt, try to run it again, and you may see following message on success

centos-radiusdx

Now press CTRL+C to return to command prompt.


 

6- Radius DB creation in MYSQL

Create mysql DATABASES for radius usage. Make sure to change the passwords where required, example mysql root password. It’s OK to use default passwords for the test flight, but for production server Its Highly recommended to use different passwords while you do the installation.

mysql -u root -pYOURMYSQLPASS
CREATE DATABASE radius;
CREATE DATABASE radius;
CREATE DATABASE conntrack;
CREATE USER 'radius'@'localhost' IDENTIFIED BY 'radius123';
CREATE USER 'conntrack'@'localhost' IDENTIFIED BY 'conn123';
GRANT ALL ON radius.* TO radius@localhost;
GRANT ALL ON conntrack.* TO conntrack@localhost;

7# Download & Install RADIUS MANAGER 4.1.0

cd /temp/
wget http://wifismartzone.com/files/rm_related/radiusmanager-4.1.0.tgz
tar zxvf radiusmanager-4.1.0.tgz
cd radiusmanager-4.1.0
chmod 755 install.sh
# Now start the Radius Install Script.
# once you will run INSTALL.SH , it will ask various queries, select according to your OS choice

./install.sh

8# Access Radius Manager Administration Panel

Now try to access your radius manager admin panel from any browser pointing to ..

http://yourip/radiusmanager/admin.php

If all ok , you will see following window in your browser

dma-login-ok

* Default ID Password 
ID = admin
Password = 1111

Enjoy,

~*~*~*~*~*~*~*~*~*~*~*~*~*~*~

If you see error or blank page, use following Apache error/access logs for further trouble shoot. Most common causes are invalid license files / in-correct php ioncube files.

tail -f /var/log/httpd/error_log
tail -f /var/log/httpd/access_log

 


# TIPS

 

TIP#1 – How to create Virtual NIC with customized / cloned MAC address

First check what ethernet name you have currently, mostly its eth0, [change it according to your network].

ip link add link eth0 address 00:11:22:33:44:55 eth0.1 type macvlan
ifconfig eth0.1 up
ifconfig eth0.1 10.0.0.2

Verify if NIC is created with our desired NIC as well.

ifconfig

# Restart APACHE service if required, YKWIM ; )

systemctl restart httpd.service

TIP#2 – Deploying PATCH 4.1.5 for Centos

DMA released few patches for its radius application. Latest version is 4.1.6 , but I usually prefer to go with 4.1.5. Following is quick copy paste version to upgrade. Make sure that you have proper working installation of radius manager & if you are not much familiarized with the restoration process then you should backup your current installation before proceeding.

# SYED JAHANZAIB
# HTTPS://AACABLE . WORDPRESS . COM
# AACABLE at HOTMAIL dot COM
mkdir /temp
cd /temp
wget http://wifismartzone.com/files/rm_related/radiusmanager-4.1-cumulative_patch.tgz
tar zxvf /temp/radiusmanager-4.1-cumulative_patch.tgz
cd /temp/radiusmanager-4.1-cumulative_patch/
cp -vrf www/radiusmanager/* /var/www/html/radiusmanager
chmod 755 bin/rm*
service rmpoller stop
cp bin/* /usr/local/bin
cp raddb/acct_users /usr/local/etc/raddb
chmod 640 /usr/local/etc/raddb/acct_users
chown root.root /usr/local/etc/raddb/acct_users
service radiusd restart
service rmpoller start

For more information, please refer to

Dmasoftlab Radius Manager 4.1.5 Patch


Note: If you find any errors in this guide, please do let me know

Thanks & Best Regard’s

~SYED JAHANZAIB~


Filed under: Radius Manager

Blocking WhatsApp in Mikrotik

$
0
0

block whatsapp image.PNG

For some reasons, the management decided to block whataAPP as per policy. In attempt to block WhatsAPP application in Mikrotik, I used WhatsAPP provided address list in order to block the app. [there are already many guides on internet, but I used old school method to block this app & got success]

I am sharing two methods to achieve the same target. There is also another method in which you forcefully divert users dns traffic to your mikrotik dns and use script to fetch ip addresses associated with any URL having whatsapp in it, but I am not discussing it here at a moment.

You can also automate this task by fetching the list from whatsapp directly and import it in address list , so that you can always have updated whatsapp servers list. Although the list doesn’t update very frequently but still its good idea to automate it with scheduler.


Method #1 – Download list & import to address list along with firewall block rule

 

1- Download whatsapp IP (CIDR) list from

https://www.whatsapp.com/cidr.txt

Save it as  cidr.txt

Note: If you dont have ipv6 , then open this file and remove all the IPV6 addressess or else you will see below error while importing 

ipv6 error

 

2- Upload this cidr.txt file to Mikrotik FILES section.

[if you use fetch method to download file directly to mikrotik, then you dont need to upload file manualy, but I used this method because most local networks are running on ipv4, so I had to remove ipv6 entries first in order to import list)

cidr

 

3- Import the file contents (which includes ip addresses) using following script

{
:local content [/file get [/file find name=cidr.txt] contents]
:local contentLen [:len $content]
:local lineEnd 0
:local line ""
:local lastEnd 0
:while ($lineEnd < $contentLen) do={
:set lineEnd [:find $content "\r\n" $lastEnd]
:if ([:len $lineEnd] = 0) do={
:set lineEnd $contentLen
}
:set line [:pick $content $lastEnd $lineEnd]
:set lastEnd ($lineEnd + 2)
/ip firewall address-list add list="whatsapp_list" address=$line
}
}

If successfull , you will see address list as below …

whtsapp address list

4- Create Firewall Filter rule to block requests going to whatsapp_list 

/ip firewall filter
add action=drop chain=forward comment="Block Whatsapp address list - zaib" disabled=yes dst-address-list=whatsapp_list

Result!

block whatapp result

Done!







Method #2 – Copy Paste Method with ipV4 package only.

Open Terminal & copy paste following code. It will add address list name ‘whatsapp_list’ along with firewall rule to block requests going to this list.


/ip firewall address-list
add address=31.13.64.51 list=whatsapp_list
add address=31.13.65.49 list=whatsapp_list
add address=31.13.66.49 list=whatsapp_list
add address=31.13.68.52 list=whatsapp_list
add address=31.13.69.240 list=whatsapp_list
add address=31.13.70.49 list=whatsapp_list
add address=31.13.71.49 list=whatsapp_list
add address=31.13.72.52 list=whatsapp_list
add address=31.13.73.49 list=whatsapp_list
add address=31.13.74.49 list=whatsapp_list
add address=31.13.75.52 list=whatsapp_list
add address=31.13.76.81 list=whatsapp_list
add address=31.13.77.49 list=whatsapp_list
add address=31.13.78.53 list=whatsapp_list
add address=31.13.80.53 list=whatsapp_list
add address=31.13.81.53 list=whatsapp_list
add address=31.13.82.51 list=whatsapp_list
add address=31.13.83.51 list=whatsapp_list
add address=31.13.84.51 list=whatsapp_list
add address=31.13.85.51 list=whatsapp_list
add address=31.13.86.51 list=whatsapp_list
add address=31.13.87.51 list=whatsapp_list
add address=31.13.88.49 list=whatsapp_list
add address=31.13.90.51 list=whatsapp_list
add address=31.13.91.51 list=whatsapp_list
add address=31.13.92.52 list=whatsapp_list
add address=31.13.93.51 list=whatsapp_list
add address=31.13.94.52 list=whatsapp_list
add address=31.13.95.63 list=whatsapp_list
add address=50.22.198.204/30 list=whatsapp_list
add address=50.22.210.32/30 list=whatsapp_list
add address=50.22.210.128/27 list=whatsapp_list
add address=50.22.225.64/27 list=whatsapp_list
add address=50.22.235.248/30 list=whatsapp_list
add address=50.22.240.160/27 list=whatsapp_list
add address=50.23.90.128/27 list=whatsapp_list
add address=50.97.57.128/27 list=whatsapp_list
add address=75.126.39.32/27 list=whatsapp_list
add address=108.168.174.0/27 list=whatsapp_list
add address=108.168.176.192/26 list=whatsapp_list
add address=108.168.177.0/27 list=whatsapp_list
add address=108.168.180.96/27 list=whatsapp_list
add address=108.168.254.65 list=whatsapp_list
add address=108.168.255.224 list=whatsapp_list
add address=108.168.255.227 list=whatsapp_list
add address=157.240.0.53 list=whatsapp_list
add address=157.240.1.53 list=whatsapp_list
add address=157.240.2.53 list=whatsapp_list
add address=157.240.3.53 list=whatsapp_list
add address=157.240.6.53 list=whatsapp_list
add address=157.240.7.54 list=whatsapp_list
add address=157.240.8.53 list=whatsapp_list
add address=157.240.9.53 list=whatsapp_list
add address=157.240.10.53 list=whatsapp_list
add address=157.240.11.53 list=whatsapp_list
add address=157.240.12.53 list=whatsapp_list
add address=157.240.13.54 list=whatsapp_list
add address=158.85.0.96/27 list=whatsapp_list
add address=158.85.5.192/27 list=whatsapp_list
add address=158.85.46.128/27 list=whatsapp_list
add address=158.85.48.224/27 list=whatsapp_list
add address=158.85.58.0/25 list=whatsapp_list
add address=158.85.61.192/27 list=whatsapp_list
add address=158.85.224.160/27 list=whatsapp_list
add address=158.85.233.32/27 list=whatsapp_list
add address=158.85.249.128/27 list=whatsapp_list
add address=158.85.254.64/27 list=whatsapp_list
add address=169.44.23.192/27 list=whatsapp_list
add address=169.44.36.0/25 list=whatsapp_list
add address=169.44.57.64/27 list=whatsapp_list
add address=169.44.58.64/27 list=whatsapp_list
add address=169.44.80.0/26 list=whatsapp_list
add address=169.44.82.96/27 list=whatsapp_list
add address=169.44.82.128/27 list=whatsapp_list
add address=169.44.82.192/26 list=whatsapp_list
add address=169.44.83.0/26 list=whatsapp_list
add address=169.44.83.96/27 list=whatsapp_list
add address=169.44.83.128/27 list=whatsapp_list
add address=169.44.83.192/26 list=whatsapp_list
add address=169.44.84.0/24 list=whatsapp_list
add address=169.44.85.64/27 list=whatsapp_list
add address=169.44.87.160/27 list=whatsapp_list
add address=169.44.167.0/27 list=whatsapp_list
add address=169.45.71.32/27 list=whatsapp_list
add address=169.45.71.96/27 list=whatsapp_list
add address=169.45.87.128/26 list=whatsapp_list
add address=169.45.169.192/27 list=whatsapp_list
add address=169.45.182.96/27 list=whatsapp_list
add address=169.45.210.64/27 list=whatsapp_list
add address=169.45.214.224/27 list=whatsapp_list
add address=169.45.219.224/27 list=whatsapp_list
add address=169.45.237.192/27 list=whatsapp_list
add address=169.45.238.32/27 list=whatsapp_list
add address=169.45.248.96/27 list=whatsapp_list
add address=169.45.248.160/27 list=whatsapp_list
add address=169.46.52.224/27 list=whatsapp_list
add address=169.46.111.144/28 list=whatsapp_list
add address=169.47.5.192/26 list=whatsapp_list
add address=169.47.6.64/27 list=whatsapp_list
add address=169.47.33.128/27 list=whatsapp_list
add address=169.47.35.32/27 list=whatsapp_list
add address=169.47.37.128/27 list=whatsapp_list
add address=169.47.40.128/27 list=whatsapp_list
add address=169.47.42.96/27 list=whatsapp_list
add address=169.47.42.160/27 list=whatsapp_list
add address=169.47.42.192/26 list=whatsapp_list
add address=169.47.47.160/27 list=whatsapp_list
add address=169.47.130.96/27 list=whatsapp_list
add address=169.47.192.192/27 list=whatsapp_list
add address=169.47.194.128/27 list=whatsapp_list
add address=169.47.198.128/27 list=whatsapp_list
add address=169.47.212.160/27 list=whatsapp_list
add address=169.53.29.128/27 list=whatsapp_list
add address=169.53.48.32/27 list=whatsapp_list
add address=169.53.71.224/27 list=whatsapp_list
add address=169.53.81.64/27 list=whatsapp_list
add address=169.53.250.128/26 list=whatsapp_list
add address=169.53.252.64/27 list=whatsapp_list
add address=169.53.255.64/27 list=whatsapp_list
add address=169.54.2.160/27 list=whatsapp_list
add address=169.54.44.224/27 list=whatsapp_list
add address=169.54.51.32/27 list=whatsapp_list
add address=169.54.55.192/27 list=whatsapp_list
add address=169.54.193.160/27 list=whatsapp_list
add address=169.54.210.0/27 list=whatsapp_list
add address=169.54.222.128/27 list=whatsapp_list
add address=169.55.67.224/27 list=whatsapp_list
add address=169.55.69.128/26 list=whatsapp_list
add address=169.55.74.32/27 list=whatsapp_list
add address=169.55.75.96/27 list=whatsapp_list
add address=169.55.100.160/27 list=whatsapp_list
add address=169.55.126.64/26 list=whatsapp_list
add address=169.55.210.96/27 list=whatsapp_list
add address=169.55.235.160/27 list=whatsapp_list
add address=173.192.162.32/27 list=whatsapp_list
add address=173.192.219.128/27 list=whatsapp_list
add address=173.192.222.160/27 list=whatsapp_list
add address=173.192.231.32/27 list=whatsapp_list
add address=173.193.205.0/27 list=whatsapp_list
add address=173.193.230.96/27 list=whatsapp_list
add address=173.193.230.128/27 list=whatsapp_list
add address=173.193.230.192/27 list=whatsapp_list
add address=173.193.239.0/27 list=whatsapp_list
add address=174.36.208.128/27 list=whatsapp_list
add address=174.36.210.32/27 list=whatsapp_list
add address=174.36.251.192/27 list=whatsapp_list
add address=174.37.199.192/27 list=whatsapp_list
add address=174.37.217.64/27 list=whatsapp_list
add address=174.37.243.64/27 list=whatsapp_list
add address=174.37.251.0/27 list=whatsapp_list
add address=179.60.192.51 list=whatsapp_list
add address=179.60.195.51 list=whatsapp_list
add address=184.173.136.64/27 list=whatsapp_list
add address=184.173.147.32/27 list=whatsapp_list
add address=184.173.161.64 list=whatsapp_list
add address=184.173.173.116 list=whatsapp_list
add address=184.173.179.32/27 list=whatsapp_list
add address=185.60.216.53 list=whatsapp_list
add address=185.60.218.53 list=whatsapp_list
add address=185.60.219.53 list=whatsapp_list
add address=192.155.212.192/27 list=whatsapp_list
add address=198.11.193.182/31 list=whatsapp_list
add address=198.11.251.32/27 list=whatsapp_list
add address=198.23.80.0/27 list=whatsapp_list
add address=208.43.115.192/27 list=whatsapp_list
add address=208.43.117.79 list=whatsapp_list
add address=208.43.122.128/27 list=whatsapp_list

# adding firewall rule to block whatsapp address list.

/ip firewall filter
add action=drop chain=forward comment="Block Whatsapp address list" dst-address-list=whatsapp_list

Result:

block whatapp result


Regard’s
Syed Jahanzaib


Filed under: Mikrotik Related

Generating Refill Cards in Radius Manager

$
0
0

On Demand Guide!

Radius manager provides 2 type of Cards system.

  1. Prepaid Cards
  2. Refill Cards [Scratch card]

 

1- Prepaid cards are simpler as they contains username / password , and starts counting expiry/quota after first usage / login from user. they also binds with selected service. This is suitable for environment where users join.leave very frequently, like Cafe’s / restaurants / public hotspot places.

2- Refill cards does not contains any user name or password. they contains only amount, which user can deposit in his account himself by login to the UCP , user control panel and use redeem voucher option). Refill cards are useful if you have more permanent type of clients who renews on monthly basis. Using refill cards, you can providers with liberty to change his service on his own if required. off course he would required higher amount of refill card to renew his new upscale service. but user can do it all on his own if required. so its kind of fully automatic system as well.

Refill cards does not binds with any specific service, they contains only AMOUNT. Once the user add deposit using refill card code, his account wont get auto renewed (although we can use script for it) . He have to activate the service as well after depositing amount. So in short user have to perform 2 steps in order to renew his account. Using refill cards, you just have to only sell cards to user, rest user will maintain on his own.

Example:

We have created a service with 1mb speed, 15gb quota & 30 days expiry limit. We want to create refill cards so that we sell refill card to user, and user will renew his account by using the portal.

Service Example:

2- services


To create refill cards, Goto Card System / Generate Cards

1- refill card menu

 

3- refill generation process

To view these generated cards, Goto Cards System  / List Refill Cards

view refill

As you can see in above screenshot, it have generated cards. You can view it in CSV which will contains cards details in the text format (for local customized card printing in bulk), and if you click on PDF button, it will show you cards in ready to print format using PDF viewer As showed in the image below

refill card in pdf

Now you can sell this card to users and they can use it from there user panel called UCP.


Using REFILL card to renew account.

From user end, login to user portal, and you will see something like this for new / expired user

1- user.PNG

As we can see that user account is in expired state, to renew it ,

Goto REDEEM VOUCHER & enter the code of refill card.

2- refill number

Once submit, it will add 100 Rs deposit in user account. Goto HOME tab and you will see following

deposite

Notice that now user have 100 rs in DEPOSIT but the account is still in EXPIRED status. We will use this deposit amount to renew / activate the account.

Goto Purchase credits, and select 1 in AMOUNT field. As showed in the image below …

1- purchase credits

 

2- refill done

 

3- refill done

Go back to HOME tabe

4- done

Account is now active, and user can login by hotspot / ppp or whatever auth method you have in your mikrotik or other NAS.

You can also refill cards by sending SMS to the radius system connected gsm modem. You will be requiring KANNEL along with Play SMS as well. I shared the idea here.

https://aacable.wordpress.com/2015/05/25/sharing-ideas-renew-expired-user-account-via-sms-in-dmasoftlab-radius-manager/

reill-with-no-quota-showing-it


 

Done.

 


Filed under: Radius Manager

Quick Notes on moving MySQL database(s) directory to New Partition

$
0
0

moving

Following are short notes on how you can move mysql db directory to another partition.

Background:

Our Government base telecom authority called PTA (in PK) regularly issues letter to local ISP’s asking them to keep user traffic data for period of minimum one year.

As showed here (Thanks to Mr. Khalid for providing this notice copy)

pta letter

We know that almost all small scale ISP are natting there users by using local dsl or other medium bandwidth, and keeping private IP data traffic is (almost) useless because finding any thing from such data is like finding a needle in the haystack. If OP is assigning users with public ip, then OP should record users public ip assignment only like showed here, but as private natted IP are still being used therefore OP should save users traffic as per law despite of it will almost useless in practical)

In general we can log user traffic by using mikrotik own small scale web proxy, or adding external proxy like SQUID and route all traffic to squid proxy and keep logs there.

But if you are using Radius Manager, we have option of CONNECTION TRACKING. Using this method, we can track all users connection in mysql DB.

c1

c2

Connection Tracking requires lot of disk space for local ISP. Recently I recommend many OP to use SSD disk as SSD disks are more reliable , long life & offer fast disk access with minimal latency, but as SSD are costly therefore as alternative, we can add secondary disk for mysql like 2.TB and move our MySQL DB in this drive, rest OS or RM will operate from our primary SSD.


Scenario:

We have 2 disk in system as follows

  1. 128 GB SSD [Ubuntu 12.4 installed along with radius manager 4.1.5]
  2. 2 TB SATA Disk [Empty & Mounted as /2tb, howto mount disk read this ]

So our requirement is to move MySQL DB to this 2 TB disk.


Quick Cmd’s …

First login to MySQL and see your current Data Directory location.


mysql> select @@datadir;
+-------------+
| @@datadir |
+-------------+
| /var/lib/mysql |
+-------------+
1 row in set (0.00 sec)

Now we need to move this folder to our new 2tb. Follow below ,,,


Stop MySQL Service & Moves files to 2 TB Disk

sudo service mysql stop

Copy mysql DB Data directory to our 2tb disk with permissions intact, this part is crucial, pay attention to this section. We will use RSYNC to have same permission level in new folder.

sudo rsync -av /var/lib/mysql /2tb/

Rename current MySQL DB directory /var/lib/mysql to .bak [for backup purposes so that in case any thing goes wrong , we still have this restore point]

sudo mv /var/lib/mysql /var/lib/mysql.bak

Change PATH in MySQL INF file

Edit mysql inf file to change the DB directory

sudo nano /etc/mysql/my.cnf

in this file, find DATADIR line and change the old path to new one As showed below …

datadir = /2tb/mysql

Save & Exit


Apparmor Section [for Ubuntu OS]:

Allow new folder in APPARMOR (if you will skip this, you will get access / permission  errors)

sudo nano /etc/apparmor.d/tunables/alias

at the bottom add this line

alias /var/lib/mysql/ -> /2tb/mysql/,

Save n Exit.

It’s also recommended to disable SELINUX.


Start MySQL & Test

Now start the mysql service

service mysql start

& if all ok you may see following …

mysql start/running, process 1881

further verify it with process check

root@radius:~# ps aux |grep mysql
mysql 1881 0.1 3.9 328928 40536 ? Ssl 16:09 0:00 /usr/sbin/mysqld

Login to my mysql and verify all db/tables showing ok


root@radius:~# mysql -uroot -pMYSQLPASSWORD
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 964
Server version: 5.5.54-0ubuntu0.12.04.1 (Ubuntu)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select @@datadir;
+-------------+
| @@datadir |
+-------------+
| /2tb/mysql/ |
+-------------+
1 row in set (0.00 sec)

mysql>

🙂


Regard’s
Syed Jahanzaib


Filed under: Linux Related

Expanding Guest IDE disk in ESXI

$
0
0

We are using VMWARE Esxi 5.0 server hosting few VM guests. One of our guest machine which is acting as proxy/filter system (Forefront TMG 2010 ) for our users, its  disk space was getting lower (as its total size was 60 GB only). I installed this TMG in year 2012 & I was missing its patches / service packs therefore I was avoiding doing fresh installation. As per Vmware documentation, you cannot increase IDE disk size.

disk_not_increasing


I tried another workaround but for some reasons, it didn’t worked in my case.
I used below workaround & it worked perfectly for me.

  • Power OFF the Target guest VM.
  • Login to ESXI Server via putty or any SSH client.
  • Navigate to folder where your guest VMDK file reside,
  • e.g: /vmfs/volumes/XXXXX/Guestname
  • Note down the .vmdk file name & issue expand command against that file
vmkfstools -X 200G TMG.VMDK

-X = expand
200G = size to increase (total size)
TMG.VMDK = File name which we want to expand

As showed in the image below …

1- space added

Depends on your hardware speed, it may take some time to complete the operation. I had some good IBM hardware & it took around 1-2 minutes to increase the size from 60GB to 200GB.

After few minutes it will populate to ESXI client automatically.

Now power ON the guest machine, and increase the size as required , either using Windwos Disk Management tool or cmd. I used MiniTool Partition Wizard Server Edition 7.1 which worked beautifully to complete the task without any hassle.

Below is Image after the task finished.

2- space added. final snap

 

 


Filed under: Forefront TMG 2010 Related

Mikrotik script to monitor local device with optional SMS alert

$
0
0

Note to Self:

Following is a simple script I made to monitor local device & upon status change, it will send SMS only. It was customized according to local requirements. You can refine at , add remove any option as per taste. There are lot of good working scripts available on the internet. Just try not to blindly copy paste any one else script. Read it many times until you understand clearly what its made for & what functions it will perform. I have added some comments for the clarity.

Script, Script, Why use Script ?

Why use such complicated scripts while you can do this easily with builtin net-watch or windows base applications like the Dude, or Nix base Nagios, and so many other tools? the answer is simple, using script you have more Power, more control, more maneuverability , customized bizarre and strange actions you can take. Above all, Learning & feeling of Power you have over the system 🙂 this alone justification is enough for me to use scripting 🙂

Thank you
~Syed Jahanzaib~


Script Output Examples:

When Device is DOWN …

1- deviec down

.

When Device is UP (restored) …

2- deviec up

.

Example of SMS received:

2017-07-26 13.44.01


the Script !


# This is Mikrotik Script for Local Device Link monitoring by IP
# - with Optional SMS Alert. We are using local Linux base KANNEL
# You can modify it to add EMAIL alerts as well using GMAIL or local Mail Gw.
# system as SMS gateway with local modem attached
# Script By Syed Jahanzaib / # https://aacable.wordpress.com
# Email : aacable at hotmail dot com
# Script Last Modified : 26-July-2017

# Set Device IP here
:global DEVICE1host1 "10.0.0.8"

#:log warning "Checking status of Ubnt Device $DEVICE1host1 by ping ..."

:local i 0;
:local F 0;
:local date;
:local time;
:set date [/system clock get date];
:set time [/system clock get time];

:global DEVICE1LanStatus;
:global DEVICE1LanLastChange;

# Company Name, Dont use SPACEC Here, because our KANNEL system dont liek spaces, use + sign instead
:local COMPANY "ZABBO"
# Dont use SPACEC Here, because our KANNEL system dont liek spaces, use + sign instead
:local DEVNAME "MailServer"

# Setting Date Time variables
:local sub1 ([/system identity get name])
:local sub2 ([/system clock get date])
:local sub3 ([/system clock get time])

# Number of Ping Count, how many times mikrotik should ping the target device
:local PINGCOUNT "5"
# Ping threshold
:local PINGTS "5"

# Provide details of Kannel SMS gateway, ID pass, and cell numbers on which sms is required
:local KURL "http://KANNEL-GW-IP-OR-NAME:13013/cgi-bin/sendsms"
:local KID "kannel"
:local KPASS "KANNELPASS"
:local cell1 "03333021909"

# SMS Msg format for Kannel SMS gateway (donot use spaces in it)
:local MSGDOWNSMS "$COMPANY+ALERT:%0A$DEVNAME%0A$DEVICE1host1+is+now+DOWN."
:local MSGUPSMS "$COMPANY+INFO:%0A$DEVNAME%0A$DEVICE1host1+is+now+UP."

# LOG error
:local DOWNLOG1 "$COMPANY ALERT: $DEVNAME with IP $DEVICE1host1 is now DOWN ..."
:local UPLOG1 "$COMPANY INFO: $DEVNAME with IP $DEVICE1host1 is now UP ..."

# Start the SCRIPT
# DONOT EDIT BELOW

# If Script is running for the first time , consider target device UP,
# Just to avoid any errors in the script dueto empty variable.
:if ([:len $DEVICE1LanStatus] = 0) do={
:set DEVICE1LanStatus "UP";
}

# PING each host $PINGCOUNT times
# IF NOT A SINGLE PING SUCCESSFULL THEN CONSIDER LINK DOWN ## ZAIB
:for i from=1 to=$PINGCOUNT do={
if ([/ping $DEVICE1host1 count=1]=0) do={:set F ($F + 1)}
:delay 1;
};

# If no response (all ping counts fails for both hosts, Time out, then LOG down status and take action
:if (($F=$PINGTS)) do={
:if (($DEVICE1LanStatus="UP")) do={

# If the link is down, then LOG warning in Mikrotik LOG window [Zaib]
:log error "$DOWNLOG1";
:set DEVICE1LanStatus "DOWN";
# Also add status in global variables to be used as tracking
:set date [/system clock get date];
:set time [/system clock get time];
:set DEVICE1LanLastChange ($time . " " . $date);
# Send SMS via KANNEL for DOWN Status
:log warning "Sending SMS for DOWN status of $DEVNAME $DEVICE1host1 ..."
/tool fetch url="$KURL\?username=$KID&password=$KPASS&to=$cell1&text=$MSGDOWNSMS"

# If ping reply received, then LOG UP and take action as required
} else={:set DEVICE1LanStatus "DOWN";}
} else={
:if (($DEVICE1LanStatus="DOWN")) do={
# If link is UP, then LOG info and warning in Mikrotik LOG window [Zaib]
:log warning "$UPLOG1"
:set DEVICE1LanStatus "UP";

# Send SMS via KANNEL for UP Status
:log warning "Sending SMS for UP status of $DEVNAME $DEVICE1host1 ..."
/tool fetch url="$KURL\?username=$KID&password=$KPASS&to=$cell1&text=$MSGUPSMS"
:set date [/system clock get date];
:set time [/system clock get time];
:set DEVICE1LanLastChange ($time . " " . $date);

} else={:set DEVICE1LanStatus "UP";}
}

# Script ends here ...


Filed under: Mikrotik Related

Playing with the `radpostauth` table in Freeradius

$
0
0

Freeradius is a well known billing system which is commonly used by ISP’s worldwide due to its reliability,  highly customizable and versatility. Many 3rd party vendors have made some good GUI fronted to manage the FR back-end engine.

It also sues mysql to facilitate logging of various users details. One of the table called radpsotauth which can hold information about users successfull/failed login attempts. Using this table, we can compliment our own GUI or 3rd party fronted (for easy management of freeradius engine) like DMASoftlab radius manager Authentication Log section so that admin / support can see users authentication logs. With some modification we can add useful information for quick troubleshooting example why user denied the authentication request, either invalid mac, wrong password, or account expired.

Note to *.*

  • You can add UNLAG query as well to apply IF statement, and add REPLY result according to your requirements.
  • This post was written for some reference purposes & will be updated as per request.
  • This guide is incomplete post. But it can be used as a reference as well for future retrieval

Example:

showing auth logs with errors numbers.JPG

As we can see in above image that in Radius Reply column, it clearly showing why user is denied like invalid mac address , account expires, invalid service reference (when user account id disabled in dma).

To enable these features we have to perform few steps as following …

 


RADDB DEFAULT CONFIG

First we need to edit the default sites config file for raddb.

Edit following file

nano /usr/local/etc/raddb/sites-available/default

Now search for “post-auth {” section

To make it simple and copy-paste format, Use following


post-auth {
sqlippool
reply_log
exec
sql
Post-Auth-Type REJECT {
sql
attr_filter.access_reject
}
}

As showed in the image below …

psot-auth section

Save & Exit.


#DIALUP.CONF Section

Edit the post-auth section in /usr/local/etc/raddb/sql/mysql/dialup.conf file

At the end of this file you will see “postauth_query” section. You need to change it

Old post-auth query

old-dialup

After changing

new-dialup

or copy paste text as below…


#######################################################################
# Authentication Logging Queries
#######################################################################
# postauth_query - Insert some info after authentication
#######################################################################

postauth_query = "INSERT INTO ${postauth_table} \
(username, pass, reply, authdate, nasipaddress, mac) \
VALUES ( \
'%{User-Name}', \
'%{%{User-Password}:-%{Chap-Password}}', \
'%{reply:Packet-Type} - %{reply:Reply-Message}', \
'%S', \
'%{NAS-IP-Address}', \
'%{Calling-Station-Id}')"

Save & Exit.


#Alter the RADPOSTAUTH table using mysql cmd …

Using mysql cmd, we will perform 2 functions

  1. Increase the REPLY column length to accommodate longer reply messages display properly
  2. Add the MAC Address column so we can detect the calling user device mac address
mysql -uroot -pPASSWORD
use radius;
ALTER TABLE radpostauth MODIFY `reply` VARCHAR( 100 );
ALTER TABLE radpostauth ADD COLUMN mac TEXT;
exit

Restart the RADIUSD service

service radiusd restart

using CMD, you can now see the authentication log table

mysql -uroot -pPASSWORD -e “use radius; select * from radpostauth;”

& you will see the information

phpmyadmin query for table

1 JOHN     123456     Access-Reject - The account has expired=21      2017-08-15 [14:14:05       192.168.1.1         10:FE:ED:33:BD:AX

Notes:

  • You can modify the messages appearing in the different columns, you can add your own customized columns as well like called station, or others
  • You can add UNLAG query as well to apply IF statement, and add REPLY result according to your requirements.
  • It can chew up your disk space, so try to make text shortest possible, like error codes only, not the whole text.
  • scheduled a cron job so that it can empty the table on weekly/monthly basis so that it may not swallow disk space plus performance should remain optimal.
  • If used in heavy environment it can put considerable strain on your system resources by putting large quantity of mysql INSERT queries into the table.

 

 


Regard’s
Syed Jahanzaib

 


Filed under: Radius Manager

IBM Lotus Domino: Layman’s approach to move Archive’s to new partition

$
0
0

bg_domino2


Scenario:

We are using IBM’s Lotus Domino 8.x on Windows 2008 R2 with following folders structure.

  • D:\LOTUS\DOMINO\DATA\MAIL   > 500 GB , users inbox
  • D:\LOTUS\DOMINO\DATA\MAIL\ARCHIVE > 1000 GB , users archived mails

Archiving policy is enabled on the server-end which runs on a weekly basis, It moves One year old email from the inbox folder to ARCHIVE folder with a_username structure. Disk Space was getting low in D: partition therefore I had added new drive (E:) and wanted to move user ARCHIVE(s) to new partition E:\ARCHIVE

There were few solutions to perform the operation, Online & Offline.

With Online approach we could use the Domino’s builtin MOVE operation (via domino admin client) in which we dont have to take any shutdown, but then we would need to get the timing right. If the mailfiles are not moved into the new folder before our  scheduled , server archive runs then new archive files will be created which may complicate things.

But since I was able to afford 2 hours down time I took the OS cut/paste option.


I did following

  1. Quit the Domino via Admin Client, then Stop the Domino Services via SERVICES.
  2. Moved (Cut n Paste) ARCHIVE folder from D to E: drive (e:\archive2 folder)
  3. In D:\LOTUS\DOMINO\DATA\MAIL folder , I created a text file called ARCHIVE.DIR
    In text file put I added path E:\ARCHIVE).
  4. Start Domino Server service (Or better to restart the server).

& all went fine.

I am big fan of Domino’s own MOVE operation, but after few months, I will be replacing this machine with new server, then it would be a problem to move the archives again. there fore above Operation was a good choice from Layman’s management perspective 🙂

Hope it will help someone with same situation.


Regard's
~Syed Jahanzaib~

Filed under: IBM Related

IBM v3700 – Noisy PSU Problem

$
0
0

v3700-full

 

v3700-d


We have IBM v3700 SAN system along with expansion unit as well. From past 2 weeks, there was loud noise generating from the SAN PSU like its running on full capacity. After some research it was found out that its a known bug in the v3700 series SAN and following actions should be taken to sort it.

  1. If you have IBM warranty/SLA, call the support, they will rectify the issue as IBM support is very good & quick in most cases. MAke sure you get the San Machine Type / Serial numbers before calling.

If you are managing the SAN on your own, then follow these instructions

  1. The first thing to try is to ‘reseat the PSU cable’ of the PSU that is running high.
  2. If reseating the cable did not work, try reseating the PSU. After a few seconds, then fan speed should start to fall.
  3. Make sure you are running the latest firmware. I was running 7.1.0.5 (build 80.4.1309270000) that was very old (as of Sep,2017). A fix for this issue has been included from code level 7.6 onward. This fix works for V3700, V5000 and V7000 Gen2 so an upgrade will fix the problem. The new firmware is 7.8 as of current date.
  4. Finally the issue should be resolved by resetting the entire canister. Connect to the SAN controller using PUTTY, & issue following command [This point#3 solved my problem]

chenclosurecanister -reset -canister <can> <encl>

You need to find out which canister PSU is making noise. Example

chenclosurecanister -reset -canister 1 1

If you have additional canister, then you may use (wait half hour before applying command to 2nd canister)

chenclosurecanister -reset -canister 2 1

As showed in below image …

v3700 commands.JPG

Wait for few minutes & the PSU sound should come back to normal.

Regard’s
Syed Jahanzaib

 


Filed under: IBM Related

Safest method to clean /boot partition

$
0
0

Today morning ,when I tried to upgrade one of remote Ubuntu kernel I received error stating that /boot partition is full.

If your /boot partition usage goes to 100% (or near about) as showed in the image below, then its a good idea to make some room in in order to perform kernel upgrade.

boot part full.JPG

Usually one of safest method is as below …


Note: in this post, I am using Ubuntu 12.4 / 32 bit version.

First check the current kernel version

uname -r

This will show you the current kernel version like below …

root@radius:~# uname -r
3.13.0-112-generic

As we can see that its 3.13.0-112-generic, make a note of it

Now run this command for a list of installed kernels:

dpkg --list 'linux-image*'

This will show you the current & all previous versions of kernels, like below …

kernel list.JPG

just delete the old kernels (marked in red) that we dont require anymore. Use following command

sudo apt-get remove linux-image-VERSION

Replace VERSION with the version of the kernel you want to remove.

WARNING: Make sure you dont delete the current running kernel (number acquired by uname -r command)

Once you are done removing all old kernels, issue following command

sudo apt-get autoremove

And finally run this to update grub kernel list

sudo update-grub

Done.

space after removal.JPG


Regard’s
Syed Jahanzaib


Filed under: Linux Related

Restart ppp dialer if getting ‘Private IP’

$
0
0

Reference Post:

Following is short script to reconnect PPPoE dialer if it receives any private IP from the ISP including 10.x.x.x / 172.x.x.x & 192.x.x.x series.

reconnect-with-spouse


# Script to find if wan link have private ip and act accordingly,
# Tested with Mikrotik ROS 5.x & 6.x versions
# 19-APR-2016 / Syed Jahanzaib

# Set your WAN Interface name , i have added pppoe-out1 , change it as required
:local WANINTERFACE
:set WANINTERFACE pppoe-out1

# Find Public IP from pppoe-out1 interface & cut subnet
:local WANIP [/ip address get [find where interface=$WANINTERFACE] address];
:set WANIP [:pick $WANIP 0 ([:len $WANIP]-3) ];

# Match if IP address starts with private address 10.*
:if ($WANIP ~"^[0-9 ]*10") do={
:log warning "Private ip address found !!!"
# Set your action here , like Re-Connect the pppoe-link
# /interface pppoe-client disable pppoe-out-1
# :delay 3
# /interface pppoe-client enable pppoe-out-1
} else={

# Match if IP address starts with private address 172.*
:if ($WANIP ~"^[0-9 ]*172") do={
:log warning "Private ip address found !!!"
# Set your action here , like Re-Connect the pppoe-link
# /interface pppoe-client disable pppoe-out-1
# :delay 3
# /interface pppoe-client enable pppoe-out-1
} else={

# Match if IP address starts with private address 192.*
:if ($WANIP ~"^[0-9 ]*192") do={
:log warning "Private ip address found !!!"
# Set your action here , like Re-Connect the pppoe-link
# /interface pppoe-client disable pppoe-out-1
# :delay 3
# /interface pppoe-client enable pppoe-out-1
} else={

# If above statement do not match, then consider it a public ip and take no action, just log : ~ )
:log warning "Public IP - $WANIP - Found, OK ! No action required"
# OR Set your desire action here if required
}
}
}
# Script Ends Here ...


Reference: https://forum.mikrotik.com/viewtopic.php?t=107231

Regard’s
Syed Jahanzaib


Filed under: Mikrotik Related

Mikrotik with Cisco Inter-Vlan Routing

$
0
0

overload

Disclaimer:
I donot have professional level expertise with the mikrotik & specially Cisco. It’s just personnel R&D that sometimes leads me to a working solution. After posting on the internet, I got some clues & Alhamdoillah it worked !


Scenario: [example]

OP have mini ISP setup. Different areas are connected with Cisco 3750 switch where Vlan(s) for each port is configured. Trunk port is connected with Mikrotik Routerboard where vlan interfaces are configured accordingly. DHCP for each VLAN is configured on the Mikrotik RB which provides different subnet to each vlan with default gateway pointing to each VLAN IP.

PPPoE Server is configured on the RB to facilitate ppp dialing for each vlan. As per policy, user must dial pppoe dialer to connect with the mikrotik PPP server in order to access internet.


Problem:

OP have few media sharing server located on Vlan No 3. When user starts downloading heavy media files from the Vlan No 3, all of his traffic routes via Mikrotik Router which creates load on router.


Solution # 1: [that worked partially]

After some R&D, I implemented following

  • Moved DHCP role to Cisco
  • Setup intervlan routing. enabled ip routing
  • Added default gateway in DHCP options pointing to Cisco local vlan ip respectively

This partially solves the problem. When user join the LAN, he gets IP address from the Cisco dhcp with default gateway to its respective vlan IP. all goes well , communication was happening fine with in vlan without touching the Mikrotik. But as soon as users dial the PPPOE dialer, his traffic starts routing via Mikrotik . after some troubleshooting it appears that when user dials pppoe dialer, his routes changes and ppp gets preference over other routes which force all traffic to go via RB.

As showed in the image below …

Load on Trunk Port when ppp user download from vlan no 3

 

routes and ipconfig of client before dhcp option


Solution # 2: [worked 100% as required]

In Cisco Switch DHCP settings for each vlan, Remove Default Gateway,  and add static routes for the sharing media servers subnet via using DHCP classless static routes option

Sounds fair enough :~)


Working Example Config for Cisco Switch 3750

# Cisco Switch Part

[Model: ws-c3750e-24pd / Version 15.0(2)SE10a ]


!
system mtu routing 1500
ip routing
!
ip dhcp pool vlan2
network 192.168.2.0 255.255.255.0
dns-server 101.11.11.36
option 121 ip 24.192.168.3 192.168.2.1 ## This option provides route information , /24.x is the subnet info and other is gw
!
ip dhcp pool vlan3
network 192.168.3.0 255.255.255.0 ## This is media server vlan, we have added manual ip & gateway pointing to vlan ip 192.168.3.0
!
ip dhcp pool vlan4
network 192.168.4.0 255.255.255.0
option 121 ip 24.192.168.3 192.168.4.1 ## This option provides route information , /24.x is the subnet info and other is gw
!

! This port is connected with the Mikrotik RB
interface GigabitEthernet1/0/1
switchport trunk encapsulation dot1q
switchport mode trunk

! This port is connected with user area 2
interface GigabitEthernet1/0/2
switchport access vlan 2
switchport mode access

! This port is connected with local FTP/Media sharing server's
interface GigabitEthernet1/0/3
switchport access vlan 3
switchport mode access

!This port is connected with user area 4
interface GigabitEthernet1/0/4
switchport access vlan 4
switchport mode access
!
interface Vlan1
ip address 192.168.254.1 255.255.255.0
!
interface Vlan2
ip address 192.168.2.1 255.255.255.0
!
interface Vlan3
ip address 192.168.3.1 255.255.255.0
!
interface Vlan4
ip address 192.168.4.1 255.255.255.0
! Following route is pointing to Mikrotik RB
ip route 0.0.0.0 0.0.0.0 192.168.254.2
!

# Mikrotik Routerboard Part


/interface ethernet

set [ find default-name=ether1 ] name=LAN-TRUNK

/interface vlan
add interface=LAN-TRUNK name=vlan2 vlan-id=2
add interface=LAN-TRUNK name=vlan3 vlan-id=3
add interface=LAN-TRUNK name=vlan4 vlan-id=4

# It is recommended to use small subnet, like /29 for below (zaib)
/ip address
add address=192.168.254.2/24 interface=LAN-TRUNK network=192.168.254.0

/interface pppoe-server server
add default-profile=pppoe-profile disabled=no interface=vlan2 max-mru=1480 max-mtu=1480 mrru=1600 one-session-per-host=yes service-name=service2
add default-profile=pppoe-profile disabled=no interface=vlan3 max-mru=1480 max-mtu=1480 mrru=1600 one-session-per-host=yes service-name=service3
add default-profile=pppoe-profile disabled=no interface=vlan4 max-mru=1480 max-mtu=1480 mrru=1600 one-session-per-host=yes service-name=service4

# FTP / Media Sharing Server Part

at your FTP server, which is under vlan no 3, define static ip like 192.168.3.2 and point its gateway to 192.168.3.1, That’s It 🙂

Results are showed as below …

 

client ROUTEs and ipconfig AFTER DHCP OPTIOIN

 

download gpoign via vlan only after addding dhcp option

 

no load on mikrotik router and local vlan download going via local vlan

 


 

Note:

I have posted minimalist configuration to reduce any complication. Most of parts are quite self explanatory. This exercise was done successfully in LAB & required results were achieved. However you must consult with some Cisco expert & conduct your own testing  before implementing it on production.

Also you may want to use ACL in order to restrict access to shared resources, YKWIM


Regard’s
Syed Jahanzaib

 


Filed under: Cisco Related, Mikrotik Related

Daily report for backup folder via email

$
0
0

This is just for my personnel reference, If you like to use it, just modify whatever is required.

I made this script to get a daily report for support staff so that they can monitor if backup’s are being performed properly & regularly. The backup scheduler make backup after every 2 hours. so there should be 12 backup files in /backup folder per day. This script just query them. I used somewhat some unusual method to acquire the files date, BUT there are other proper methods to get the same , dueto some urgency i just made whatever worked for me. Will update it if any changes will be required.


the Script !

mkdir /temp
touch /temp/bkpreport.sh
chmod +x  /temp/bkpreport.sh
nano /temp/bkpreport.sh

& paste following …


#!/bin/bash
# This bash script is made to send report for files that were created in /backup folder by another scheduler
# I made this to ensure that backups are done properly with automated reports including some other system level information.
# 12-DEC-2017
# Syed Jahanzaib / aacable @ hotmail . com
# https://aacable . wordpress . com
#set -x

#MYSQL Related Details
HOSTNAME=`hostname`
MYSQLID="root"
MYSQLPASS="SQLPASS"
SQL_ACCOUNTING_TABLE="radacct"
GMAILID="YOURGMAIL@gmail.com"
GMAILPASS="GMAILPASS"
ADMINMAIL1="TO1@hotmail.com"
COMPANY="ZAIB Ltd."
#GMAILS MTP
SMTP="64.233.184.108:587"

# Script will search this folder for the files
BKPFOLDER="/backup"
MAILFILE="/tmp/bkpdir.log"
#Set Human Friendly Date Format for yesterday & Display
DATE=`date`
TODAY=`date +"%d-%b-%Y"`
YESTERDAY=`date +"%d-%b-%Y" -d '-1 days'`
MAILSUB="$COMPANY RADIUS Backup Rerport for $YESTERDAY"
# Count number of files
LIST=`ls -lh $BKPFOLDER --time-style=+"%d-%b-%Y" |grep $YESTERDAY`
TOTFILES=`ls -lh $BKPFOLDER --time-style=+"%d-%b-%Y" |grep $YESTERDAY |wc -l`

# disk we want to monitor, make sure to change this
# You need to adjust this , to match your drive, use df -h & modify this
DISK="/dev/mapper/vg_myradius-lv_home"

# Get DB size in MB
MYSQLDBSIZE=`mysql -u$MYSQLID -p$MYSQLPASS --skip-column-names -e "SELECT table_schema "radius", sum(data_length + index_length)/1024/1024 FROM information_schema.TABLES WHERE table_schema='radius' GROUP BY table_schema;" | cut -f1 -d"." | sed 's/[^0-9]*//g'`
DISKTOT=`df -h $DISK |awk '{print $2}'| sed -n 3p`
DISKUSED=`df -h $DISK |awk '{print $3}'| sed -n 3p`
DISKAVA=`df -h $DISK |awk '{print $4}'| sed -n 3p`
DISKUSEPER=`df -h $DISK |awk '{print $5}'| sed -n 3p`
MEMTOT=`free -m |awk '{print $2}'| sed -n 2p`
MEMUSED=`free -m |awk '{print $3}'| sed -n 2p`
MEMAVA=`free -m |awk '{print $4}'| sed -n 2p`
MEMUSEDPER=`free -m | grep Mem | awk '{print $3/$2 * 100.0}'`
MEMAVAPER=`free -m | grep Mem | awk '{print $4/$2 * 100.0}'`
IPADD=`ifconfig | awk -v RS="\n\n" '{ for (i=1; i<=NF; i++) if ($i == "inet" && $(i+1) ~ /^addr:/) address = substr($(i+1), 6); if (address != "127.0.0.1") printf "%s\t%s\n", $1, address }'`
SESSIONS=`mysql -u$MYSQLID -p$MYSQLPASS --skip-column-names -e "use radius; SELECT username FROM $SQL_ACCOUNTING_TABLE WHERE acctstoptime IS NULL;" |wc -l`
FOOTER="This automated report is generated on $DATE
Powered by $COMPANY
Coding by Syed.Jahanzaib / aacable at hotmail dot com"

echo "Daily report for $HOSTNAME System @ COMPANY.

$TOTFILES backup sets were made with intervale of 2 hours on $YESTERDAY

List of files that were backuped $YESTERDAY...

$LIST

OTHER DETAILS: JUST FYI,

===============
NETWORK DETAILS:
===============
Hostname = $HOSTNAME
Network IP Details
$IPADD

==========================
RADIUS SERVER MYSQL REPORT:
==========================
MYSQL 'RADIUS' DB SIZE = $MYSQLDBSIZE MB
RADIUS Online Users = $SESSIONS Users / [at the time of this script running, generaly 00:00 Hours / Midnight]

====================
DIS / STORAGE REPORT:
====================
Total Disk Space = $DISKTOT
Total Disk Space Used = $DISKUSED
Total Disk Space Available = $DISKAVA
Total Disk Space = $DISKUSEPER

==============
MEMORY REPORT:
==============
Total RAM = $MEMTOT MB
Total RAM Used = $MEMUSED MB
Total RAM Available = $MEMAVA MB
Total RAM Used Percent = $MEMUSEDPER %
Total RAM Available Percent = $MEMAVAPER %

$FOOTER" >$MAILFILE

#Display Results in terminal
cat $MAILFILE

# Send results via email to $ADMINMAIL1
sendemail -t $GMAILID -u "$MAILSUB" -o tls=yes -s $SMTP -t $ADMINMAIL1 -xu $GMAILID -xp $GMAILPASS -f $GMAILID -o message-file=$MAILFILE -o message-content-type=text

Sample Email !

Click to enlarge

Regard’s
Syed Jahanzaib

Freeradius External Authentication Script & log reject request only in radpostauth with customized REPLY message

$
0
0

FreeRadius Core info

  1. FREERADIUS WITH MIKROTIK – Part #1
  2. FREERADIUS WITH MIKROTIK – Part #2 
  3. FREERADIUS WITH MIKROTIK – Part #3
  4. FREERADIUS WITH MIKROTIK – Part #4
  5. FREERADIUS WITH MIKROTIK – Part #5
  6. FREERADIUS EXTERNAL AUTH SCRIPT & RADPOSTAUTH – Part #6 >>> YOU ARE HERE

Note: This post is for reference purposes only. This post may change rapidly as at the time of writing , frequent changes are being made to adjust many parameters to fulfill local OP requirements. So you may see some display text difference as compared in the code itself … worry not 🙂 Just read and Enjoy, Pick your desired section.

Also you may want to read this reply came from ALAN (freeradius) when I asked on external auth script.

FreeRadius users mailing list (freeradius-users@lists.freeradius.org)

________________________________
From: Freeradius-Users <freeradius-users-bounces+aacable=hotmail.com@lists.freeradius.org> on behalf of Alan DeKok <aland@deployingradius.com>
Sent: Saturday, January 13, 2018 8:30:02 PM
To: FreeRadius users mailing list
Subject: Re: External Auth Script or local Auth

On Jan 13, 2018, at 8:40 AM, JAHANZAIB SYED <aacable@hotmail.com> wrote:
> I am using Freeradius ver 2.1.10

You should upgrade to 2.2.10. There’s just no reason to use a version which is almost 10 years old

> I have noticed that some commercial radius servers (with freeradius backend) using External script (php/perl or C code) to authenticate users. I just wanted to know that what are the additional benefits of using external auth script over freeradius own authentication (via rad-groups) ?

So that they can avoid GPL licensing issues.

> I made my own bash script that runs fine for authentication by checking user status in my_users table like expiry, disable/enable, quota, uptime etc , but for heavy load network like 20-30k users, what is recommended?

Use the features in FreeRADIUS. They work. They’re also MUCH faster than forking an external program.

i.e. FreeRADIUS can do 10’s of 1000’s of DB queries per second, and 10’s of 1000’s of authentications per second. When you use shell script, that number can drop by 10x to 100x.

On top of that, why re-implement features which already work? It doesn’t make any sense to write a shell script to do something, when FreeRADIUS can already do it.
Most people who are re-packaging FreeRADIUS are figuring this out. Some have taken the source, and hacked it up… at which point they have their own magic server that no one understands.
And a few years later, FreeRADIUS has more / better features than their hacked-up version, and they can no longer sell decent features to their customers.

Alan DeKok.

z@ib

Following is an BASH script which we can use to authenticate users in freeradius. Using external auth script have several benefits over traditional attributes. Example we can provide NAS with radreply based on various attributes in users table like expiration, quota, disabled/expired users & other crazy stuff 🙂

It took many hours for a duffer like me to accomplish this task. Some says BASH is not suitable for servers under heavy load, therefore you may look for C/C++ approach for faster fetching results. I have tested this with 1000 + loop auth requests & it worked fine without putting any load on the server & without any invalid  or missing any single request !

Regard’s
Syed Jahanzaib


Scenario:

  • OS: Ubuntu 12.4 Server Edition
  • FreeRADIUS Version 2.1.10, for host i686-pc-linux-gnu
  • Mysql Ver 14.14 Distrib 5.5.54, for debian-linux-gnu (i686) using readline 6.2

>>> OP Requirements :

  1. If users not found, It should display error message in debug log & REJECT user request
  2. If user password does not match with the radcheck table entry, REJECT the user request
  3. If user is Disabled by OP, let him login with disabled-pool (for redirection purposes)
  4. If user is Expired, let him login with expired-pool (for redirection purposes)
  5. If user is logged in for the first time, his MAC should update in USERS table for AUTO MAC Binding purposes. So only this device should be able to connect in future
  6. If user try to login from other device, let him login with invalidmac-pool (for redirection purposes)
  7. Check for Over Quota users (not required at a moment)
  8. LOG requests in mysql RADPOSTAUTH table for REJECT actions

So in short we donot want to REJECT user login request if it matches above criteria.

Yes I know its a kind of weird stuff, but still its good for learning !

>>> Mysqle ‘USERS’ Table example

In mysql we have following users table [Just an example, its not fine tuned]

#### USERS TABLE
root@testradius:/temp# mysql -uroot -pROOTPASS -e "use radius; describe users;"
+------------+---------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+-------------------+-----------------------------+
| id | int(10) | NO | PRI | NULL | auto_increment |
| username | varchar(128) | NO | MUL | NULL | |
| password | varchar(32) | NO | | NULL | |
| firstname | text | NO | | NULL | |
| lastname | text | NO | | NULL | |
| email | text | NO | | NULL | |
| mobile | text | NO | | NULL | |
| cnic | text | NO | | NULL | |
| srvname | text | NO | | NULL | |
| srvid | int(11) | NO | | NULL | |
| expiration | datetime | YES | | NULL | |
| mac | varchar(30) | NO | | NULL | |
| bwpkg | varchar(1000) | NO | | NULL | |
| pool | varchar(128) | YES | | other | |
| enabled | varchar(1) | NO | | NULL | |
| owner | text | NO | | NULL | |
| createdon | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+------------+---------------+------+-----+-------------------+-----------------------------+
17 rows in set (0.00 sec)

root@testradius:/temp# mysql -uroot -pROOTPASS -e "use radius; select * from users;"
+----+----------+----------+----------------+---------------+---------------------+-------------+-------------------+---------+-------+---------------------+-------------------+-------------+----------------------+---------+--------+---------------------+
| id | username | password | firstname | lastname | email | mobile | cnic | srvname | srvid | expiration | mac | bwpkg | pool | enabled | owner | createdon |
+----+----------+----------+----------------+---------------+---------------------+-------------+-------------------+---------+-------+---------------------+-------------------+-------------+----------------------+---------+--------+---------------------+
| 1 | zaib | | syed | jahanzaib | aacableAThotmail.com | 03333021909 | 1234567890-1-1 | | 0 | 2018-12-23 00:00:00 | 00:0C:29:35:F8:2F | 1024k/1024k | public-pool | 1 | galaxy | 2017-12-23 16:25:09 |
| 7 | test | | test firstname | test lastname | test@test.com | 13434234234 | 242342420424-42-2 | | 0 | 2017-12-24 00:00:00 | 00:0C:29:35:F8:2F | 2048k/2048k | public-multinet-pool | 1 | zaib | 2017-12-25 16:27:39 |
+----+----------+----------+----------------+---------------+---------------------+-------------+-------------------+---------+-------+---------------------+-------------------+-------------+----------------------+---------+--------+---------------------+

FREERADIUS config to accommodate external authentication script [auth.sh] execution

We need to add following directives in FR config files in order to execute the bash script for auth purpose once the username/password is found ok by FR.


>>> Edit freeradius/USERS file in FR

nano /etc/freeradius/users

& Add following in the end of this file …

DEFAULT Auth-Type := PAP
Exec-Program-Wait = "/temp/auth.sh %{User-Name} %{User-Password} %{Calling-Station-Id}"

SAVE & EXIT !


>>> Now edit sites-enabled/default file …

nano /etc/freeradius/sites-enabled/default

& use following … [my working sample file, you must modify it as per your requirements]

authorize {
preprocess
chap
pap
mschap
digest
# suffix
# eap {
# ok = return
# }
files
### ZAIB Section-1 Start Here ##
sql{
notfound = 1
}
if(notfound){
update reply {
Reply-Message = 'Username not found'
}
reject
}
### ZAIB Section-1 Ends Here ##
# checkval
# expiration
# logintime
# pap
}

authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
digest
unix
# eap
}

preacct {
preprocess
acct_unique
suffix
files
}

accounting {
detail
unix
radutmp
sql
exec
attr_filter.accounting_response
}

session {
# radutmp
sql
}

### ZAIB Section-2 Start Here ##
post-auth {
exec
Post-Auth-Type REJECT {
update reply {
Reply-Message = 'Wrong Password'
}
sql
attr_filter.access_reject
}
}
### ZAIB Section-2 ENDS Here ##

pre-proxy {
}

post-proxy {
eap
}

SAVE & EXIT !


 


AUTH.SH [bash script as external auth for FR]

Create auth.sh file

  • mkdir /temp
  • touch /temp/auth.sh
  • chmod+x /temp/auth.sh
  • nano /temp/auth.sh

& paste following data [after necessary modifications]

#!/bin/bash
# Bash script for Freeradius / external auth script
# By Syed Jahanzaib / aacable at hotmail dot com
# https://aacable.wordpress.com
# 22-DEC-2017
# Last modified on 27-DEC-2017
# You may want to disable few sections in it like user validation, password validation
# because both are now handled by FR with our custom reply message hurrahhhhh zaib.
#set -x
USERNAME=$1
PASS=$2
MAC=$3
MYSQL_USR="root"
MYSQL_PASS="ROOT-OR-SQL-PASS"
DB="radius"
TBL="users"
MSG=""
USRISVALID=`mysql -u$MYSQL_USR -p$MYSQL_PASS --skip-column-names -s -e "use $DB; select id from $TBL where username ='$USERNAME';" | tr "'" " "`
if [ -z "$USRISVALID" ];then
echo "$USERNAME >>>> User Not Found."
exit 1
fi
CHKPASS=`mysql -u$MYSQL_USR -p$MYSQL_PASS --skip-column-names -s -e "use $DB; select password from users where username='$USERNAME';"`
if [ "$PASS" != "$CHKPASS" ];then
echo "$USERNAME / $PASS >>> Incorrect Password."
exit 1
fi
ENORDIS=`mysql -u$MYSQL_USR -p$MYSQL_PASS -s -e "use $DB; select enabled from $TBL where username ='$USERNAME';" | tail -n 1`
if [ "$ENORDIS" == "0" ];then
echo 'Mikrotik-Rate-Limit="'1k/1k'",Framed-Pool="'disabled-pool'",Session-Timeout="'0'"'
exit 0
fi
CHECKMAC=`mysql -u$MYSQL_USR -p$MYSQL_PASS --skip-column-names -s -e "use $DB; select mac from $TBL where username ='$USERNAME';" | tail -n 1`
if [ -z "$CHECKMAC" ];then
mysql -u$MYSQL_USR -p$MYSQL_PASS -e "use $DB; UPDATE $TBL SET mac ='$MAC' WHERE users.username ='$USERNAME' LIMIT 1;"
fi
if [ "$MAC" != "$CHECKMAC" ];then
echo 'Mikrotik-Rate-Limit="'1k/1k'",Framed-Pool="'invalidmac-pool'",Session-Timeout="'0'"'
exit 0
fi
SECONDS=`mysql -u$MYSQL_USR -p$MYSQL_PASS -s -e "use $DB; select time_to_sec(TIMEDIFF (expiration, NOW() ) ) as secs from users where username ='$USERNAME';" | tail -n 1`
if [ "$SECONDS" -lt 0 ]; then
echo 'Mikrotik-Rate-Limit="'1k/1k'",Framed-Pool="'expired-pool'",Session-Timeout="'0'"'
exit 0
fi
POOL=`mysql -u$MYSQL_USR -p$MYSQL_PASS -s -e "use $DB; select pool as pool from $TBL where username ='$USERNAME';" | tail -n 1`
BWPKG=`mysql -u$MYSQL_USR -p$MYSQL_PASS -s -e "use $DB; select bwpkg as bwpkg from $TBL where username ='$USERNAME';" | tail -n 1`
echo 'Framed-Pool="'$POOL'",Session-Timeout="'$SECONDS'",Mikrotik-Rate-Limit="'$BWPKG'",'
exit 0
fi

EXAMPLE:

After all is configured properly, we can see the results as following.

>>> To test with the script it self

root@testradius:/temp# ./auth.sh MR.PONKA PASS 00:0C:29:35:F8:2F
MR.PONKA >>>> User Not Found... *****

root@testradius:/temp# ./auth.sh zaib PASS 00:0C:29:35:F8:2F
Framed-Pool="public-pool",Session-Timeout="3020399",Mikrotik-Rate-Limit="1024k/1024k",

root@testradius:/temp# ./auth.sh zaib PASS 11:11:11:11:11:11
Mikrotik-Rate-Limit="1k/1k",Framed-Pool="invalidmac-pool",Session-Timeout="0"

root@testradius:/temp# ./auth.sh test PASS 00:0C:29:35:F8:2F
Mikrotik-Rate-Limit="1k/1k",Framed-Pool="expired-pool",Session-Timeout="0"

>>> To test from RADCLIENT ,

we can use the following radclient syntax to test username/pass/mac.

echo "User-Name = zaib, Password = zaib, Calling-Station-Id =00:0C:29:35:F8:2F" | radclient -s localhost:1812 auth RADIUS_SECRET

If user not found

Sending delayed reject for request 2
Sending Access-Reject of id 32 to 127.0.0.1 port 57901
 Reply-Message = "Username not found"
Waking up in 4.9 seconds.

If user is connecting from other device [mac binding scenario]

+- entering group post-auth {...}
Exec-Program output: Mikrotik-Rate-Limit="1k/1k",Framed-Pool="invalidmac-pool",Session-Timeout="0"
Exec-Program-Wait: value-pairs: Mikrotik-Rate-Limit="1k/1k",Framed-Pool="invalidmac-pool",Session-Timeout="0"
Exec-Program: returned: 0
++[exec] returns ok
Sending Access-Accept of id 113 to 127.0.0.1 port 50894
Mikrotik-Rate-Limit = "1k/1k"
Framed-Pool = "invalidmac-pool"
Session-Timeout = 0

If user account is expired…

+- entering group post-auth {...}
Exec-Program output: Mikrotik-Rate-Limit="1k/1k",Framed-Pool="expired-pool",Session-Timeout="0"
Exec-Program-Wait: value-pairs: Mikrotik-Rate-Limit="1k/1k",Framed-Pool="expired-pool",Session-Timeout="0"
Exec-Program: returned: 0
++[exec] returns ok
Sending Access-Accept of id 176 to 127.0.0.1 port 36544
Mikrotik-Rate-Limit = "1k/1k"
Framed-Pool = "expired-pool"
Session-Timeout = 0

& IF all is OK, & account is valid …. then user will be able to connect with his assigned profile present in the users table …

+- entering group post-auth {...}
Exec-Program output: Framed-Pool="public-pool",Session-Timeout="3020399",Mikrotik-Rate-Limit="1024k/1024k",
Exec-Program-Wait: value-pairs: Framed-Pool="public-pool",Session-Timeout="3020399",Mikrotik-Rate-Limit="1024k/1024k",
Exec-Program: returned: 0
++[exec] returns ok
Sending Access-Accept of id 0 to 127.0.0.1 port 37090
Framed-Pool = "public-pool"
Session-Timeout = 3020399
Mikrotik-Rate-Limit = "1024k/1024k"

RADPOSTAUTH mysql query section

Following is RADPOSTAUTH Table to accommodate modified message.

mysql>describe radpostauth;
+--------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(64) | NO | | | |
| pass | varchar(64) | NO | | | |
| mac | varchar(18) | NO | | NULL | |
| nasipaddress | varchar(16) | NO | | NULL | |
| reply | varchar(200) | NO | | | |
| authdate | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| reason | varchar(100) | NO | | NULL | |
+--------------+--------------+------+-----+-------------------+-----------------------------+

MYSQL QUERY:

This is mysql query which will be executed on every login attempt. Either success or failed. Replace existing or modify as required.

cat /etc/freeradius/sql/mysql/dialup.conf
postauth_query = "INSERT into ${postauth_table} (username, pass, mac, nasipaddress, reply, authdate, reason) values ('%{User-Name}', '%{User-Password:-Pap-Password}', '%{Calling-Station-Id}', '%{NAS-IP-Address}', '%{reply:Packet-Type}', NOW(), '%{reply:Reply-Message}')"

Now restart your freeradius service in DEBUG mode

freeradius -X

& issue following commands in other terminal window

# echo "User-Name = zaib1, Password = wrongpass, Calling-Station-Id =00:0C:29:35:F8:2F" | radclient -s localhost:1812 auth testing123
Received response ID 30, code 3, length = 40
Reply-Message = "Username not found"

Total approved auths: 0
Total denied auths: 1
Total lost auths: 0

# echo "User-Name = zaib, Password = wrongpass, Calling-Station-Id =00:0C:29:35:F8:2F" | radclient -s localhost:1812 auth testing123
Received response ID 77, code 3, length = 47
Reply-Message = "Wrong Password"

Total approved auths: 0
Total denied auths: 1
Total lost auths: 0

# echo "User-Name = zaib, Password = zaib, Calling-Station-Id =00:0C:29:35:F8:2F" | radclient -s localhost:1812 auth testing123
Received response ID 121, code 2, length = 58
Framed-Pool = "public-pool"
Session-Timeout = 3020399
Mikrotik-Rate-Limit = "1024k/1024k"

Total approved auths: 1
Total denied auths: 0
Total lost auths: 0

Now look at the debug window

& you will get

# debug for USERNAME not found request

# debug for WRONG Username

Sending delayed reject for request 13
Sending Access-Reject of id 30 to 127.0.0.1 port 46089
Reply-Message = "Username not found"

# debug for WRONG Password

Sending Access-Reject of id 77 to 127.0.0.1 port 41764
Reply-Message = "Wrong Password"
Waking up in 4.9 seconds.
Cleaning up request 14 ID 77 with timestamp +666
Ready to process requests.

# debug for SUCCESSFUL request

[pap] login attempt with password "zaib"
[pap] Using clear text password "zaib"
[pap] User authenticated successfully
++[pap] returns ok
# Executing section post-auth from file /etc/freeradius/sites-enabled/default
+- entering group post-auth {...}
Exec-Program output: Framed-Pool="public-pool",Session-Timeout="3020399",Mikrotik-Rate-Limit="1024k/1024k",
Exec-Program-Wait: value-pairs: Framed-Pool="public-pool",Session-Timeout="3020399",Mikrotik-Rate-Limit="1024k/1024k",
Exec-Program: returned: 0
++[exec] returns ok
Sending Access-Accept of id 121 to 127.0.0.1 port 46954
Framed-Pool = "public-pool"
Session-Timeout = 3020399
Mikrotik-Rate-Limit = "1024k/1024k"
Finished request 15.
Going to the next request
Waking up in 4.9 seconds.
Cleaning up request 15 ID 121 with timestamp +675
Ready to process requests.

Now look @ the radpostauth table


Alhamdolillah !

 

Mikrotik with Freeradius/mySQL – Quota Limit # Part-7

$
0
0

FreeRadius Core info

FREERADIUS WITH MIKROTIK – Part #1 – General Tip’s

FREERADIUS WITH MIKROTIK – Part #2  – COA

FREERADIUS WITH MIKROTIK – Part #3 – Expiration

FREERADIUS WITH MIKROTIK – Part #4 – Auto Mac Binding

FREERADIUS WITH MIKROTIK – Part #5 – Stale Sessions

FREERADIUS  WITH MIKROTIK – Part # 6 – External Auth Script & RADPOSTAUTH

FREERADIUS WITH MIKROTIK – Part #7  – Quota Limit  < You are Here


Personnel Note:

This is another post about freeradius. My aim is to let people know that creating your own Radius Billing system is not an ROCKET SCIENCE. The only thing required is the ultimate passion to achieve the goal. And with the right search, reading, understanding logic’s, you can do all on your own. I strongly encourage to read the FR mailing list and Google

OS: Ubuntu 16.04.3 LTS / 64bit


qt-logo.jpg

Scenario:

Assuming, we have already configured freeradius and user can authenticate & all is working fine. Now we want to provide users with Quota limit. But we donot want to use RADACCT table to calculate there usage & we also don’t want to check there quota on REAL time using freeradius UNLAG query. we will simply cron a script that will run every 10 minutes and will check for quota used for each user from the USERS table. We will make a separate table where we will add the QUOTA user and there limit to avoid re checking for same user. and in USERS table we will simply update there USED data record (in qt_used column in users table) using TRIGGER on radacct table.


USERS table Example.

Where all users information like name/mobile etc will be saved. Also it will contain a column qt_used which we will update dynamically using trigger on radacct table.

----------------------------------------------------------
-- Table structure for table `users`

CREATE TABLE `users` (
`id` int(10) NOT NULL,
`username` varchar(128) NOT NULL,
`password` varchar(32) NOT NULL,
`firstname` text NOT NULL,
`lastname` text NOT NULL,
`email` text NOT NULL,
`mobile` text NOT NULL,
`cnic` text NOT NULL,
`srvname` text NOT NULL,
`srvid` int(3) NOT NULL,
`expiration` date DEFAULT NULL,
`mac` varchar(30) NOT NULL,
`bwpkg` varchar(256) NOT NULL,
`pool` varchar(128) DEFAULT 'other',
`is_enabled` int(1) NOT NULL,
`is_days_expired` int(1) NOT NULL,
`is_qt_expired` int(1) NOT NULL,
`is_uptime_expired` int(1) NOT NULL,
`qt_total` varchar(32) NOT NULL,
`qt_used` varchar(20) NOT NULL,
`uptime_limit` varchar(20) NOT NULL,
`uptime_used` varchar(32) NOT NULL,
`owner` text NOT NULL,
`createdon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `users`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `username` (`username`) USING BTREE;

ALTER TABLE `users_qt`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

USERS Quota table Example!

If user is added in this product (username & qoota). then bash script will only check these users against there used quota (qt_used column in USERS table)

------------------------------------------------------------
-- Table structure for table `users_qt`

CREATE TABLE `users_qt` (
`id` int(11) NOT NULL,
`username` varchar(32) NOT NULL,
`quota` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `users_qt`
ADD PRIMARY KEY (`id`);

LOG Table Example!

We will use this table to log any disconnect message.

-- Table structure for table `log`
CREATE TABLE `log` (
`id` int(11) NOT NULL,
`data` varchar(32) NOT NULL,
`msg` varchar(128) NOT NULL,
`datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `log`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=29;

Trigger for RADACCT

This trigger will simply update the qt_used column for all users (which are enabled, not expired, not over-quota already)

DELIMITER $$
CREATE TRIGGER `radacct_after_update` AFTER UPDATE ON `radacct` FOR EACH ROW BEGIN
#if (NEW.acctterminatecause ='Session-Timeout')
#then
#UPDATE users set is_days_expired ='1' WHERE username =OLD.username;
#UPDATE radusergroup set groupname ='expired' WHERE username =OLD.username;
#ELSE
if (NEW.acctoutputoctets > 1)
OR (NEW.acctinputoctets > 1)
then
UPDATE users set qt_used = qt_used + NEW.acctoutputoctets WHERE is_enabled ='1' AND is_qt_expired ='0' AND is_uptime_expired ='0' AND is_days_expired ='0';
END IF;
#END IF;
END
$$
DELIMITER ;

Now insert a record in users_qt table for a user in this table. (quota limit 300 bytes testing only)

INSERT INTO 'users_qt' ('id', 'username', 'quota') VALUES (NULL, 'zaib', '300');

Now check the record.

root@radius:/temp# mysql -uroot -pPASS -s --skip-column-names -e "use radius; select * from users_qt;"

1 zaib 300

Ok now we simply connect the user and will do some data download or browse , since we have defined very small bytes limit it will fill in seconds.

Now to check the over-quota user we will use a small bash script (which will be cron to run every 10 minutes)


BASH script to check over quota user.

qc_check.sh

root@radius:/temp# cat qc.sh
#!/bin/bash
##set -x
SQLID="root"
SQLPASS="SQLPASS"
export MYSQL_PWD=$SQLPASS
DB="radius"
#Table which contain main users information
TBL="users"
#Table which contains users name which will be scanned for quota
QTDB="users_qt"
#Log table in which few actions will be logged
TBL_LOG="log"
#Rad user group in which we will update user profile like from 1mb to expired or likewise
GROUP="radusergroup"
#What is the Next pool name which will be
NEXTSRV="overquota"
# Temp file where user list will be saved
TMP="/tmp/qt_users.txt"
# NAS IP & port to send COA or disconenct pkt
NAS="10.0.0.1:3799"
# Radius Secret on NAS
RADSECRET="testing123"
CMD="mysql -u$SQLID --skip-column-names -s -e"
$CMD "use $DB; select username from $QTBL;" > $TMP
if [ ! -s $TMP ]
then
echo "No user found to check for QUOTA in table, exit"
exit 1
fi

# Run loop forumla to run CMD for single or multi usernames
num=0
cat $TMP | while read users
do
num=$[$num+1]
USERNAME=`echo $users |awk '{print $1}'`
TOTQT=`$CMD "use $DB; select quota from users_qt where username ='$USERNAME';"`
USEDQT=`$CMD "use $DB; SELECT qt_used FROM $TBL WHERE UserName='$USERNAME';"`

# If quota exceeds then perform multiple actions
if [ "$USEDQT" -gt "$TOTQT" ]; then

# Pull account session id from radacct table, which will be used to send to NAS for user COA OR Disconnection
ACCTSESID=`$CMD "use $DB; select acctsessionid from radacct where username ='$USERNAME' AND acctstoptime is NULL;"`
echo "Warning ! $USERNAME user quota reached limits. Allowed = $TOTQT Used = $USEDQT Disconnectig him now by sendin POD to NAS and adding LOG as well"

#Delete user from Quota check table, so it may reapt checking every time for same user
$CMD "use $DB; delete from users_qt where username ='$USERNAME';"

# Update User group to NEXT Service , like expired pool
$CMD "use $DB; update $GROUP set groupname='$NEXTSRV' where username ='$USERNAME';"

# If user is Online , Kick him using session id with RADCLIENT
if [ ! -z "$ACCTSESID" ]; then
echo user-name=$USERNAME,Acct-Session-Id=$ACCTSESID | radclient -x $NAS disconnect $RADSECRET

#Add in LOG table about kicked action
$CMD "use $DB; INSERT into $TBL_LOG (data, msg) VALUES ('$USERNAME', '$USERNAME - User Kickd dueto Quota limit exceeded');"
else
$CMD "use $DB; INSERT into $TBL_LOG (data, msg) VALUES ('$USERNAME', '$USERNAME - User quota found exceeded, but could not found its online session in Radius');"
fi
fi
done

Done.

Now run the Quota checking script …

root@radius:/temp# ./qc.sh

Warning ! zaib user quota reached limits. Allowed = 300 Used = 400 Disconnectig him now by sending POD to NAS and adding LOG as well

Once script found user Over Quota, it will update the user group in RADGROUPREPLY  so user should get OVER QUOTA pool …

group_updated

Entry in LOG table will be added …

over-qt.JPG

(in above pic, user was not online but he reached the quota, therefore the log informed about this too 🙂 )

Ok lets test user with radclient.

echo "User-Name = zaib, Password = zaib, Calling-Station-Id =00:0C:29:35:F8:2F" | radclient -s localhost:1812 auth RADSECRET

RESPONSE:

Received response ID 218, code 2, length = 89
Reply-Message = "Exp-Mod-Reply: Your account has expired."
Framed-Pool = "expired-pool"
Mikrotik-Rate-Limit = "1k/1k"

Total approved auths: 1
Total denied auths: 0
Total lost auths: 0

 

Disclaimer:

I might be missing any part, message me if any one required further info in it.

In the end I would like to thanks Mr. Khazoum Yaghi to give me hints for the separate table for quota checking. I was stucked on the script which keep checking for over-quota users again and again but after adding user user quota in separate table, the script now delete user entry from this table, so next time the script will run, it will not check that user because of missing entry in the quota table.

There are some other proper methods as well, but I just managed to achieve my task this way.

Regard’s

Syed Jahanzaib

Viewing all 409 articles
Browse latest View live