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

news2024/12/28 5:38:52

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

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

常见数据包的包头长度:

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

1.网络封包的整体过程

b9862fea2f087d3b67094930ca880936.jpeg

2.IP 数据包

ebe7e9e778a89d7d0a9bd7fbd266818f.jpeg

3.Tcp 数据包

f763a400c69a49311c807b249ae4496a.jpeg7b1c612c34741ef7baac1e79edae9321.jpeg

4.UDP 数据包

4e2df6d230034d23311d2400c5166cfa.jpeg

0c2adb2da346d1c29b7fcb33713a6220.jpeg

5、Ethernet Header:

fdd860a2aceebbf59b8ef1b60712b65f.jpeg

6、ICMP Packet:

7f10af18128e0f93ec9a62d1b03761ba.jpeg

82472f4e781681fc355abb288f78d455.jpeg

7、ARP Packet:

32a04db59f20953a00cacb832e283881.jpeg

二、程序接收报文示例

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


}

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

欢迎关注公众号:

a4d4be1bb5bfc305e601ecf99bdf86bb.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/937751.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于unity的轻量配置工具开发

工具结构&#xff1a;针对每张表格生成一个表格类&#xff0c;其中默认包含一个list和字典类型参数记录表格数据&#xff0c;初始化项目时将list中的数据转为按id索引的dictionary&#xff0c;用于访问数据。额外包含一个同名Temp后缀的类&#xff0c;记录表格的字段、备注等信…

李跳跳跳过APP开屏广告,附下载地址

最近&#xff0c;李跳跳APP宣布永久停止更新。据称&#xff0c;该应用导致了消费者权益的减损&#xff0c;被指构成不正当竞争&#xff0c;并因此遭受某大厂的投诉&#xff0c;甚至收到了一封法律函件的威胁。面对压力&#xff0c;最终李跳跳APP选择了退出舞台。 李跳跳APP是什…

cs231n assignment3 q3 Image Captioning with Transformers

文章目录 先啰嗦直接看代码Q3 Image Captioning with TransformersMultiHeadAttention.forward题面解析代码输出 Positional Encoding题面解析代码输出 transformer.forward题面解析代码输出 先啰嗦直接看代码 Q3 Image Captioning with Transformers MultiHeadAttention.for…

c++ style casting

https://www.youtube.com/watch?vUfrR1nNfoeY&listPLE28375D4AC946CC3&index17

Python3 列表

Python3 列表 序列是 Python 中最基本的数据结构。 序列中的每个值都有对应的位置值&#xff0c;称之为索引&#xff0c;第一个索引是 0&#xff0c;第二个索引是 1&#xff0c;依此类推。 Python 有 6 个序列的内置类型&#xff0c;但最常见的是列表和元组。 列表都可以进…

TensorBoard的使用

TensorBoard&#xff1a;对图像进行变换 1. SummaryWriter的使用 ctrl类出现注释解析&#xff1a; 将条目直接log_dir写入要成为由TensorBoard使用。 “摘要编写器”类提供了一个高级 API 来创建事件文件&#xff0c;并在给定目录中添加摘要和事件。该类更新文件内容异步。…

Python系统监控利器

迷途小书童的 Note 读完需要 3分钟 速读仅需 1 分钟 1 简介 计算机系统监控对保证服务质量和排查故障非常重要。psutil 是一个用于 Python 的跨平台系统监控和过程管理工具&#xff0c;为我们提供便捷的监控方案。 2 基本工作原理 psutil 使用 Python 封装了系统调用&#xff0…

C++学习记录——이십팔 C++11(4)

文章目录 包装器1、functional2、绑定 这一篇比较简短&#xff0c;只是因为后要写异常和智能指针&#xff0c;所以就把它单独放在了一篇博客&#xff0c;后面新开几篇博客来写异常和智能指针 包装器 1、functional 包装器是一个类模板&#xff0c;对可调用对象类型进行再封装…

安全学习DAY20_自动化工具项目武器库介绍

信息打点-自动化工具 文章目录 信息打点-自动化工具本节思维导图&概述 各类红蓝队优秀工具项目集合&#xff1a;All-Defense-Tool 自动化-武器库部署F8x 自动化信息搜集-网络空间AsamF 自动化信息搜集-企查信息ENScan 自动化信息搜集-综合架构-ARL&NemoARL灯塔Nemo_Go …

MySQL 特殊语法时间格式以及Greadb连接

