Click here to Skip to main content
15,887,776 members
Please Sign up or sign in to vote.
3.00/5 (1 vote)
See more:
Dear community,

I want to make an C# script or program that is able to locate which Port on a switch the PC it runs on has.

Sadly i have no clue how to achieve that.

I have found a possibility to do it with SNMP
( See here )
but I could not find a way to use SNMP in C# without needing to buy classes or dll's.

If anyone has an Idea how I can solve this problem please help me out. :)


---------------EDIT:-------------------------

I was in a hurry when i wrote the question and it seems that I didn't explain my problem very well.

Basicly I have a Cisco Linksys Switch, the Switch is connected with multiple PC's.

What I am trying to do is write an Programm in C# that is runned on one of the PC's.
The programm should tell me what Switch port the PC is plugged in.
Or if it is possible to get an mac address table that lists all Ports with connected MAC-addresses.

Is there a way to do that in C#?

Furthermore I found a way to get a mac address table, or eaven the actual Switch Port number using SNMP.

So my second question was, is there a way to use SNMP in C# without paying for an dll or classes.
Posted
Updated 21-Oct-12 10:03am
v2
Comments
Sergey Alexandrovich Kryukov 16-Oct-12 20:29pm    
Dear inquirer,

I want to answer your question on the switch ports.

Sadly, I have no clue what is the question. And the problem is also not described.

If you have an idea on how to describe a problem in a comprehensible way, and, importantly, ask some question(s), please help me to see it.
-- Community

I think its difficult (or I don't know) to achieve without SNMP binaries. Port is attached to switch and only SNMP can provide those specs.
 
Share this answer
 
There are many ways to begin. So I do not make this confusing which is your preference?

You can use netsnmp.

Either shell script something to the exe binaries and pipe the query back to what you are
using.

Download the netsnmp source. Study it and "roll your own" or modify it.

You can use #SNMP (SharpSNMP) C# open source SNMP..

Also there is SNMPDll on Code project.

There is snmp_pp or SNMP++.



The steps to port map a switch:
1 Find an MIB Browser so you can check your SNMP OIDs and keep your sanity.
2 Memorise this article:
http://www.cisco.com/en/US/tech/tk648/tk362/technologies_tech_note09186a00801c9199.shtml[^]
3 Your approach is going to be getting the mac address table, getting the interface table then allign those two together.

Do not assume that an IFIndex is the same as a port number. ifName.2 != Fa0/2 (does not equal)



For the grand finally, you need to query a router to map the mac address to an IP address.

You could get fancy. You can try to query your DHCP server to map mac addresses to ip addresses.

The "tricky" part in all of this is handling the arrays/classes etc you may setup to align the information retreived from your own code.

As for advice: do not try to develop this in a production environment.
Bad code could hang a switch and you could find your self not worring about any of this ;o)!


I found a "simple" example in my files. I hope the citation/credit is adequate:


/*
C# Network Programming
by Richard Blum

Publisher: Sybex
ISBN: 0782141765
*/
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;


public class SimpleSNMP
{

public static void Main()
{
int commlength, miblength, datatype, datalength, datastart;
int uptime = 0;
string output;
SNMP conn = new SNMP();
byte[] response = new byte[1024];
string[] argv = new string[3] ;
argv[0] = "192.168.1.10";
argv[1] = "public";

Console.WriteLine("Device SNMP information:");

// Send sysName SNMP request
response = conn.get("get", argv[0], argv[1], "1.3.6.1.2.1.1.5.0");
if (response[0] == 0xff)
{
Console.WriteLine("No response from {0}", argv[0]);
return;
}

// If response, get the community name and MIB lengths
commlength = Convert.ToInt16(response[6]);
miblength = Convert.ToInt16(response[23 + commlength]);

// Extract the MIB data from the SNMP response
datatype = Convert.ToInt16(response[24 + commlength + miblength]);
datalength = Convert.ToInt16(response[25 + commlength + miblength]);
datastart = 26 + commlength + miblength;
output = Encoding.ASCII.GetString(response, datastart, datalength);
Console.WriteLine(" sysName - Datatype: {0}, Value: {1}",
datatype, output);

// Send a sysLocation SNMP request
response = conn.get("get", argv[0], argv[1], "1.3.6.1.2.1.1.6.0");
if (response[0] == 0xff)
{
Console.WriteLine("No response from {0}", argv[0]);
return;
}

// If response, get the community name and MIB lengths
commlength = Convert.ToInt16(response[6]);
miblength = Convert.ToInt16(response[23 + commlength]);

// Extract the MIB data from the SNMP response
datatype = Convert.ToInt16(response[24 + commlength + miblength]);
datalength = Convert.ToInt16(response[25 + commlength + miblength]);
datastart = 26 + commlength + miblength;
output = Encoding.ASCII.GetString(response, datastart, datalength);
Console.WriteLine(" sysLocation - Datatype: {0}, Value: {1}", datatype, output);

// Send a sysContact SNMP request
response = conn.get("get", argv[0], argv[1], "1.3.6.1.2.1.1.4.0");
if (response[0] == 0xff)
{
Console.WriteLine("No response from {0}", argv[0]);
return;
}

// Get the community and MIB lengths
commlength = Convert.ToInt16(response[6]);
miblength = Convert.ToInt16(response[23 + commlength]);

// Extract the MIB data from the SNMP response
datatype = Convert.ToInt16(response[24 + commlength + miblength]);
datalength = Convert.ToInt16(response[25 + commlength + miblength]);
datastart = 26 + commlength + miblength;
output = Encoding.ASCII.GetString(response, datastart, datalength);
Console.WriteLine(" sysContact - Datatype: {0}, Value: {1}",
datatype, output);

// Send a SysUptime SNMP request
response = conn.get("get", argv[0], argv[1], "1.3.6.1.2.1.1.3.0");
if (response[0] == 0xff)
{
Console.WriteLine("No response from {0}", argv[0]);
return;
}

// Get the community and MIB lengths of the response
commlength = Convert.ToInt16(response[6]);
miblength = Convert.ToInt16(response[23 + commlength]);

// Extract the MIB data from the SNMp response
datatype = Convert.ToInt16(response[24 + commlength + miblength]);
datalength = Convert.ToInt16(response[25 + commlength + miblength]);
datastart = 26 + commlength + miblength;

// The sysUptime value may by a multi-byte integer
// Each byte read must be shifted to the higher byte order
while (datalength > 0)
{
uptime = (uptime << 8) + response[datastart++];
datalength--;
}
Console.WriteLine(" sysUptime - Datatype: {0}, Value: {1}",
datatype, uptime);

}
}


