http://www.cnblogs.com/rollenholt/articles/2585432.html
http://blog.csdn.net/ctthuangcheng/article/details/9746501
http://www.cnblogs.com/rollenholt/articles/2585432.html
http://baike.baidu.com/link?url=PipBWz6NFljSSDX_q-AeKVO1shLJijhn4xU4iaOPAN9aaDkaQZvL3n10XCnur0rURR3-4Q6TA6HDw-N8DYR-Xq
http://wenku.baidu.com/link?url=gomqzjumyFcoIPceA9jZXdkazLIIbGR_xxF5cu11EZVqvTRVnqiH3sl30kUgoW5nZjZEB1TdTXFZm6UZRPfIce5W7fk1m6TD1N2pTii8Ycq
(sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) < 0 )//使用原始套接字,ETH_P_ALL可以获取所有经过本机的数据包,当然前提是网卡为混杂模式。
协议参数可选择的很多,这里列几个常用的。
strncpy(ethreq.ifr_name, "wlan0", IFNAMSIZ);//指定需要经过的网卡。
if( ioctl(sock, SIOCGIFFLAGS, ðreq) == -1 )//获得该网卡的接口信息。
{
perror("ioctl:");
close(sock);
exit(1);
}
ethreq.ifr_flags |= IFF_PROMISC;//设置成混杂模式。
if( ioctl(sock, SIOCSIFFLAGS, ðreq) == -1)//将网卡的接口信息写回。
{
perror("ioctl:");
close(sock);
exit(1);
}
struct ifreq
{
# define IFHWADDRLEN 6
# define IFNAMSIZ IF_NAMESIZE
union
{
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */
} ifr_ifrn;
union
{
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr ifru_netmask;
struct sockaddr ifru_hwaddr;
short int ifru_flags;
int ifru_ivalue;
int ifru_mtu;
struct ifmap ifru_map;
char ifru_slave[IFNAMSIZ]; /* Just fits the size */
char ifru_newname[IFNAMSIZ];
__caddr_t ifru_data;
} ifr_ifru;
};
# define ifr_name ifr_ifrn.ifrn_name /* interface name*/ 在这里就是网卡eth0或eth1
# define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ mac地址
# define ifr_addr ifr_ifru.ifru_addr /* address */ source地址
# define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */ 目的ip地址
# define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ 广播地址
# define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */ 子网掩码
# define ifr_flags ifr_ifru.ifru_flags /* flags */ 模式标志 设置混杂模式
# define ifr_metric ifr_ifru.ifru_ivalue /* metric */
# define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
# define ifr_map ifr_ifru.ifru_map /* device map */
# define ifr_slave ifr_ifru.ifru_slave /* slave device */
# define ifr_data ifr_ifru.ifru_data /* for use by interface */
# define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */
# define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */
# define ifr_qlen ifr_ifru.ifru_ivalue /* queue length */
# define ifr_newname ifr_ifru.ifru_newname /* New name */
# define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
# define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
# define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
recvfrom(sock, buffer, MAXLINE, 0, NULL, NULL);//接收通过网卡的信息。
#include "mysock.h"
#include "analysis.h"
unsigned int sec = 3;
void alarm_h()
{
sec = 0;
// printf("*************alarm*****************\n");
}
int main()
{
int sock;
unsigned char buffer[MAXLINE];//接收缓冲区,以太网环境中ip数据包长度规定为46-1500,加上mac层的14(mac帧最后的4字节crc不包括在内),为64-1518,不过貌似再长了可以分片自己重组。
int n = 0;
struct ifreq ethreq;
if( (sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0 )//使用原始套接字,ETH_P_ALL可以获取所有经过本机的数据包,当然前提是网卡为混杂模式。
{
perror("socket:");
exit(1);
}
strncpy(ethreq.ifr_name, "wlan0", IFNAMSIZ);//指定需要经过的网卡。
if( ioctl(sock, SIOCGIFFLAGS, ðreq) == -1 )//获得该网卡的接口信息。
{
perror("ioctl:");
close(sock);
exit(1);
}
ethreq.ifr_flags |= IFF_PROMISC;//设置成混杂模式。
if( ioctl(sock, SIOCSIFFLAGS, ðreq) == -1)//将网卡的接口信息写回。
{
perror("ioctl:");
close(sock);
exit(1);
}
struct sigaction newact, oldact;//使用SIGALRM信号计时。
newact.sa_handler = alarm_h;//信号处理函数
sigemptyset(&newact.sa_mask);//清空屏蔽字
newact.sa_flags = 0;
while(1)
{
sigaction(SIGALRM, &newact, &oldact);//改变该信号的默认行为,旧的存在oldact中,使用之后别忘了还回来。
printf("input seconds:\t");
scanf("%d", &sec);//请用户输入信息。
alarm(sec);//开始计时。sec若为0关闭计时。
while(sec > 0)//计时时间到的时候,SIFALRM信号的处理函数会将sec置零。
{
printf("-----\n");
n = recvfrom(sock, buffer, MAXLINE, 0, NULL, NULL);//接收通过网卡的信息。
if(n < 0)
{
perror("recvform:");
continue;
}
printf("recv %d bytes!\n", n);
int i;
for(i = 0 ; i < n ; i++)
{
printf("%02x\t", buffer[i]);//打印信息
if( (i+1)%12 == 0)
printf("\n");
}
printf("\n");
analysis_mac(buffer);//解析数据包。这里只能解析IP数据报。
}
alarm(0);//停止计时器。
sigaction(SIGALRM, &oldact, NULL);//改成默认行为。
}
return 0;
}