一、时间语法 DATE_FORMAT和to_char() select to_char(now(),%Y-%m-%d %H:%i:%s) from dual; select DATE_FORMAT(now(),%Y-%m-%d %H:%i:%s) from dual; 2.to_date() 和STR_TO_DATE(#{date},%Y-%m-%d ) select to_date(now(),yyyy-mm-dd hh24:mi:ss) from dual;

null和undefined区别

1.undefined&#xff0c;表示无值。 比如下面场景&#xff1a; a. 变量被声明了&#xff0c;但是没有被赋值&#xff1b; b. 调用函数的时候&#xff0c;应该给函数传参却没有给函数传这个参数打印出来就是 undefined&#xff1b; c. 访问一个对象中没有的属性&#xff1b;…

Blender给一个对象添加多个动画

最近在做一个类似元宇宙的项目&#xff0c;需要使用3D建模软件来给3D模型添加动画&#xff0c;3D建模软件选择Blender&#xff08;因为开源免费…&#xff09;&#xff0c;版本: V3.5 遇到的需求是同一个对象要添加多个动画&#xff0c;然后在代码里根据需要调取动画来执行。本…

飞腾CPU FT-2000/4 uboot下PHY调试记录

一、环境说明 板子是FT-2000/4的开发板: 固件版本: ft-2004c_u-boot-v2-Ver0.3_202112231001.tar.gz ft2004c_v2.06_image_fix.rar 二、调试命令说明 调试PHY主要用到的命令是mii,先查看下可用的命令: mii device,缩写mii dev,查看网络控制器mac。mii device,缩写mi…

【C++】初始化列表

前言&#xff1a;这个知识点的细节比较多&#xff0c;且有些细节不太容易理解&#xff0c;要做好准备哟&#x1f47b; Ⅰ.构造函数的不完美&#x1f62d; 初始化列表&#xff0c;顾名思义&#xff0c;用列表一样的格式将其初始化。 &#x1f914;奇怪啊&#xff0c;构造函数的…

DOCKER 部署 webman项目

# 设置基础镜像 FROM php:8.2-fpm# 安装必要的软件包和依赖项 RUN apt-get update && apt-get install -y \nginx \libzip-dev \libpng-dev \libjpeg-dev \libfreetype6-dev \&& rm -rf /var/lib/apt/lists/*# 安装 PHP 扩展 RUN docker-php-ext-configure gd …

Uniapp笔记(八)初识微信小程序

一、微信小程序基本介绍 1、什么是微信小程序 微信小程序简称小程序&#xff0c;英文名Mini Program&#xff0c;是一种不需要下载安装即可使用的应用&#xff0c;它实现了应用“触手可及”的梦想&#xff0c;用户扫一扫或搜一下即可打开应用 小程序是一种新的开放能力&#…

嵌入式学习之指针

今天周天&#xff0c;主要对linux系统编程的知识进行了学习&#xff0c;但是很多精华还是没有学到位&#xff0c;重点的学习内容是把linux 中open,write,lseek,close的相关操作进行了学习。其次再次把函数指针&#xff0c;数组指针&#xff0c;指针函数&#xff0c;指针数组进行…

线性代数的学习和整理13: 函数与向量/矩阵

目录 1 函数与 向量/矩阵 2 函数的定义域&#xff0c;值域&#xff0c;到达域 3 对应关系 1 函数与 向量/矩阵 下面两者形式类似&#xff0c;本质也类似 函数的&#xff1a; axy &#xff0c;常规函数里&#xff0c;a,x,y 一般都是单个数矩阵&#xff1a; AXY &a…

[管理与领导-54]:IT基层管理者 - 扩展技能 - 1 - 时间管理 -1- 时间管理的基本理念和五大原则

前言&#xff1a; 管理学大师彼得 德鲁克曾说过:“不能管理时间&#xff0c;便什么也不能管理” 。论语中说&#xff1a;逝者如斯 夫!不舍昼夜。时间对任何一个人来说都是十分重要的&#xff0c;对于惜时如金的管理者来说更是如此。 时间也是一种资源&#xff0c;对所有的人…

TIM输入捕获笔记 (计算编码电机的频率和占空比)

1. 输入捕获简介 IC (Input Capture) 输入捕获输入捕获模式下&#xff0c;当通道输入引脚出现指定电平跳变时&#xff0c;当前CNT的值将被锁存到CCR中&#xff0c;可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数每个高级定时器和通用定时器都拥有4个输入捕获…