class SNMP
{
public SNMP()
{

}

public byte[] get(string request, string host, string community, string mibstring)
{
byte[] packet = new byte[1024];
byte[] mib = new byte[1024];
int snmplen;
int comlen = community.Length;
string[] mibvals = mibstring.Split('.');
int miblen = mibvals.Length;
int cnt = 0, temp, i;
int orgmiblen = miblen;
int pos = 0;

// Convert the string MIB into a byte array of integer values
// Unfortunately, values over 128 require multiple bytes
// which also increases the MIB length
for (i = 0; i < orgmiblen; i++)
{
temp = Convert.ToInt16(mibvals[i]);
if (temp > 127)
{
mib[cnt] = Convert.ToByte(128 + (temp / 128));
mib[cnt + 1] = Convert.ToByte(temp - ((temp / 128) * 128));
cnt += 2;
miblen++;
}
else
{
mib[cnt] = Convert.ToByte(temp);
cnt++;
}
}
snmplen = 29 + comlen + miblen - 1; //Length of entire SNMP packet

//The SNMP sequence start
packet[pos++] = 0x30; //Sequence start
packet[pos++] = Convert.ToByte(snmplen - 2); //sequence size

//SNMP version
packet[pos++] = 0x02; //Integer type
packet[pos++] = 0x01; //length
packet[pos++] = 0x00; //SNMP version 1

//Community name
packet[pos++] = 0x04; // String type
packet[pos++] = Convert.ToByte(comlen); //length
//Convert community name to byte array
byte[] data = Encoding.ASCII.GetBytes(community);
for (i = 0; i < data.Length; i++)
{
packet[pos++] = data[i];
}

//Add GetRequest or GetNextRequest value
if (request == "get")
packet[pos++] = 0xA0;
else
packet[pos++] = 0xA1;

packet[pos++] = Convert.ToByte(20 + miblen - 1); //Size of total MIB

//Request ID
packet[pos++] = 0x02; //Integer type
packet[pos++] = 0x04; //length
packet[pos++] = 0x00; //SNMP request ID
packet[pos++] = 0x00;
packet[pos++] = 0x00;
packet[pos++] = 0x01;

//Error status
packet[pos++] = 0x02; //Integer type
packet[pos++] = 0x01; //length
packet[pos++] = 0x00; //SNMP error status

//Error index
packet[pos++] = 0x02; //Integer type
packet[pos++] = 0x01; //length
packet[pos++] = 0x00; //SNMP error index

//Start of variable bindings
packet[pos++] = 0x30; //Start of variable bindings sequence

packet[pos++] = Convert.ToByte(6 + miblen - 1); // Size of variable binding

packet[pos++] = 0x30; //Start of first variable bindings sequence
packet[pos++] = Convert.ToByte(6 + miblen - 1 - 2); // size
packet[pos++] = 0x06; //Object type
packet[pos++] = Convert.ToByte(miblen - 1); //length

//Start of MIB
packet[pos++] = 0x2b;
//Place MIB array in packet
for (i = 2; i < miblen; i++)
packet[pos++] = Convert.ToByte(mib[i]);
packet[pos++] = 0x05; //Null object value
packet[pos++] = 0x00; //Null

//Send packet to destination
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
sock.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReceiveTimeout, 5000);
IPHostEntry ihe = Dns.Resolve(host);
IPEndPoint iep = new IPEndPoint(ihe.AddressList[0], 161);
EndPoint ep = (EndPoint)iep;
sock.SendTo(packet, snmplen, SocketFlags.None, iep);

//Receive response from packet
try
{
int recv = sock.ReceiveFrom(packet, ref ep);
}
catch (SocketException)
{
packet[0] = 0xff;
}
return packet;
}

public string getnextMIB(byte[] mibin)
{
string output = "1.3";
int commlength = mibin[6];
int mibstart = 6 + commlength + 17; //find the start of the mib section
//The MIB length is the length defined in the SNMP packet
// minus 1 to remove the ending .0, which is not used
int miblength = mibin[mibstart] - 1;
mibstart += 2; //skip over the length and 0x2b values
int mibvalue;

for (int i = mibstart; i < mibstart + miblength; i++)
{
mibvalue = Convert.ToInt16(mibin[i]);
if (mibvalue > 128)
{
mibvalue = (mibvalue / 128) * 128 + Convert.ToInt16(mibin[i + 1]);
//ERROR here, it should be mibvalue = (mibvalue-128)*128 + Convert.ToInt16(mibin[i+1]);
//for mib values greater than 128, the math is not adding up correctly

i++;
}
output += "." + mibvalue;
}
return output;
}
}
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900