在C#中获取网桥(交换机)端口 [英] Get Bridge (Switch) Port in C#

查看:128
本文介绍了在C#中获取网桥(交换机)端口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的社区,

我想制作一个C#脚本或程序,以便能够在其运行的PC上找到交换机上的哪个端口.

可悲的是,我不知道如何实现这一目标.

我发现可以使用SNMP做到这一点
(请参阅此处)
但是我无法找到一种无需购买类或dll即可在C#中使用SNMP的方法.

如果有人对如何解决此问题有任何想法,请帮助我. :)


----------------------------------------

写问题时我很着急,似乎我没有很好地解释我的问题.

基本上,我有一个Cisco Linksys交换机,该交换机与多台PC连接.

我要做的是用C#编写一个在PC上运行的Programm.
程序应该告诉我PC插入了哪个Switch端口.
或者,如果有可能获得列出所有具有已连接MAC地址的端口的mac地址表.

有没有办法在C#中做到这一点?

此外,我找到了一种获取mac地址表或使用SNMP避开实际交换机端口号的方法.

所以我的第二个问题是,有没有一种方法可以在C#中使用SNMP而不用为dll或类付费.

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. :)


----------------------------------------

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.

推荐答案

我认为这很困难(或者我没有)不知道)实现没有SNMP二进制文件.端口连接到交换机,只有SNMP可以提供这些规范.
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.


有很多开始的方法.因此,我不会让您感到困惑,这是您的偏好吗?

您可以使用netsnmp.

要么将shell脚本添加到exe二进制文件中,然后将查询通过管道传递回您自己的位置
正在使用.

下载netsnmp源.研究它并自己动手"或对其进行修改.

您可以使用#SNMP(SharpSNMP)C#开源SNMP.
在项目上也有SNMPDll.

有snmp_pp或SNMP ++.



端口映射交换机的步骤:
1找到一个MIB浏览器,以便您可以检查SNMP OID并保持理智.
2记住本文:
http://www.cisco.com/en/US/tech/tk648/tk362/technologies_tech_note09186a00801c9199.shtml [ ^ ]
3您的方法将是获取mac地址表,获取接口表,然后将这两个地址放在一起.

不要假定IFIndex与端口号相同. ifName.2!= Fa0/2(不相等)



最后,您需要查询路由器以将mac地址映射到IP地址.

你可能会喜欢上.您可以尝试查询DHCP服务器以将mac地址映射到IP地址.

所有这些中的棘手"部分正在处理数组/类,您可以设置它们以对齐从您自己的代码中检索到的信息.

至于建议:请勿尝试在生产环境中进行开发.
错误的代码可能会挂上一个开关,您可能会发现自己对此并不感到担心; o)!


我在文件中找到一个简单"的示例.我希望引文/信用足够:


/*
C#网络编程
由Richard Blum

发行人:Sybex
ISBN:0782141765
*/
使用系统;
使用System.Text;
使用System.Net;
使用System.Net.Sockets;


