赞
踩
七层网络设计
利用netmap拿到传输到服务端的原始数据;它是由mmap将网卡的数据映射到内存中;使用nm_open("eth0",NULL,0,NULL)返回的fd是指向网卡的,当网卡里面来数据时就可以通过fd来知晓,操作数据是操作内存里面的数据
1:客户端会定时的发生arp请求
2:将服务器的IP地址,mac地址记录在客户端的ARP表当中;如果服务器没有回应就不会记录。
ARP表的作用是发送给服务器的包,查看服务器的地址是否在ARP表当中,如果没有就不会进行发送
- #include <stdio.h>
-
- #include <sys/poll.h>
- #include <arpa/inet.h>
-
- #define NETMAP_WITH_LIBS
-
- #include <net/netmap_user.h>
-
- #pragma pack(1)
-
-
- #define ETH_ADDR_LENGTH 6
-
- #define PROTO_IP 0x0800
- #define PROTO_ARP 0x0806
- #define PROTO_UDP 17
- #define PROTO_ICMP 1
-
-
- struct ethhdr {
- unsigned char h_dst[ETH_ADDR_LENGTH];//源mac地址
- unsigned char h_src[ETH_ADDR_LENGTH];//目的mac地址
- unsigned short h_proto;//协议,保存的是上层的协议,是IP协议还是ICMP协议,还是其他的协议
-
- }; // 14
-
-
- struct iphdr {
-
- unsigned char hdrlen:4,
- version:4; // 0x45
-
-
- unsigned char tos;
-
- unsigned short totlen;
-
- unsigned short id;
-
- unsigned short flag_offset; //
-
- unsigned char ttl; //time to livem,默认为64,每过一个网关就减一
- // 0x1234// htons
-
- unsigned char type;//传输层协议是udp,还是tcp,
-
- unsigned short check;//校验值
-
- unsigned int sip;//源ip
- unsigned int dip;//目的Ip
-
- }; // 20
-
-
-
- struct udphdr {
-
- unsigned short sport;//源端口号
- unsigned short dport;//目的端口号
-
- unsigned short length;//udp总长度
- unsigned short check;
-
- }; // 8
-
-
- struct udppkt {
-
- struct ethhdr eh; // 14
- struct iphdr ip; // 20
- struct udphdr udp; // 8
-
- unsigned char data[0];
-
- }; // sizeof(struct udppkt) ==
-
-
- struct arphdr {
-
- unsigned short h_type;
- unsigned short h_proto;
-
- unsigned char h_addrlen;
- unsigned char h_protolen;
-
- unsigned short oper;
-
- unsigned char smac[ETH_ADDR_LENGTH];
- unsigned int sip;
-
- unsigned char dmac[ETH_ADDR_LENGTH];
- unsigned int dip;
- };
-
- struct arppkt {
-
- struct ethhdr eh;
- struct arphdr arp;
-
- };
-
-
-
- int str2mac(char *mac, char *str) {
-
- char *p = str;
- unsigned char value = 0x0;
- int i = 0;
-
- while (p != '\0') {
-
- if (*p == ':') {
- mac[i++] = value;
- value = 0x0;
- } else {
-
- unsigned char temp = *p;
- if (temp <= '9' && temp >= '0') {
- temp -= '0';
- } else if (temp <= 'f' && temp >= 'a') {
- temp -= 'a';
- temp += 10;
- } else if (temp <= 'F' && temp >= 'A') {
- temp -= 'A';
- temp += 10;
- } else {
- break;
- }
- value <<= 4;
- value |= temp;
- }
- p ++;
- }
-
- mac[i] = value;
-
- return 0;
- }
-
-
- //回应arp
- void echo_arp_pkt(struct arppkt *arp, struct arppkt *arp_rt, char *mac) {
-
- memcpy(arp_rt, arp, sizeof(struct arppkt));
-
- memcpy(arp_rt->eh.h_dst, arp->eh.h_src, ETH_ADDR_LENGTH);
- str2mac(arp_rt->eh.h_src, mac);
- arp_rt->eh.h_proto = arp->eh.h_proto;
-
- arp_rt->arp.h_addrlen = 6;
- arp_rt->arp.h_protolen = 4;
- arp_rt->arp.oper = htons(2);
-
- str2mac(arp_rt->arp.smac, mac);
- arp_rt->arp.sip = arp->arp.dip;
-
- memcpy(arp_rt->arp.dmac, arp->arp.smac, ETH_ADDR_LENGTH);
- arp_rt->arp.dip = arp->arp.sip;
-
- }
-
- //
- int main() {
-
- struct nm_pkthdr h;
- struct nm_desc *nmr = nm_open("netmap:eth0", NULL, 0, NULL);
- if (nmr == NULL) return -1;
-
- struct pollfd pfd = {0};
- pfd.fd = nmr->fd;
- pfd.events = POLLIN;
-
- while (1) {
-
- int ret = poll(&pfd, 1, -1);
- if (ret < 0) continue;
-
- if (pfd.revents & POLLIN) {
-
- unsigned char *stream = nm_nextpkt(nmr, &h);
-
- struct ethhdr *eh = (struct ethhdr *)stream;
- if (ntohs(eh->h_proto) == PROTO_IP) {//如果是IP协议
-
- struct udppkt *udp = (struct udppkt *)stream;
-
- if (udp->ip.type == PROTO_UDP) { //如果是udp协议就直接打印
-
- int udplength = ntohs(udp->udp.length);
-
- udp->data[udplength-8] = '\0';
-
- printf("udp --> %s\n", udp->data);
-
- } else if (udp->ip.type == PROTO_ICMP) {//这个是处理ping的请求
-
-
-
- }
-
-
- } else if (ntohs(eh->h_proto) == PROTO_ARP) {//如果是arp协议
-
- struct arppkt *arp = (struct arppkt *)stream;
-
- struct arppkt arp_rt;
-
- if (arp->arp.dip == inet_addr("192.168.0.123")) { //
-
- echo_arp_pkt(arp, &arp_rt, "00:50:56:33:1c:ca");
-
- nm_inject(nmr, &arp_rt, sizeof(arp_rt));
-
- printf("arp ret\n");
-
- }
-
- }
-
- }
-
- }
-
-
-
- }
-
-
-
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。