/**
*以太网模块
*完成功能:获取及IP、子网掩码设置DHCP自动获取IP
* Author:Lzy
* Greate Date:2012.03.15
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//以太网相关结构体
typedefstruct
{
charLocalIp[16];//IP addr
charMask[16];//mask addr
charMac[18];//phy addr
}ET_ENET_CONFIG;
typedefstruct
{
charDestination[16];//dest net
charMask[16];//dest mask addr
charGateWay[16];// gateway addr
}ET_ROUTE_CONFIG;//
set route struct
#defineMAXINTERFACES 16
#defineSIN_ADDR(x) (((structsockaddr_in *)
(&(x)))->sin_addr.s_addr)//套接字的IP地址
#defineSET_SA_FAMILY(addr, family) \
memset((char*)&(addr),'\0',sizeof(addr)); \
addr.sa_family = (family)//套接字协议栈地址
chardevice_name[20];
ET_ENET_CONFIGeth;
ET_ROUTE_CONFIGroute;
/**
*根据设备名获取IP和子网掩码
*/
intget_ip(char* ipaddr,char*netmask,constchar*ethname)
{
intret = -1;
if(ipaddr && netmask
&& ethname)
{
intfd, intrface;
structifreq buf[16];//声明一个structifreq结构体(这个结构体中有很多重要的参数)
structifconf ifc;//通常是用来保存所有接口信息的
if((fd = socket(AF_INET, SOCK_DGRAM,
0)) < 0)//建立一个套接字
return-1;
ifc.ifc_len=sizeof(buf);
ifc.ifc_buf= (caddr_t) buf;
if(ioctl(fd, SIOCGIFCONF, (char*) &ifc) < 0)//这里涉及ioctl函数对于网络文件的控制获取所有接口的清单
goto_error_;
intrface = ifc.ifc_len/sizeof(structifreq);
while(intrface-- > 0)
{
if(strstr(buf[intrface].ifr_name, ethname))
{
if((ioctl(fd, SIOCGIFADDR, (char*) &buf[intrface])) < 0)//获取接口地址
goto_error_;
sprintf(ipaddr,"%s", inet_ntoa(((structsockaddr_in*) (&buf[intrface].ifr_addr))->sin_addr));//将一个in_addr结构体输出成点数格输出IP地址
if((ioctl(fd, SIOCGIFNETMASK,
(char*)
&buf[intrface])) < 0)
`//获取子网掩码
goto_error_;
sprintf(netmask,"%s", inet_ntoa(((structsockaddr_in*) (&buf[intrface].ifr_netmask))->sin_addr));
ret = 0;
}
}
_error_: close(fd);
}
returnret;
}
/**
*获取物理地址
*/
intget_mac(char*mac)
{
intfd, ret = -1;
if(mac)
{
structifreq ifr;
if((fd = socket(AF_INET, SOCK_DGRAM,
0)) < 0)//建立套接字
{
printf("socket");
return-1;
}
ifr.ifr_addr.sa_family = AF_INET;//指定套接字协议栈地址
strncpy(ifr.ifr_name,"eth0", IFNAMSIZ - 1);//把网卡名字复制到ifreq结构体中的name变量
if(ioctl(fd, SIOCGIFHWADDR,
&ifr) == 0)//获取物理地址
{
sprintf(mac,"%02x-%02x-%02x-%02x-%02x-%02x", (unsignedchar) ifr.ifr_hwaddr.sa_data[0], (unsignedchar) ifr.ifr_hwaddr.sa_data[1], (unsignedchar) ifr.ifr_hwaddr.sa_data[2], (unsignedchar) ifr.ifr_hwaddr.sa_data[3], (unsignedchar) ifr.ifr_hwaddr.sa_data[4], (unsignedchar) ifr.ifr_hwaddr.sa_data[5]);
// strupr(mac);
ret = 0;
}
close(fd);
}
returnret;
}
/**
*设置IP地址
*/
staticintset_ipaddr(char*ipaddr)
{
charipaddress[60];
sprintf(ipaddress,"ifconfig eth0
%s",
ipaddr);
printf("%s\n", ipaddress);
system(ipaddress);
return0;
}
/**
*设置子网掩码
*/
staticintset_netmask(char*netmask)
{
charnetset[60];
sprintf(netset,"ifconfig eth0 netmask
%s",
netmask);
printf("%s\n", netset);
system(netset);
return0;
}
/**
*设置网关
*/
staticintset_gateway(char*gateway)
{
charnetset[60];
sprintf(netset,"ifconfig eth0
broadcast %s", gateway);
printf("%s\n", netset);
system(netset);
return0;
}
/**
*函数功能:设置或读取以太网各参数
*命令ID定义说明:
* ulCmdId argp
*
0x01 -->输出参数,指向ET_ENET_CONFIG结构体的指针,读取当前的以太网信息(主要获取本机IP地址、掩码地址及物理地址)
*
0x02-->输入参数,指向ET_ENET_CONFIG结构体的指针,设置以太网本地IP,掩码地址
*
0x06-->输入参数,指向ET_ROUTE_CONFIG结构体的指针,设置路由
*
0x08-->参数无,以太网复位操作
*返回值: 0x8B-->参数错误: 0x00-->执行成功: 0x01-->执行失败
*/
intST_NetExpand(unsignedlongulCmdId,char*argp)
{
printf("get ip\n");
charcmd[256];
memset(cmd, 0,sizeof(cmd));
switch(ulCmdId)
{
case0x01:
{
get_ip(eth.LocalIp, eth.Mask,"eth0");
get_mac(eth.Mac);
memcpy(argp, ð,sizeof(eth));
break;
}
case0x02:
{
memcpy(ð, argp,sizeof(ET_ENET_CONFIG));
set_ipaddr(eth.LocalIp);
set_netmask(eth.Mask);
break;
}
case0x06:
{
memcpy(&route,
argp,sizeof(ET_ENET_CONFIG));
sprintf(cmd,"route add -net %s netmask
%s gw %s", route.Destination, route.Mask,
route.GateWay);
system(cmd);
break;
}
case0x08:
return0x00;
}
return0x00;
}
/**
*函数功能:设置或读取以太网各参数
*命令ID定义说明:
* ulCmdId argp
* 0x00--------- |0x00-->0表示关闭DHCP功能
* |0x01-->设置"开机后自动启动DHCP来获取IP地址
* 0x01-->输出参数,用以存储状态值(要求为int型指针变量,作为输出参数)
*用在开启DHCP功能后,获取DHCP的工作状态(见下表中状态值定义)
*
------------------------------------------------------------------------------------------------------
*
DHCP的工作状态表
*
:0x01-->正准备启动
*
:0x02-->DHCP已启动
*
:0x03-->成功获取IP地址
*
:0x04-->获取IP地址失败
*返回值:0x8B-->参数错误:0x00-->执行成功:0x01-->执行失败
*/
voiddhcp_start(void)
{
system("udhcpc");//自动获取IP
}
pthread_tid_dhcp;
intST_NetDhcpExpand(unsignedlongulCmdId,char*argp)
{
if(ulCmdId == 0x01)
{
pthread_create(&id_dhcp,
NULL, (void*) dhcp_start, NULL);
}
if(ulCmdId == 0)
{
pthread_cancel(id_dhcp);
}
*argp = 0;
;
return0x00;
}