struct sockaddr_in
{
sa_family_t sin_family; /* address family: AF_INET */
u_int16_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
struct in_addr
{
u_int32_t s_addr; /* address in network byte order */
};
struct sockaddr
{
ushort sa_family;
char sa_data[14];
};
struct ifconf{
int ifc_len;//缓冲存储器的大小
union{
caddr_t ifcu_buf;
struct ifreq *ifcu_req;
}
ifc_ifcu;
};
struct ifreq {
/ * Interface name */
char ifr_name[IFNAMSIZ];
union {
struct sockaddr ifr_addr;
struct sockaddr ifr_dstaddr;
struct sockaddr ifr_broadaddr;
struct sockaddr ifr_netmask;
struct sockaddr ifr_hwaddr;
short ifr_flags;
int ifr_ifindex;
int ifr_metric;
int ifr_mtu;
struct ifmap ifr_map;
char ifr_slave[IFNAMSIZ];
char ifr_newname[IFNAMSIZ];
char * ifr_data;
};
};
1. 先通过ioctl获得本地所有接口的信息,并保存在ifconf中
2. 再从ifconf中取出每一个ifreq中表示ip地址的信息
增加网关
/******************************************************************
º¯ÊýÔÐÍ:DG_AL_eth_add_route
¹¦ÄÜÃèÊö:ÍøÂçÄ£¿é¼Ó·ÓÉ
²ÎÊý: D_UINT8 *dest:Ä¿±êµØÖ·
D_UINT8* mask:ÑÚÂë
D_UINT8 *gw_addr:Íø¹Ø
·µ»ØÖµ: D_SUCCESS³É¹¦£¬D_FAILUREʧ°Ü
******************************************************************/
static D_INT32 DG_AL_eth_add_route(D_UINT8 *dest, D_UINT8* mask, D_UINT8 *gw_addr)
{
struct rtentry rt = {0};
struct sockaddr_in addr= {0};
int sockfd = -1, ret = -1;
char ip_buf[20] = {0};
memset((char *)&rt, 0, sizeof(struct rtentry));
/*¿´µ½ÁíÍâÒ»Öֲο¼Ó÷¨£¬ÓÐĬÈϺÍÖ÷»ú×ÖÑù
rt.rt_flags = (RTF_UP | RTF_GATEWAY | RTF_DEFAULT | RTF_HOST);
*/
rt.rt_flags=(RTF_UP|RTF_GATEWAY);
rt.rt_dev = if_eth0;
addr.sin_family = AF_INET;
sprintf(ip_buf, "%d.%d.%d.%d", dest[0], dest[1], dest[2], dest[3]);
/*addr.sin_addr.s_addr = inet_addr((const char *)ip_buf ); */
inet_aton((const char *)ip_buf, &(addr.sin_addr));
memcpy((char *)&rt.rt_dst, (char *)&addr, sizeof(struct sockaddr_in));
sprintf(ip_buf, "%d.%d.%d.%d", gw_addr[0], gw_addr[1], gw_addr[2], gw_addr[3]);
/*ddr.sin_addr.s_addr = inet_addr((const char *)ip_buf); */
inet_aton((const char *)ip_buf, &(addr.sin_addr));
memcpy((char *)&rt.rt_gateway,(char *)&addr, sizeof(struct sockaddr_in));
sprintf(ip_buf, "%d.%d.%d.%d", mask[0], mask[1], mask[2], mask[3]);
/*addr.sin_addr.s_addr = inet_addr((const char *)ip_buf);*/
inet_aton((const char *)ip_buf, &(addr.sin_addr));
memcpy((char *)&rt.rt_genmask,(char *)&addr, sizeof(struct sockaddr_in));
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
return D_FAILURE;
}
/*SIOCADDRT ÓÃÓÚÔö¼Ó·ÓÉ*/
ret = ioctl(sockfd, SIOCADDRT, &rt);
close(sockfd);
if (0 != ret)
{
return D_FAILURE;
}
return D_SUCCESS;
}
设置ip
/******************************************************************
DG_AL_eth_chip_ip_to_dev
D_UINT8 *pIpaddr:
D_UINT8 *pSubnetmask:
D_UINT8 *pGateway:
D_SUCCESS
******************************************************************/
static D_INT32 DG_AL_eth_chip_ip_to_dev(D_UINT8 *pIpaddr,D_UINT8 *pSubnetmask,D_UINT8 *pGateway)
{
int sockfd;
struct ifreq ifr;
struct sockaddr_in *sin = NULL;
struct rtentry rt;
char ipbuf[20] = {0};
D_INT32 ret = D_SUCCESS;
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) <= 0)
{
DG_AL_TRACE(DG_AL_TRACE_ERROR_E, "%s: socket err. ", __func__);
return D_FAILURE;
}
SET_IP: /* ÉèÖÃIP */
if((NULL == pIpaddr) || (0 == pIpaddr[0]))
{
goto SET_NETMASK;
}
memset(&ifr, 0, sizeof(ifr));
memset(ipbuf, 0x00, 20);
strncpy(ifr.ifr_name, if_eth0, sizeof(ifr.ifr_name) -1);
sin = (struct sockaddr_in *)&ifr.ifr_addr;
sin->sin_family = AF_INET;
sprintf(ipbuf, "%d.%d.%d.%d", pIpaddr[0], pIpaddr[1], pIpaddr[2], pIpaddr[3]);
if(1 != inet_pton(AF_INET, ipbuf, &sin->sin_addr))
{
DG_AL_TRACE(DG_AL_TRACE_ERROR_E, "%s: IP inet_pton err. ", __func__);
ret = D_FAILURE;
goto SET_NETMASK;
}
if(ioctl(sockfd, SIOCSIFADDR, &ifr) < 0)
{
DG_AL_TRACE(DG_AL_TRACE_ERROR_E, "%s: IP ioctl err. ", __func__);
ret = D_FAILURE;
goto SET_NETMASK;
}
SET_NETMASK: /* ÉèÖÃ×ÓÍøÑÚÂë */
if((NULL == pSubnetmask) || (0 == pSubnetmask[0]))
{
goto SET_GATEWAY;
}
memset(&ifr, 0, sizeof(ifr));
memset(ipbuf, 0x00, 20);
strncpy(ifr.ifr_name, if_eth0, sizeof(ifr.ifr_name) -1);
sin = (struct sockaddr_in *)&ifr.ifr_netmask;
sin->sin_family = AF_INET;
sprintf(ipbuf, "%d.%d.%d.%d", pSubnetmask[0], pSubnetmask[1], pSubnetmask[2], pSubnetmask[3]);
if(1 != inet_pton(AF_INET, ipbuf, &sin->sin_addr))
{
DG_AL_TRACE(DG_AL_TRACE_ERROR_E, "%s: MASK inet_pton err. ", __func__);
ret = D_FAILURE;
goto SET_GATEWAY;
}
if(ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0)
{
DG_AL_TRACE(DG_AL_TRACE_ERROR_E, "%s: MASK ioctl err. ", __func__);
ret = D_FAILURE;
goto SET_GATEWAY;
}
SET_GATEWAY: /* ÉèÖÃÍø¹Ø */
if((NULL == pGateway) || (0 == pGateway[0]))
{
goto END;
}
#if 1
memset( &rt, 0, sizeof(rt) );
memset(ipbuf, 0x00, 20);
rt.rt_dev = if_eth0;
rt.rt_flags = RTF_UP | RTF_GATEWAY;
sin = (struct sockaddr_in *)&rt.rt_gateway;
sin->sin_family = AF_INET;
sprintf(ipbuf, "%d.%d.%d.%d", pGateway[0], pGateway[1], pGateway[2], pGateway[3]);
if(1 != inet_pton(AF_INET, ipbuf, &sin->sin_addr))
{
DG_AL_TRACE(DG_AL_TRACE_ERROR_E, "%s: GATE inet_pton err. ", __func__);
ret = D_FAILURE;
goto END;
}
memset(ipbuf, 0x00, 20);
sprintf(ipbuf, "%s", "0.0.0.0");
sin = (struct sockaddr_in *)&rt.rt_dst;
sin->sin_family = AF_INET;
if(1 != inet_pton(AF_INET, ipbuf, &sin->sin_addr))
{
DG_AL_TRACE(DG_AL_TRACE_ERROR_E, "%s: GATE inet_pton err. ", __func__);
ret = D_FAILURE;
goto END;
}
sin = (struct sockaddr_in *)&rt.rt_genmask;
sin->sin_family = AF_INET;
if(1 != inet_pton(AF_INET, ipbuf, &sin->sin_addr))
{
DG_AL_TRACE(DG_AL_TRACE_ERROR_E, "%s: GATE inet_pton err. ", __func__);
ret = D_FAILURE;
goto END;
}
if(ioctl(sockfd, SIOCADDRT, &rt) < 0)
{
DG_AL_TRACE(DG_AL_TRACE_ERROR_E, "%s: GATE ioctl err. ", __func__);
ret = D_FAILURE;
goto END;
}
#else
{
char str[64];
sprintf(str, "route add default gw %d.%d.%d.%d", pGateway[0], pGateway[1], pGateway[2], pGateway[3]);
// printf("%s",str);
if(system(str) < 0)
{
DG_AL_TRACE(DG_AL_TRACE_ERROR_E, "%s: GATE set err. ", __func__);
ret = D_FAILURE;
goto END;
}
}
#endif
END:
close(sockfd);
return ret;
}
设置mac
/******************************************************************
DG_AL_eth_chip_set_mac
******************************************************************/
static D_INT32 DG_AL_eth_chip_set_mac(D_UINT8 *pMac)
{
int fd;
struct ifreq ifr;
D_INT32 ret = 0;
if(pMac == NULL)
{
return D_FAILURE;
}
if (( fd = socket( AF_INET, SOCK_DGRAM, IPPROTO_IP )) <= 0)
{
DG_AL_TRACE(DG_AL_TRACE_DEBUG_E, "%s: socket err. ", __func__);
return D_FAILURE;
}
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, if_eth0, sizeof(ifr.ifr_name) - 1);
/*1.let eth down*/
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0)
{
close(fd);
DG_AL_TRACE(DG_AL_TRACE_DEBUG_E, "%s: ioctl err. ", __func__);
return D_FAILURE;
}
ifr.ifr_flags &= ~IFF_UP;
if(ioctl(fd, SIOCSIFFLAGS, (char *)&ifr) < 0)
{
close(fd);
DG_AL_TRACE(DG_AL_TRACE_DEBUG_E, "%s: ioctl err. ", __func__);
return D_FAILURE;
}
/*2.set mac */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, if_eth0, sizeof(ifr.ifr_name) - 1);
ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; /*ARPHRD_ETHER 1;*/
memcpy((char *)ifr.ifr_hwaddr.sa_data, (char *)pMac, ETH_MAC_LEN);
if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0)
{
DG_AL_TRACE(DG_AL_TRACE_DEBUG_E, "%s: ioctl err. ", __func__);
close(fd);
return D_FAILURE;
}
/*3.let eth up*/
ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0)
{
DG_AL_TRACE(DG_AL_TRACE_DEBUG_E, "%s: ioctl err. ", __func__);
close(fd);
return D_FAILURE;
}
close(fd);
return D_SUCCESS;
}
1.AF_INET方法获取
#include <stdio.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/if_arp.h>
#define MAXINTERFACES 16
int main(argc, argv)
register int argc;
register char *argv[];
{
register int fd, intrface, retn = 0;
struct ifreq buf[MAXINTERFACES];
struct arpreq arp;
struct ifconf ifc;
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
ifc.ifc_len = sizeof buf;
ifc.ifc_buf = (caddr_t) buf;
if (!ioctl(fd, SIOCGIFCONF, (char *) &ifc)) {
intrface = ifc.ifc_len / sizeof(struct ifreq);
printf("interface num is intrface=%d ", intrface);
while (intrface-- > 0) {
printf("net device %s ", buf[intrface].ifr_name);
/*Jugde whether the net card status is promisc*/
if (!(ioctl(fd, SIOCGIFFLAGS, (char *) &buf[intrface]))) {
if (buf[intrface].ifr_flags & IFF_PROMISC) {
puts("the interface is PROMISC");
retn++;
}
} else {
char str[256];
sprintf(str, "cpm: ioctl device %s",
buf[intrface].ifr_name);
perror(str);
}
/*Jugde whether the net card status is up*/
if (buf[intrface].ifr_flags & IFF_UP) {
puts("the interface status is UP");
} else {
puts("the interface status is DOWN");
}
/*Get IP of the net card */
if (!(ioctl(fd, SIOCGIFADDR, (char *) &buf[intrface]))) {
puts("IP address is:");
puts(inet_ntoa
(((struct sockaddr_in *) (&buf[intrface].
ifr_addr))->sin_addr));
puts("");
//puts (buf[intrface].ifr_addr.sa_data);
} else {
char str[256];
sprintf(str, "cpm: ioctl device %s",
buf[intrface].ifr_name);
perror(str);
}
/*Get HW ADDRESS of the net card */
if (!(ioctl(fd, SIOCGIFHWADDR, (char *) &buf[intrface]))) {
puts("HW address is:");
printf("%02x:%02x:%02x:%02x:%02x:%02x ",
(unsigned char) buf[intrface].ifr_hwaddr.
sa_data[0],
(unsigned char) buf[intrface].ifr_hwaddr.
sa_data[1],
(unsigned char) buf[intrface].ifr_hwaddr.
sa_data[2],
(unsigned char) buf[intrface].ifr_hwaddr.
sa_data[3],
(unsigned char) buf[intrface].ifr_hwaddr.
sa_data[4],
(unsigned char) buf[intrface].ifr_hwaddr.
sa_data[5]);
puts("");
puts("");
}
else {
char str[256];
sprintf(str, "cpm: ioctl device %s",
buf[intrface].ifr_name);
perror(str);
}
}
} else
perror("cpm: ioctl");
} else
perror("cpm: socket");
close(fd);
return retn;
}
2.PF_PACKET方法获取网卡地址
/* Low level network programming in Linux using PF_PACKET
* Need root privileges */
#include <stdio.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <linux/sockios.h>
int main(int argc, char **argv)
{
int i, sockfd;
static struct ifreq req;
struct sockaddr_ll inside_address;
/* Low level socket */
sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (sockfd < 0) {
perror("Unable to create low level socket: ");
exit(1);
}
memset(&inside_address, 0, sizeof(inside_address));
inside_address.sll_family = AF_PACKET;
inside_address.sll_protocol = htons(ETH_P_ALL);
inside_address.sll_hatype = ARPOP_REQUEST;
inside_address.sll_pkttype = PACKET_BROADCAST;
inside_address.sll_halen = 6;
strcpy(req.ifr_name, "eth1");
ioctl(sockfd, SIOCGIFINDEX, &req);
inside_address.sll_ifindex = req.ifr_ifindex;
ioctl(sockfd, SIOCGIFHWADDR, &req);
if (bind(sockfd, (struct sockaddr *) &inside_address,
sizeof(inside_address)) != 0) {
perror("Error:");
exit(1);
}
for (i = 0; i < 6; i++)
inside_address.sll_addr[i] =
(unsigned char) req.ifr_hwaddr.sa_data[i];
printf("%X ", inside_address.sll_ifindex);
for (i = 0; i < 5; i++) {
printf("%02X", inside_address.sll_addr[i]);
printf(":");
}
printf("%02X ", inside_address.sll_addr[i]);
close(sockfd);
return 0;
}
获取连接状态
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if.h>
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned char u8;
#include <linux/sockios.h>
#include <linux/ethtool.h>
// -1 -- error , details can check errno
// 1 -- interface link up
// 0 -- interface link down.
int get_netlink_status(const char *if_name)
{
int skfd;
struct ifreq ifr;
struct ethtool_value edata;
edata.cmd = ETHTOOL_GLINK;
edata.data = 0;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name) - 1);
ifr.ifr_data = (char *) &edata;
if (( skfd = socket( AF_INET, SOCK_DGRAM, 0 )) == 0)
return -1;
if(ioctl( skfd, SIOCETHTOOL, &ifr ) == -1)
{
close(skfd);
return -1;
}
close(skfd);
return edata.data;
}
D_INT32 DG_AL_eth_chip_link_status(D_UINT32 EthIndex)
{
D_INT32 fd;
struct ifreq ifr;
D_INT32 ret = 0;
char *if_eth = NULL;
if_eth = str_if_eth[EthIndex];
if (( fd = socket( AF_INET, SOCK_DGRAM, IPPROTO_IP )) <= 0)
{
DG_AL_TRACE(DG_AL_TRACE_DEBUG_E, "[AL-ETH]%s: socket err. ", __FUNCTION__);
return 0;
}
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, if_eth, sizeof(ifr.ifr_name) - 1);
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0)
{
close(fd);
DG_AL_TRACE(DG_AL_TRACE_DEBUG_E, "[AL-ETH]%s: ioctl err. ", __FUNCTION__);
return 0;
}
if ((ifr.ifr_flags & IFF_RUNNING) == 0)
{
ret = 0;
}
else
{
ret = 1;
}
close(fd);
return ret;
}