Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7723968
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: 嵌入式

2012-11-01 11:06:28

/**

 * 以太网模块

 * 完成功能:获取及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   

 

阅读(2990) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~