前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >不使用ip和port如何进行网络通讯(raw socket应用例子)

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

作者头像
用户5908113
发布2023-09-09 08:55:37
3590
发布2023-09-09 08:55:37
举报
文章被收录于专栏:Pou光明

主要应用方向是上位机和嵌软(如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:

二、程序接收报文示例

代码语言:javascript
复制
*************************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

代码语言:javascript
复制
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

代码语言:javascript
复制
/* 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_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;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");

}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Pou光明 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档