linux原始套接字编程之收发链路层广播(收端)
2015-11-04 13:58
666 查看
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if_ether.h>
#include <netpacket/packet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define ETH_ALEN 6
#define ETH_P_GATE 0x9006
#define ETH_MAX_DATA_LEN 1488
#define ETH_HEAD_LEN 16
#define ETH_BODY_LEN 1496
#define ETH_LEN ETH_HEAD_LEN + ETH_BODY_LEN
struct EtherHead
{
unsigned char dest[ETH_ALEN]; /* destinat ion eth addr */
unsigned char source[ETH_ALEN]; /* source e ther addr */
unsigned int proto; /* packet type ID field */
};
struct EtherBody
{
size_t datalen;
char data[ETH_MAX_DATA_LEN];
};
int main()
{
//创建原始套接字
int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_GATE));
if (0 > sock)
{
printf("create_sock err %s", strerror(errno));
return -1;
}
//获取网卡信息
struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));
memcpy(ifr.ifr_name, "eth0", strlen("eth0") + 1);
ifr.ifr_ifindex = if_nametoindex(ifr.ifr_name);
struct sockaddr_ll sk_ll;
sk_ll.sll_family = AF_PACKET;
sk_ll.sll_protocol = htons(ETH_P_GATE);
sk_ll.sll_hatype = 1;
sk_ll.sll_halen = ETH_ALEN;
sk_ll.sll_pkttype = PACKET_MULTICAST;
sk_ll.sll_ifindex = ifr.ifr_ifindex;//指定网卡
if(0 < bind(sock, (struct sockaddr *)&sk_ll, sizeof(struct sockaddr_ll)))
{
printf("bind err %s", strerror(errno));
exit(0);
}
void *buf = malloc(1512);
struct sockaddr_in recv;
socklen_t recvlen = 0;
while(1)
{
if(-1 == recvfrom(sock, buf, 1512, 0, (struct sockaddr *)&recv, &recvlen))
{
printf("sendto err %s", strerror(errno));
exit(-1);
}
//struct EtherBody *eth = NULL;
//memcpy(eth, buf+ETH_HEAD_LEN, ETH_BODY_LEN);
//printf("%s\n", eth->data);
printf("data:%s\n", ((struct EtherBody *)(buf+ETH_HEAD_LEN))->data);
sleep(1);
}
}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if_ether.h>
#include <netpacket/packet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define ETH_ALEN 6
#define ETH_P_GATE 0x9006
#define ETH_MAX_DATA_LEN 1488
#define ETH_HEAD_LEN 16
#define ETH_BODY_LEN 1496
#define ETH_LEN ETH_HEAD_LEN + ETH_BODY_LEN
struct EtherHead
{
unsigned char dest[ETH_ALEN]; /* destinat ion eth addr */
unsigned char source[ETH_ALEN]; /* source e ther addr */
unsigned int proto; /* packet type ID field */
};
struct EtherBody
{
size_t datalen;
char data[ETH_MAX_DATA_LEN];
};
int main()
{
//创建原始套接字
int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_GATE));
if (0 > sock)
{
printf("create_sock err %s", strerror(errno));
return -1;
}
//获取网卡信息
struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));
memcpy(ifr.ifr_name, "eth0", strlen("eth0") + 1);
ifr.ifr_ifindex = if_nametoindex(ifr.ifr_name);
struct sockaddr_ll sk_ll;
sk_ll.sll_family = AF_PACKET;
sk_ll.sll_protocol = htons(ETH_P_GATE);
sk_ll.sll_hatype = 1;
sk_ll.sll_halen = ETH_ALEN;
sk_ll.sll_pkttype = PACKET_MULTICAST;
sk_ll.sll_ifindex = ifr.ifr_ifindex;//指定网卡
if(0 < bind(sock, (struct sockaddr *)&sk_ll, sizeof(struct sockaddr_ll)))
{
printf("bind err %s", strerror(errno));
exit(0);
}
void *buf = malloc(1512);
struct sockaddr_in recv;
socklen_t recvlen = 0;
while(1)
{
if(-1 == recvfrom(sock, buf, 1512, 0, (struct sockaddr *)&recv, &recvlen))
{
printf("sendto err %s", strerror(errno));
exit(-1);
}
//struct EtherBody *eth = NULL;
//memcpy(eth, buf+ETH_HEAD_LEN, ETH_BODY_LEN);
//printf("%s\n", eth->data);
printf("data:%s\n", ((struct EtherBody *)(buf+ETH_HEAD_LEN))->data);
sleep(1);
}
}
相关文章推荐
- centos安装GO
- Linux 下 MySQL 启动与关闭 说明
- 解决linux下ssh登陆远程服务器出错
- linux sort 命令
- 鸟哥的Linux私房菜(基础篇)- 第二十二章、软件安装:原始码与 Tarball
- linux 下名称改为bogon
- Linux 安装FFmpeg
- Linux常用操作指令
- 鸟哥的Linux私房菜(基础篇)- 第二十章、启动流程、模块管理与 Loader
- 鸟哥的Linux私房菜(基础篇)- 第十九章、认识与分析登录文件
- 鸟哥的Linux私房菜(基础篇)- 第十八章、认识系统服务 (daemons)
- 鸟哥的Linux私房菜(基础篇)- 第十七章、程序管理与 SELinux 初探
- 鸟哥的Linux私房菜(基础篇)- 第十六章、例行性工作排程 (crontab)
- redhat系列linux使用本地的光盘镜像来制作一个yum安装源
- 鸟哥的Linux私房菜(基础篇)- 第十五章、磁碟配额(Quota)与进阶文件系统管理
- 鸟哥的Linux私房菜(基础篇)- 第十四章、Linux 账号管理与 ACL 权限配置
- CentOS6 Linux系统添加永久静态路由的方法
- Linux下配置安装PHP环境
- 鸟哥的Linux私房菜(基础篇)- 第十二章、正规表示法与文件格式化处理
- 鸟哥的Linux私房菜(基础篇)- 第十章、vim 程序编辑器