Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在linux上拦截IP数据包_Linux_Ip_Intercept_Packets - Fatal编程技术网

如何在linux上拦截IP数据包

如何在linux上拦截IP数据包,linux,ip,intercept,packets,Linux,Ip,Intercept,Packets,我正试图在Linux上实现这一目标(不确定这是否可行以及如何实现): 我需要编写一个程序来截获接口上的所有IP数据包,并将该数据包传递给一组特定的用户空间程序。我的意思是,我的程序(可能是内核模块或特殊的用户空间程序)捕获了一个IP数据包,然后这个数据包不再经过IP堆栈。例如,假设操作系统正在运行许多进程(在内核空间或用户空间),a、B、C、D……等等。如果在接口处接收到IP数据包,比如eth2,我只希望a、B看到这个数据包,所有其他进程甚至都知道这个数据包的存在。 有人能给我指出正确的方向吗?

我正试图在Linux上实现这一目标(不确定这是否可行以及如何实现): 我需要编写一个程序来截获接口上的所有IP数据包,并将该数据包传递给一组特定的用户空间程序。我的意思是,我的程序(可能是内核模块或特殊的用户空间程序)捕获了一个IP数据包,然后这个数据包不再经过IP堆栈。例如,假设操作系统正在运行许多进程(在内核空间或用户空间),a、B、C、D……等等。如果在接口处接收到IP数据包,比如eth2,我只希望a、B看到这个数据包,所有其他进程甚至都知道这个数据包的存在。
有人能给我指出正确的方向吗?非常感谢

我建议您重新检查是否确实有必要按照您描述的方式拦截数据包。如上所述,这听起来好像你还没有完全理解网络是如何工作的

首先,除非您的程序以某种方式神奇地读取原始网络数据包,而不是使用标准套接字,否则它们无论如何都不会接收发送给彼此的流量。每个套接字都有一个与其关联的端口,并且只有一个进程可以绑定到同一主机中的同一端口(套接字实际上只是一对端口和一个主机地址)

如果您实际上正在程序中读取原始网络数据包,并且这是必要的,那么您很可能不应该在同一台主机上运行它们。相反,使用虚拟化将不允许在不同虚拟主机中看到彼此发送的数据包的程序放置在不同的虚拟主机中,从而将它们完全分离,而不是使用相当复杂的编程解决方案

如果其他一切都失败了,您可能想好好看看哪一个允许您捕获网络数据包,甚至可以同时从多个程序捕获。尽管您必须以root用户身份运行它们,但这对于将网络接口置于混杂模式等都是必要的。这里有一个简单的例子,可以从网络上阅读一些小东西,你可以从libpcap主页和相关的

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pcap.h>

/* IP header (from tcpdump examples) */
struct sniff_ip {
    u_char ip_vhl;          /* version << 4 | header length >> 2 */
    u_char ip_tos;          /* type of service */
    u_short ip_len;         /* total length */
    u_short ip_id;          /* identification */
    u_short ip_off;         /* fragment offset field */
    u_char ip_ttl;          /* time to live */
    u_char ip_p;            /* protocol */
    u_short ip_sum;         /* checksum */
    struct in_addr ip_src, ip_dst;  /* source and dest address */
};

/* callback function for pcap_loop */
void cllbck(u_char * args,
        const struct pcap_pkthdr *hdr, const u_char * pkt)
{
    const struct sniff_ip *ip = (struct sniff_ip *) (pkt + 14);

    fprintf(stderr, "Sniffed a packet with length %d.\n", hdr->len);
    fprintf(stderr, "IP version %d.\n", ip->ip_vhl >> 4);
}

