草庐IT

linux - 环回接口(interface)上的原始套接字是否可能?

coder 2023-06-18 原文

我们正在尝试通过原始套接字与监听 Linux 环回接口(interface)的服务器进行通信,服务器似乎没有从我们这里获得一个数据包。我们发送的数据包在 Wireshark 中是可见的。

环回上的原始套接字是否可能? (请不要问我们为什么需要它:这里解释起来太复杂了)

编辑:这就是我们打开它的方式

_I_RawSocket = socket( PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)))

memset( &ifr, 0, sizeof( ifr ) );
strcpy( ifr.ifr_ifrn.ifrn_name, _InterfaceName);

ioctl( _I_RawSocket, SIOCGIFINDEX, &ifr )

memset( &sll, 0, sizeof( sll ) );
sll.sll_family   = AF_PACKET;
sll.sll_ifindex  = ifr.ifr_ifindex;
sll.sll_protocol = htons( ETH_P_ALL );

bind( _I_RawSocket, (struct sockaddr *) &sll, sizeof( sll ))

服务器是 lighttpd,可以通过本地主机上的普通套接字访问。 netstat --raw 打印空表,但我绝对确定我们在普通 eth 设备上有两个功能性原始套接字。

最佳答案

原始套接字在使用 bind() 和 connect() 时表现特别不稳定,但我无法确认您的问题出在它们身上。我建议您采用更直接的方法:

发件人

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define DEST "127.0.0.1"

int main(int argc, char **argv)
{

 int s;
 struct sockaddr_in dst_addr;
 char packet[50];

 struct iphdr *ip = (struct iphdr *)packet;  

 if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
  perror("error:");
  exit(EXIT_FAILURE);
 }

 dst_addr.sin_family = AF_INET;
 dst_addr.sin_port = 0; /* not needed in SOCK_RAW */
 inet_pton(AF_INET, DEST, (struct in_addr *)&dst_addr.sin_addr.s_addr);
 memset(dst_addr.sin_zero, 0, sizeof(dst_addr.sin_zero));

 memset(packet, 'A', sizeof(packet));   /* payload will be all As */

 ip->ihl = 5;
 ip->version = 4;
 ip->tos = 0;
 ip->tot_len = htons(40);
 ip->frag_off = 0;  /* NF */
 ip->ttl = 64;
 ip->protocol = IPPROTO_RAW; /* this has to be IPPROTO_RAW */
 ip->check = 0;
 ip->saddr = dst_addr.sin_addr.s_addr;
 ip->daddr = dst_addr.sin_addr.s_addr;

 while(42) {
  sleep(5);
  if (sendto(s, packet, sizeof(packet), 0, 
   (struct sockaddr *)&dst_addr, (socklen_t)sizeof(dst_addr)) < 0)
   perror("uh oh:");
 }
 return(0);
}

接收者

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>


int main(int argc, char **argv)
{
 int s;
 struct sockaddr_in src_addr;
 char packet[50];

 if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
  perror("error:");
  exit(EXIT_FAILURE);
 }

 memset(packet, 0, sizeof(packet));
 socklen_t *len = (socklen_t *)sizeof(src_addr);
 int fromlen = sizeof(src_addr);

 while(42) {
  if (recvfrom(s, &packet, sizeof(packet), 0,
   (struct sockaddr *)&src_addr, &fromlen) < 0)
   perror("uh oh:");

  int i = sizeof(struct iphdr); /* print the payload */
  for(; i < sizeof(packet); i++) {
   printf("%c", packet[i]);
  }
  printf("\n");
 }
 return(0);
}

我希望它们的行为与您希望的完全一样。阅读 man 7 raw 以了解其工作原理的详细信息,更重要的是 man 7 packet 如果您想扩展它。另外,请注意 IPPROTO_RAW 暗示 IP_HDRINCL 套接字选项,这就是我们自己构建 ip header 的原因 - 尽管 IP 校验和和总长度仍然由内核计算和填充。

编辑:此外,如果您想要一个原始套接字来将有效数据发送到像 lighttpd 这样的应用程序,您必须将 protocol 参数与 socket() 并为 IP header 字段提供有效值。正确的以太网 header 不是强制性的 - 内核堆栈将为您填充唯一重要的字段。

关于linux - 环回接口(interface)上的原始套接字是否可能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3335277/

有关linux - 环回接口(interface)上的原始套接字是否可能?的更多相关文章

  1. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  2. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  3. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  4. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  5. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

  6. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  7. ruby-on-rails - Ruby - 如何从 ruby​​ 上的 .pfx 文件中提取公钥、rsa 私钥和 CA key - 2

    我有一个.pfx格式的证书,我需要使用ruby​​提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o

  8. ruby - 是否可以在不实际发送或读取数据的情况下查明 ruby​​ 套接字是否处于 ESTABLISHED 或 CLOSE_WAIT 状态? - 2

    s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成

  9. ruby-on-rails - Ruby 的 'open_uri' 是否在读取或失败后可靠地关闭套接字? - 2

    一段时间以来,我一直在使用open_uri下拉ftp路径作为数据源,但突然发现我几乎连续不断地收到“530抱歉,允许的最大客户端数(95)已经连接。”我不确定我的代码是否有问题,或者是否是其他人在访问服务器,不幸的是,我无法真正确定谁有问题。本质上,我正在读取FTPURI:defself.read_uri(uri)beginuri=open(uri).readuri=="Error"?nil:urirescueOpenURI::HTTPErrornilendend我猜我需要在这里添加一些额外的错误处理代码...我想确保我采取一切预防措施来关闭所有连接,这样我的连接就不是问题所在,但是我

  10. 带有 attr_accessor 的类上的 Ruby instance_eval - 2

    我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到

随机推荐