获取MAC地址 课程设计.docx
《获取MAC地址 课程设计.docx》由会员分享,可在线阅读,更多相关《获取MAC地址 课程设计.docx(9页珍藏版)》请在冰豆网上搜索。
获取MAC地址课程设计
程序设计课程设计
设计说明书
获取MAC地址
学生姓名
周琳
学号
0618014056
班级
062
成绩
指导教师
贾伟
计算机科学与技术系
2007年7月20日
程序设计课程设计评阅书
题目
获取MAC地址
学生姓名
周琳
学号
0618014056
指导教师评语及成绩
指导教师签名:
年月日
答辩评语及成绩
答辩教师签名:
年月日
教研室意见
总成绩:
室主任签名:
年月日
课程设计任务书
2006—2007学年第2学期
专业:
计算机科学与技术学号:
0618014056姓名:
周琳
课程设计名称:
获取MAC地址
设计题目:
获取MAC地址
完成期限:
自年月日至年月日共周
设计依据、要求及主要内容(可另加附页):
指导教师(签字):
教研室主任(签字):
批准日期:
年月日
摘要
用C语言编写一个获取本机MAC地址的程序,功能简单
关键词:
MAC地址
目录
1课题描述……………………………………………………………………1
2设计过程……………………………………………………………………2
3测试………………………………………………………………………11
总结…………………………………………………………………………12
参考文献……………………………………………………………………12
1课题描述
该程序是通过C程序实现的获取本机的MAC地址
开发工具:
VC++,VISO
2设计过程
2.1概念结构设计
如今的网络是分层来实现的,就像是搭积木一样,先设计某个特定功能的模块,然后把模块拼起来组成整个网络。
局域网也不例外,一般来说,在组网上我们使用的是IEEE802参考模型,从下至上分为:
物理层、媒体接入控制层(MAC),逻辑链路控制层(LLC)。
标识网络中的一台计算机,一般至少有三种方法,最常用的是域名地址、IP地址和MAC地址,分别对应应用层、网络层、物理层。
网络管理一般就是在网络层针对IP地址进行管理,但由于一台计算机的IP地址可以由用户自行设定,管理起来相对困难,MAC地址一般不可更改,所以把IP地址同MAC地址组合到一起管理就成为常见的管理方式。
这是由组网方式决定的,如今比较流行的接入Internet的方式(也是未来发展的方向)是把主机通过局域网组织在一起,然后再通过交换机和Internet相连接。
这样一来就出现了如何区分具体用户,防止盗用的问题。
由于IP只是逻辑上标识,任何人都随意修改,因此不能用来标识用户;而MAC地址则不然,它是固化在网卡里面的。
从理论上讲,除非盗来硬件(网卡),否则是没有办法冒名顶替的。
MAC(MediaAccessControl,介质访问控制)地址是识别LAN节点的标识。
MAC对设备(通常是网卡)接口是全球唯一的。
MAC地址为48位,用12个16进制数表示。
前6个16进制数字有IEEE管理,用来识别生产者或者厂商,构成OUI(ORGANIZATIONALUNIQUEIDENTIFIER,组织唯一识别符)。
后6个包括网卡序列号,或者特定硬件厂商的设定值。
MAC地址有时候被称为BIA(BURNED-INADDRESS,预烧硬件地址),因为他被烧在网卡ROM里面。
网卡初始化时,他被复制到计算机的RAM里面。
从上面的介绍可以知道,这种标识方式只是MAC地址基于的,如果有人能够更改MAC地址,就可以盗用IP免费上网了,目前网上针对小区宽带的盗用MAC地址免费上网方式就是基于此这种思路。
如果想盗用别人的IP地址,除了IP地址还要知道对应的MAC地址。
举个例子,获得局域网内某台主机的MAC地址,比如想得到局域网内名为TARGET主机的MAC地址,先用PING命令:
PINGTARGET,这样在我们主机上面的ARP表的缓存中就会留下目标地址和MAC映射的记录,然后通过ARPA命令来查询ARP表,这样就得到了指定主机的MAC地址。
最后用ARP-sIP网卡MAC地址,命令把网关的IP地址和它的MAC地址映射起来就可以了。
ARP(AddressResolutionProtocol)是地址解析协议,ARP是一种将IP地址转化成物理地址的协议。
从IP地址到物理地址的映射有两种方式:
表格方式和非表格方式。
ARP具体说来就是将网络层(IP层,也就是相当于OSI的第三层)地址解析为数据连接层(MAC层,也就是相当于OSI的第二层)的MAC地址。
ARP协议是通过IP地址来获得MAC地址的。
ARP原理:
郴鰽要向主机B发送报文,会查询本地的ARP缓存表,找到B的IP地址对应的MAC地址后就会进行数据传输。
如果未找到,则广播A一个ARP请求报文(携带主机A的IP地址Ia——物理地址Pa),请求IP地址为Ib的主机B回答物理地址Pb。
网上所有主机包括B都收到ARP请求,但只有主机B识别自己的IP地址,于是向A主机发回一个ARP响应报文。
其中就包含有B的MAC地址,A接收到B的应答后,就会更新本地的ARP缓存。
接着使用这个MAC地址发送数据(由网卡附加MAC地址)。
因此,本地高速缓存的这个ARP表是本地网络流通的基础,而且这个缓存是动态的。
ARP表:
为了回忆通信的速度,最近常用的MAC地址与IP的转换不用依靠交换机来进行,而是在本机上建立一个用来记录常用主机IP-MAC映射表,即ARP表。
MAC地址也叫物理地址、硬件地址或链路地址,由网络设备制造商生产时写在硬件内部。
MAC地址与网络无关,也即无论将带有这个地址的硬件(如网卡、集线器、路由器等)接入到网络的何处,都有相同的MAC地址,它由厂商写在网卡的BIOS里。
MAC地址可采用6字节(48比特)或2字节(16比特)这两种中的任意一种。
但随着局域网规模越来越大,一般都采用6字节的MAC地址。
这个48比特都有其规定的意义,前24位是由生产网卡的厂商向IEEE申请的厂商地址,目前的价格是1000美元买一个地址块,后24位由厂商自行分配,这样的分配使得世界上任意一个拥有48位MAC地址的网卡都有唯一的标识。
另外,2字节的MAC地址不用网卡厂商申请。
MAC地址通常表示为12个16进制数,每2个16进制数之间用冒号隔开,如:
08:
00:
20:
0A:
8C:
6D就是一个MAC地址,其中前6位16进制数08:
00:
20代表网络硬件制造商的编号,它由IEEE分配,而后3位16进制数0A:
8C:
6D代表该制造商所制造的某个网络产品(如网卡)的系列号。
每个网络制造商必须确保它所制造的每个以太网设备都具有相同的前三字节以及不同的后三个字节。
这样就可保证世界上每个以太网设备都具有唯一的MAC地址。
定义获取MAC地址相关的的结构体
typedefstruct_ASTAT_
{
ADAPTER_STATUSadapt;
NAME_BUFFERNameBuff[30];
}ASTAT,*PASTAT;
//定义一个结构体
ASTATAdapter;
3、测试
3.1程序流程图
getmac_one函数流程图main函数流程图
3.2运行结果如下
3.2程序源码
#include
#include"nb30.h"
#include
#include//该头文件定义了一些通用函数
#include//该头文件声明了输入输出流函数
#include
#pragmacomment(lib,"netapi32.lib")//连接Netapi32.lib库,MAC获取中用到了NetApi32.DLL的功能
typedefstruct_ASTAT_
{
ADAPTER_STATUSadapt;
NAME_BUFFERNameBuff[30];
}ASTAT,*PASTAT;
//定义一个结构体
ASTATAdapter;
voidgetmac_one(intlana_num);
intmain(intargc,char*argv[])
{
NCBncb;////定义一个NCB(网络控制块)类型的结构体变量ncb
UCHARuRetCode;
LANA_ENUMlana_enum;
memset(&ncb,0,sizeof(ncb));//将已开辟内存空间ncb的值均设为值0
ncb.ncb_command=NCBENUM;//统计系统中网卡的数量
ncb.ncb_buffer=(unsignedchar*)&lana_enum;//ncb_buffer成员指向由LANA_ENUM结构填充的缓冲区
ncb.ncb_length=sizeof(lana_enum);//向网卡发送NCBENUM命令,以获取当前机器的网卡信息,如有多少个网卡,每个网卡的编号(MAC地址)
uRetCode=Netbios(&ncb);//调用netbois(ncb)获取网卡序列号
printf("TheNCBENUMreturncodeis:
0x%x\n",uRetCode);
if(uRetCode==0)
{
printf("EthernetCountis:
%d\n\n",lana_enum.length);
//对每一张网卡,以其网卡编号为输入编号,获取其MAC地址
for(inti=0;igetmac_one(lana_enum.lana[i]);
}
return0;
}
voidgetmac_one(intlana_num)
{
NCBncb;
UCHARuRetCode;
memset(&ncb,0,sizeof(ncb));
ncb.ncb_command=NCBRESET;
ncb.ncb_lana_num=lana_num;
//指定网卡号
//首先对选定的网卡发送一个NCBRESET命令,以便进行初始化
uRetCode=Netbios(&ncb);
printf("TheNCBRESETreturncodeis:
0x%x\n",uRetCode);
memset(&ncb,0,sizeof(ncb));
ncb.ncb_command=NCBASTAT;
ncb.ncb_lana_num=lana_num;//指定网卡号
strcpy((char*)ncb.ncb_callname,"*");
ncb.ncb_buffer=(unsignedchar*)&Adapter;
//指定返回的信息存放的变量
ncb.ncb_length=sizeof(Adapter);
//接着,可以发送NCBASTAT命令以获取网卡的信息
uRetCode=Netbios(&ncb);
printf("TheNCBASTATreturncodeis:
0x%x\n",uRetCode);
if(uRetCode==0)
{
//把网卡MAC地址格式化成常用的16进制形式,如0010-A4E4-5802
printf("TheEthernetNumber[%d]is:
%02X-%02X-%02X-%02X-%02X-%02X\n",
lana_num,Adapter.adapt.adapter_address[0],
Adapter.adapt.adapter_address[1],
Adapter.adapt.adapter_address[2],
Adapter.adapt.adapter_address[3],
Adapter.adapt.adapter_address[4],
Adapter.adapt.adapter_address[5]);
}
}
总结
通过本次设计获取本机的MAC地址,是我再次再一次对C语言有了更清楚的认识,同时也对网络方面关于MAC地址有了进一步的认识。
这次由于时间紧,所设计的程序功能很简单,没有其他的功能,例如获取IP地址等。
本程序功过测试,没有发生任何问题,具有健壮性。
参考文献
[1]VisualC++程序开发范例宝典(附光盘)作者:
明日科技编著出版社:
人民邮电出版社出版时间:
2007年07月