int main(int argc, char *argv[])
{
    char *dev;                  /* device name */
    char errbuf[PCAP_ERRBUF_SIZE];      /* buffer for libpcap errmsgs */
    pcap_t *cap;                /* libpcap capture session */
    char *filt = "host 127.0.0.1";      /* capture filter */
    struct bpf_program fp;      /* compiled filter */
    struct pcap_pkthdr hdr;     /* packet header from libpcap */
    const u_char *pkt;          /* packet from libpcap */

    dev = strdup(argv[1]);
    if (dev == NULL) {
        fprintf(stderr, "Invalid device.\n");
        return 2;
    }

    /* open the device for live capture */
    cap = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
    if (cap == NULL) {
        fprintf(stderr, "Opening device `%s´ failed: %s\n", dev, errbuf);
        return 2;
    }

    /* compile the capture filter */
    if (pcap_compile(cap, &fp, filt, 0, PCAP_NETMASK_UNKNOWN) < 0) {
        fprintf(stderr, "Failed to parse filter `%s´: %s\n",
                filt, pcap_geterr(cap));
        return 2;
    }
    /* set the filter active for this session */
    if (pcap_setfilter(cap, &fp) == -1) {
        fprintf(stderr, "Couldn't install filter %s: %s\n",
                filt, pcap_geterr(cap));
        return 2;
    }

    /* pcap close will loop until an error if 2nd arg is < 0 */
    pcap_loop(cap, -1, cllbck, NULL);

    /* end session, pcap_loop has exited ie. an error has occurred */
    pcap_close(cap);

    return 0;
}

/* end of file */
#包括
#包括
#包括
#包括
#包括
#包括
/*IP头(来自tcpdump示例)*/
结构嗅探ip{
u_char ip_vhl;/*版本>2*/
u_char ip_tos;/*服务类型*/
u_短ip_len;/*总长度*/
u_短ip_id;/*标识*/
u_短ip_关闭;/*碎片偏移字段*/
u_char ip_ttl;/*生存时间*/
u_char ip_p;/*协议*/
u_short ip_sum;/*校验和*/
结构地址ip地址src,ip地址;/*源地址和目标地址*/
};
/*pcap_循环的回调函数*/
无效cllbck(u_char*args,
const struct pcap_pkthdr*hdr,const u_char*pkt)
{
const struct sniff_ip*ip=(struct sniff_ip*)(pkt+14);
fprintf(stderr,“嗅探长度为%d的数据包。\n”,hdr->len);
fprintf(标准,“IP版本%d.\n”,IP->IP_vhl>>4);
}
int main(int argc,char*argv[])
{
char*dev;/*设备名称*/
char errbuf[PCAP_errbuf_SIZE];/*用于libpcap errmsgs的缓冲区*/
pcap_t*cap;/*libpcap捕获会话*/
char*filt=“主机127.0.0.1”/*捕获筛选器*/
结构bpf_程序fp;/*编译过滤器*/
来自libpcap的struct pcap_pkthdr hdr;/*数据包头*/
来自libpcap的const u_char*pkt;/*数据包*/
dev=strdup(argv[1]);
如果(dev==NULL){
fprintf(stderr,“无效设备”。\n”);
返回2;
}
/*打开设备进行实时捕获*/
cap=pcap\u open\u live(dev,BUFSIZ,11000,errbuf);
如果(cap==NULL){
fprintf(stderr,“打开设备“%s”失败:%s\n”,dev,errbuf);
返回2;
}
/*编译捕获过滤器*/
如果(pcap_编译(cap、&fp、filt、0、pcap_网络掩码_未知)<0){
fprintf(stderr,“未能分析筛选器“%s”:%s\n”,
过滤器,pcap_geterr(cap));
返回2;
}
/*将此会话的筛选器设置为活动*/
如果(pcap_设置过滤器(cap和fp)=-1){
fprintf(stderr,“无法安装筛选器%s:%s\n”,
过滤器,pcap_geterr(cap));
返回2;
}
/*如果第二个参数<0,pcap close将循环直到出现错误*/
pcap_回路(cap,-1,cllbck,NULL);
/*结束会话,pcap_循环已退出,即发生错误*/
pcap_关闭(cap);
返回0;
}
/*文件结束*/

这似乎不是一个编程问题。我建议在我们的姐妹网站上提问。嗨,迈克尔,实际上我需要在我的程序中实现这个功能,这就是为什么我认为它与编程问题有关。