主要应用方向是上位机和嵌软(如stm32单片机)通讯,不在单片机中嵌入web server,即mac层通讯。
一、下面先了解网络数据包组成。
常见数据包的包头长度:
EtherHeader Length: 14 Bytes
TCP Header Length : 20 Bytes
UDP Header Length : 8 Bytes
IP Header Length : 20 Bytes
1.网络封包的整体过程
2.IP 数据包
3.Tcp 数据包
4.UDP 数据包
5、Ethernet Header:
6、ICMP Packet:
7、ARP Packet:
二、程序接收报文示例
*************************UDP Packet******************************
Ethernet Header|-Source Address : 00-0C-29-64-D9-F5|-Destination Address : FF-FF-FF-FF-FF-FF|-Protocol : 8IP Header|-Version : 4|-Internet Header Length : 5 DWORDS or 20 Bytes|-Type Of Service : 16|-Total Length : 33 Bytes|-Identification : 10201|-Time To Live : 64|-Protocol : 17|-Header Checksum : 37369|-Source IP : 0.0.0.0|-Destination IP : 192.168.0.66UDP Header|-Source Port : 23451|-Destination Port : 23452|-UDP Length : 13|-UDP Checksum : 0DataAA BB CC DD EE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*****************************************************************
三、程序示例
程序环境:ubuntu 14.04 send(虚拟机,自定义模式 VMnet1)
Ubuntu 16.04 recv(虚拟机,自定义模式 VMnet1)
1、send
int main()
{sock_raw=socket(AF_PACKET,SOCK_RAW,IPPROTO_RAW);if(sock_raw == -1)printf("error in socket");// increase in case of large data.Here data is --> AA BB CC DD EEsendbuff=(unsigned char*)malloc(64); memset(sendbuff,0,64);get_eth_index(); // interface numberget_mac();get_ip();struct sockaddr_ll sadr_ll;
// sadr_ll.sll_ifindex = ifreq_i.ifr_ifindex;sadr_ll.sll_ifindex = if_nametoindex("eth0");sadr_ll.sll_halen = ETH_ALEN;sadr_ll.sll_addr[0] = DESTMAC0;sadr_ll.sll_addr[1] = DESTMAC1;sadr_ll.sll_addr[2] = DESTMAC2;sadr_ll.sll_addr[3] = DESTMAC3;sadr_ll.sll_addr[4] = DESTMAC4;sadr_ll.sll_addr[5] = DESTMAC5;printf("sending...\n");while(1){send_len = sendto(sock_raw,sendbuff,64,0,(const struct sockaddr*)&sadr_ll,sizeof(struct sockaddr_ll));if(send_len<0){printf("error in sending....sendlen=%d....errno=%d\n",send_len,errno);return -1;}}
}
2、recv
/* Note: run this program as root user* Author:Subodh Saxena */
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<signal.h>
#include<stdbool.h>
#include<sys/socket.h>
#include<sys/types.h>#include<linux/if_packet.h>
#include<netinet/in.h>
#include<netinet/if_ether.h> // for ethernet header
#include<netinet/ip.h> // for ip header
#include<netinet/udp.h> // for udp header
#include<netinet/tcp.h>
#include<arpa/inet.h> // to avoid warning at inet_ntoaFILE* log_txt;
int total,tcp,udp,icmp,igmp,other,iphdrlen;struct sockaddr saddr;
struct sockaddr_in source,dest;void ethernet_header(unsigned char* buffer,int buflen)
{struct ethhdr *eth = (struct ethhdr *)(buffer);fprintf(log_txt,"\nEthernet Header\n");fprintf(log_txt,"\t|-Source Address : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",eth->h_source[0],eth->h_source[1],eth->h_source[2],eth->h_source[3],eth->h_source[4],eth->h_source[5]);fprintf(log_txt,"\t|-Destination Address : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",eth->h_dest[0],eth->h_dest[1],eth->h_dest[2],eth->h_dest[3],eth->h_dest[4],eth->h_dest[5]);fprintf(log_txt,"\t|-Protocol : %d\n",eth->h_proto);}void ip_header(unsigned char* buffer,int buflen)
{struct iphdr *ip = (struct iphdr*)(buffer + sizeof(struct ethhdr));iphdrlen =ip->ihl*4;memset(&source, 0, sizeof(source));source.sin_addr.s_addr = ip->saddr; memset(&dest, 0, sizeof(dest));dest.sin_addr.s_addr = ip->daddr; fprintf(log_txt , "\nIP Header\n");fprintf(log_txt , "\t|-Version : %d\n",(unsigned int)ip->version);fprintf(log_txt , "\t|-Internet Header Length : %d DWORDS or %d Bytes\n",(unsigned int)ip->ihl,((unsigned int)(ip->ihl))*4);fprintf(log_txt , "\t|-Type Of Service : %d\n",(unsigned int)ip->tos);fprintf(log_txt , "\t|-Total Length : %d Bytes\n",ntohs(ip->tot_len));fprintf(log_txt , "\t|-Identification : %d\n",ntohs(ip->id));fprintf(log_txt , "\t|-Time To Live : %d\n",(unsigned int)ip->ttl);fprintf(log_txt , "\t|-Protocol : %d\n",(unsigned int)ip->protocol);fprintf(log_txt , "\t|-Header Checksum : %d\n",ntohs(ip->check));fprintf(log_txt , "\t|-Source IP : %s\n", inet_ntoa(source.sin_addr));fprintf(log_txt , "\t|-Destination IP : %s\n",inet_ntoa(dest.sin_addr));
}void payload(unsigned char* buffer,int buflen)
{int i=0;unsigned char * data = (buffer + iphdrlen + sizeof(struct ethhdr) + sizeof(struct udphdr));fprintf(log_txt,"\nData\n");int remaining_data = buflen - (iphdrlen + sizeof(struct ethhdr) + sizeof(struct udphdr));for(i=0;i<remaining_data;i++){if(i!=0 && i%16==0)fprintf(log_txt,"\n");fprintf(log_txt," %.2X ",data[i]);}fprintf(log_txt,"\n");}void tcp_header(unsigned char* buffer,int buflen)
{fprintf(log_txt,"\n*************************TCP Packet******************************");ethernet_header(buffer,buflen);ip_header(buffer,buflen);struct tcphdr *tcp = (struct tcphdr*)(buffer + iphdrlen + sizeof(struct ethhdr));fprintf(log_txt , "\nTCP Header\n");fprintf(log_txt , "\t|-Source Port : %u\n",ntohs(tcp->source));fprintf(log_txt , "\t|-Destination Port : %u\n",ntohs(tcp->dest));fprintf(log_txt , "\t|-Sequence Number : %u\n",ntohl(tcp->seq));fprintf(log_txt , "\t|-Acknowledge Number : %u\n",ntohl(tcp->ack_seq));fprintf(log_txt , "\t|-Header Length : %d DWORDS or %d BYTES\n" ,(unsigned int)tcp->doff,(unsigned int)tcp->doff*4);fprintf(log_txt , "\t|----------Flags-----------\n");fprintf(log_txt , "\t\t|-Urgent Flag : %d\n",(unsigned int)tcp->urg);fprintf(log_txt , "\t\t|-Acknowledgement Flag : %d\n",(unsigned int)tcp->ack);fprintf(log_txt , "\t\t|-Push Flag : %d\n",(unsigned int)tcp->psh);fprintf(log_txt , "\t\t|-Reset Flag : %d\n",(unsigned int)tcp->rst);fprintf(log_txt , "\t\t|-Synchronise Flag : %d\n",(unsigned int)tcp->syn);fprintf(log_txt , "\t\t|-Finish Flag : %d\n",(unsigned int)tcp->fin);fprintf(log_txt , "\t|-Window size : %d\n",ntohs(tcp->window));fprintf(log_txt , "\t|-Checksum : %d\n",ntohs(tcp->check));fprintf(log_txt , "\t|-Urgent Pointer : %d\n",tcp->urg_ptr);payload(buffer,buflen);fprintf(log_txt,"*****************************************************************\n\n\n");
}void udp_header(unsigned char* buffer, int buflen)
{fprintf(log_txt,"\n*************************UDP Packet******************************");ethernet_header(buffer,buflen);ip_header(buffer,buflen);fprintf(log_txt,"\nUDP Header\n");struct udphdr *udp = (struct udphdr*)(buffer + iphdrlen + sizeof(struct ethhdr));fprintf(log_txt , "\t|-Source Port : %d\n" , ntohs(udp->source));fprintf(log_txt , "\t|-Destination Port : %d\n" , ntohs(udp->dest));fprintf(log_txt , "\t|-UDP Length : %d\n" , ntohs(udp->len));fprintf(log_txt , "\t|-UDP Checksum : %d\n" , ntohs(udp->check));payload(buffer,buflen);fprintf(log_txt,"*****************************************************************\n\n\n");}void data_process(unsigned char* buffer,int buflen)
{struct iphdr *ip = (struct iphdr*)(buffer + sizeof (struct ethhdr));++total;/* we will se UDP Protocol only*/ switch (ip->protocol) //see /etc/protocols file {case 6:++tcp;
// tcp_header(buffer,buflen);break;case 17:++udp;udp_header(buffer,buflen);break;default:++other;}printf("TCP: %d UDP: %d Other: %d Toatl: %d \r",tcp,udp,other,total);}int main()
{int sock_r,saddr_len,buflen;unsigned char* buffer = (unsigned char *)malloc(65536); memset(buffer,0,65536);log_txt=fopen("log.txt","w");if(!log_txt){printf("unable to open log.txt\n");return -1;}printf("starting .... \n");sock_r=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL)); if(sock_r<0){printf("error in socket\n");return -1;}while(1){saddr_len=sizeof saddr;buflen=recvfrom(sock_r,buffer,65536,0,&saddr,(socklen_t *)&saddr_len);if(buflen<0){printf("error in reading recvfrom function\n");return -1;}fflush(log_txt);data_process(buffer,buflen);}close(sock_r);// use signals to close socket printf("DONE!!!!\n");}
如需完成发送程序,可关注公众号后,后台留言,说明所需程序。
欢迎关注公众号: