不使用ip和port如何进行网络通讯(raw socket应用例子)

主要应用方向是上位机和嵌软(如stm32单片机)通讯,不在单片机中嵌入web server,即mac层通讯。

一、下面先了解网络数据包组成。

常见数据包的包头长度:

EtherHeader Length: 14 Bytes
TCP Header Length  : 20 Bytes
UDP Header Length  : 8  Bytes
IP Header Length   : 20 Bytes

1.网络封包的整体过程

不使用ip和port如何进行网络通讯(raw socket应用例子)_第1张图片

2.IP 数据包

不使用ip和port如何进行网络通讯(raw socket应用例子)_第2张图片

3.Tcp 数据包

不使用ip和port如何进行网络通讯(raw socket应用例子)_第3张图片不使用ip和port如何进行网络通讯(raw socket应用例子)_第4张图片

4.UDP 数据包

不使用ip和port如何进行网络通讯(raw socket应用例子)_第5张图片

不使用ip和port如何进行网络通讯(raw socket应用例子)_第6张图片

5、Ethernet Header:

不使用ip和port如何进行网络通讯(raw socket应用例子)_第7张图片

6、ICMP Packet:

不使用ip和port如何进行网络通讯(raw socket应用例子)_第8张图片

不使用ip和port如何进行网络通讯(raw socket应用例子)_第9张图片

7、ARP Packet:

不使用ip和port如何进行网络通讯(raw socket应用例子)_第10张图片

二、程序接收报文示例

*************************UDP Packet******************************
Ethernet Header
  |-Source Address  : 00-0C-29-64-D9-F5
  |-Destination Address  : FF-FF-FF-FF-FF-FF
  |-Protocol    : 8


IP 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.66


UDP Header
  |-Source Port      : 23451
  |-Destination Port  : 23452
  |-UDP Length        : 13
  |-UDP Checksum     : 0


Data
 AA  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  EE
  sendbuff=(unsigned char*)malloc(64); 
  memset(sendbuff,0,64);




        get_eth_index();  // interface number
        get_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
#include
#include
#include
#include
#include
#include


#include
#include     
#include    // for ethernet header
#include    // for ip header
#include    // for udp header
#include
#include           // to avoid warning at inet_ntoa


FILE* 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;isource));
     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");


}

如需完成发送程序,可关注公众号后,后台留言,说明所需程序。

欢迎关注公众号:

不使用ip和port如何进行网络通讯(raw socket应用例子)_第11张图片

你可能感兴趣的:(tcp/ip,网络协议,网络)