分类:
2012-11-07 21:55:34
原文地址:Linux_C以太网基本操作 作者:luozhiyong131
/**
* 以太网模块
* 完成功能:获取及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
//以太网相关结构体
typedef struct
{
char LocalIp[16]; //IP addr
char Mask[16]; //mask addr
char Mac[18]; //phy addr
} ET_ENET_CONFIG;
typedef struct
{
char Destination[16]; //dest net
char Mask[16]; //dest mask addr
char GateWay[16]; // gateway addr
} ET_ROUTE_CONFIG; // set route struct
#define MAXINTERFACES 16
#define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr) // 套接字的IP地址
#define SET_SA_FAMILY(addr, family) \
memset((char*)&(addr), '\0', sizeof(addr)); \
addr.sa_family = (family) // 套接字协议栈地址
char device_name[20];
ET_ENET_CONFIG eth;
ET_ROUTE_CONFIG route;
/**
* 根据设备名获取IP和子网掩码
*/
int get_ip(char* ipaddr, char *netmask, const char *ethname)
{
int ret = -1;
if (ipaddr && netmask && ethname)
{
int fd, intrface;
struct ifreq buf[16]; //声明一个struct ifreq结构体(这个结构体中有很多重要的参数)
struct ifconf 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(struct ifreq);
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(((struct sockaddr_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(((struct sockaddr_in*) (&buf[intrface].ifr_netmask))->sin_addr));
ret = 0;
}
}
_error_: close(fd);
}
return ret;
}
/**
* 获取物理地址
*/
int get_mac(char *mac)
{
int fd, ret = -1;
if (mac)
{
struct ifreq 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", (unsigned char) ifr.ifr_hwaddr.sa_data[0], (unsigned char) ifr.ifr_hwaddr.sa_data[1], (unsigned char) ifr.ifr_hwaddr.sa_data[2], (unsigned char) ifr.ifr_hwaddr.sa_data[3], (unsigned char) ifr.ifr_hwaddr.sa_data[4], (unsigned char) ifr.ifr_hwaddr.sa_data[5]);
// strupr(mac);
ret = 0;
}
close(fd);
}
return ret;
}
/**
* 设置IP地址
*/
static int set_ipaddr(char *ipaddr)
{
char ipaddress[60];
sprintf(ipaddress, "ifconfig eth0 %s", ipaddr);
printf("%s\n", ipaddress);
system(ipaddress);
return 0;
}
/**
* 设置子网掩码
*/
static int set_netmask(char *netmask)
{
char netset[60];
sprintf(netset, "ifconfig eth0 netmask %s", netmask);
printf("%s\n", netset);
system(netset);
return 0;
}
/**
* 设置网关
*/
static int set_gateway(char *gateway)
{
char netset[60];
sprintf(netset, "ifconfig eth0 broadcast %s", gateway);
printf("%s\n", netset);
system(netset);
return 0;
}
/**
* 函数功能:设置或读取以太网各参数
* 命令ID定义说明:
* ulCmdId argp
* 0x01 -->输出参数,指向ET_ENET_CONFIG结构体的指针,读取当前的以太网信息(主要获取本机IP地址、掩码地址及物理地址)
* 0x02-->输入参数,指向ET_ENET_CONFIG结构体的指针,设置以太网本地IP,掩码地址
* 0x06-->输入参数,指向ET_ROUTE_CONFIG结构体的指针,设置路由
* 0x08-->参数无,以太网复位操作
* 返回值: 0x8B-->参数错误 : 0x00-->执行成功 : 0x01-->执行失败
*/
int ST_NetExpand(unsigned long ulCmdId, char *argp)
{
printf("get ip\n");
char cmd[256];
memset(cmd, 0, sizeof(cmd));
switch (ulCmdId)
{
case 0x01:
{
get_ip(eth.LocalIp, eth.Mask, "eth0");
get_mac(eth.Mac);
memcpy(argp, ð, sizeof(eth));
break;
}
case 0x02:
{
memcpy(ð, argp, sizeof(ET_ENET_CONFIG));
set_ipaddr(eth.LocalIp);
set_netmask(eth.Mask);
break;
}
case 0x06:
{
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;
}
case 0x08:
return 0x00;
}
return 0x00;
}
/**
* 函数功能:设置或读取以太网各参数
* 命令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-->执行失败
*/
void dhcp_start(void)
{
system("udhcpc"); //自动获取IP
}
pthread_t id_dhcp;
int ST_NetDhcpExpand(unsigned long ulCmdId, char *argp)
{
if (ulCmdId == 0x01)
{
pthread_create(&id_dhcp, NULL, (void *) dhcp_start, NULL);
}
if (ulCmdId == 0)
{
pthread_cancel(id_dhcp);
}
*argp = 0;
;
return 0x00;
}
源码: net.zip