公共类SimpleSNMP
{

公共静态void Main()
{
int commlength,miblength,数据类型,datalength,datastart;
int正常运行时间= 0;
字符串输出;
SNMP conn =新的SNMP();
byte []响应=新的byte [1024];
string [] argv =新的string [3];
argv [0] ="192.168.1.10";
argv [1] ="public";

Console.WriteLine(设备SNMP信息:");

//发送sysName SNMP请求
响应= conn.get("get",argv [0],argv [1],"1.3.6.1.2.1.1.5.0");
如果(response [0] == 0xff)
{
Console.WriteLine("{0}无响应",argv [0]);
返回;
}

//如果响应,请获取社区名称和MIB长度
commlength = Convert.ToInt16(response [6]);
miblength = Convert.ToInt16(response [23 + commlength]);

//从SNMP响应中提取MIB数据
数据类型= Convert.ToInt16(response [24 + commlength + miblength]);
datalength = Convert.ToInt16(response [25 + commlength + miblength]);
datastart = 26 + commlength + miblength;
输出= Encoding.ASCII.GetString(响应,数据开始,数据长度);
Console.WriteLine("sysName-数据类型:{0},值:{1}",
数据类型,输出);

//发送sysLocation SNMP请求
响应= conn.get("get",argv [0],argv [1],"1.3.6.1.2.1.1.6.0");
如果(response [0] == 0xff)
{
Console.WriteLine("{0}无响应",argv [0]);
返回;
}

//如果响应,请获取社区名称和MIB长度
commlength = Convert.ToInt16(response [6]);
miblength = Convert.ToInt16(response [23 + commlength]);

//从SNMP响应中提取MIB数据
数据类型= Convert.ToInt16(response [24 + commlength + miblength]);
datalength = Convert.ToInt16(response [25 + commlength + miblength]);
datastart = 26 + commlength + miblength;
输出= Encoding.ASCII.GetString(响应,数据开始,数据长度);
Console.WriteLine("sysLocation-数据类型:{0},值:{1}",数据类型,输出);

//发送sysContact SNMP请求
响应= conn.get("get",argv [0],argv [1],"1.3.6.1.2.1.1.4.0");
如果(response [0] == 0xff)
{
Console.WriteLine("{0}无响应",argv [0]);
返回;
}

//获取社区和MIB的长度
commlength = Convert.ToInt16(response [6]);
miblength = Convert.ToInt16(response [23 + commlength]);

//从SNMP响应中提取MIB数据
数据类型= Convert.ToInt16(response [24 + commlength + miblength]);
datalength = Convert.ToInt16(response [25 + commlength + miblength]);
datastart = 26 + commlength + miblength;
输出= Encoding.ASCII.GetString(响应,数据开始,数据长度);
Console.WriteLine("sysContact-数据类型:{0},值:{1}",
数据类型,输出);

//发送SysUptime SNMP请求
响应= conn.get("get",argv [0],argv [1],"1.3.6.1.2.1.1.3.0");
如果(response [0] == 0xff)
{
Console.WriteLine("{0}无响应",argv [0]);
返回;
}

//获取响应的社区和MIB长度
commlength = Convert.ToInt16(response [6]);
miblength = Convert.ToInt16(response [23 + commlength]);

//从SNMp响应中提取MIB数据
数据类型= Convert.ToInt16(response [24 + commlength + miblength]);
datalength = Convert.ToInt16(response [25 + commlength + miblength]);
datastart = 26 + commlength + miblength;

//sysUptime值可以是一个多字节整数
//每个读取的字节必须移至高字节顺序
while(数据长度> 0)
{
正常运行时间=(正常运行时间<< <8)+ response [datastart ++];
datalength--;
}
Console.WriteLine("sysUptime-数据类型:{0},值:{1}",
数据类型,正常运行时间);

}
}


SNMP类
{
公用SNMP()
{

}

public byte [] get(字符串请求,字符串宿主,字符串社区,字符串mibstring)
{
字节[]数据包=新字节[1024];
位元组[] mib =新位元组[1024];
int snmplen;
int comlen = community.Length;
string [] mibval​​s = mibstring.Split(''.'');
int miblen = mibval​​s.Length;
int cnt = 0,temp,i;
int orgmiblen = miblen;
int pos = 0;

//将字符串MIB转换为整数值的字节数组
//不幸的是,超过128的值需要多个字节
//这也会增加MIB的长度
for(i = 0; i< orgmiblen; i ++)
{
temp = Convert.ToInt16(mibval​​s [i]);
如果(温度> 127)
{
mib [cnt] = Convert.ToByte(128 +(temp/128));
mib [cnt + 1] = Convert.ToByte(temp-((temp/128)* 128));
cnt + = 2;
miblen ++;
}
其他
{
mib [cnt] = Convert.ToByte(temp);
cnt ++;
}
}
snmplen = 29 + comlen + miblen-1; //整个SNMP数据包的长度

//SNMP序列开始
packet [pos ++] = 0x30; //顺序开始
packet [pos ++] = Convert.ToByte(snmplen-2); //序列大小

//SNMP版本
packet [pos ++] = 0x02; //整数类型
packet [pos ++] = 0x01; //长度
packet [pos ++] = 0x00; //SNMP版本1

//社区名称
packet [pos ++] = 0x04; //字符串类型
packet [pos ++] = Convert.ToByte(comlen); //长度
//将社区名称转换为字节数组
byte [] data = Encoding.ASCII.GetBytes(community);
对于(i = 0; i< data.Length; i ++)
{
packet [pos ++] = data [i];
}

//添加GetRequest或GetNextRequest值
如果(request =="get")
packet [pos ++] = 0xA0;
其他
packet [pos ++] = 0xA1;

packet [pos ++] = Convert.ToByte(20 + miblen-1); //总MIB的大小

//请求ID
packet [pos ++] = 0x02; //整数类型
packet [pos ++] = 0x04; //长度
packet [pos ++] = 0x00; //SNMP请求ID
packet [pos ++] = 0x00;
packet [pos ++] = 0x00;
packet [pos ++] = 0x01;

//错误状态
packet [pos ++] = 0x02; //整数类型
packet [pos ++] = 0x01; //长度
packet [pos ++] = 0x00; //SNMP错误状态

//错误索引
packet [pos ++] = 0x02; //整数类型
packet [pos ++] = 0x01; //长度
packet [pos ++] = 0x00; //SNMP错误索引

//开始变量绑定
packet [pos ++] = 0x30; //开始变量绑定序列

packet [pos ++] = Convert.ToByte(6 + miblen-1); //变量绑定的大小

packet [pos ++] = 0x30; //第一个变量绑定序列的开始
packet [pos ++] = Convert.ToByte(6 + miblen-1-2); //大小
packet [pos ++] = 0x06; //对象类型
packet [pos ++] = Convert.ToByte(miblen-1); //长度

//开始MIB
packet [pos ++] = 0x2b;
//将MIB数组放在数据包中
为(i = 2; i< miblen; i ++)
packet [pos ++] = Convert.ToByte(mib [i]);
packet [pos ++] = 0x05; //空对象值
packet [pos ++] = 0x00; //空

//将数据包发送到目的地
套接字袜子=新套接字(AddressFamily.InterNetwork,SocketType.Dgram,
ProtocolType.Udp);
sock.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReceiveTimeout,5000);
IPHostEntry ihe = Dns.Resolve(主机);
IPEndPoint iep =新IPEndPoint(ihe.AddressList [0],161);
EndPoint ep =(EndPoint)iep;
sock.SendTo(packet,snmplen,SocketFlags.None,iep);

//接收来自数据包的响应
试试
{
int recv = sock.ReceiveFrom(packet,ref ep);
}
捕获(SocketException)
{
数据包[0] = 0xff;
}
返回数据包;
}

公共字符串getnextMIB(byte [] mibin)
{
字符串输出="1.3";
int commlength = mibin [6];
int mibstart = 6 + commlength + 17; //找到mib部分的开始
//MIB长度是SNMP数据包中定义的长度
//减1删除结尾的.0,该结尾未使用
int miblength = mibin [mibstart]-1;
mibstart + = 2; //跳过长度和0x2b值
int mibval​​ue;

for(int i = mibstart; i< mibstart + miblength; i ++)
{
mibval​​ue = Convert.ToInt16(mibin [i]);
如果(mibval​​ue> 128)
{
mibval​​ue =(mibval​​ue/128)* 128 + Convert.ToInt16(mibin [i + 1]);
//这里出现错误,应为mibval​​ue =(mibval​​ue-128)* 128 + Convert.ToInt16(mibin [i + 1]);
//对于大于128的mib值,数学运算未正确累加

i ++;
}
输出+ =." + mibval​​ue;
}
返回输出;
}
}
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;
}
}


这篇关于在C#中获取网桥(交换机)端口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