Linux でこの目標を達成しようとしています (可能かどうか、可能かどうかは不明です):インターフェイス上のすべての IP パケットをインターセプトし、このパケットを特定のユーザー空間プログラムのセットに配信するプログラムを作成する必要があります。 . インターセプトとは、IP パケットがプログラム (おそらくカーネル モジュールまたは特別なユーザー空間プログラム)によってキャプチャされ、このパケットが IP スタックを通過しないことを意味します。たとえば、OS が多くのプロセス (カーネル空間またはユーザー空間のいずれか)、A、B、C、D などを実行しているとします。IP パケットがインターフェイスで受信された場合、eth2 とします。 、私は A、B だけがこのパケットを見て、他のすべてのプロセスがこのパケットの存在さえ知っていることを望んでいます。誰かが私を正しい方向に導くことができますか? どうもありがとう!
1 に答える
私が提案するのは、あなたが説明した方法でパケットを傍受することが本当に必要かどうかを再検討することです. 上記のように、ネットワーキングの仕組みを完全には理解していないようです。
まず第一に、プログラムが魔法のように標準のソケットを使用する代わりに生のネットワーク パケットを読み取ることができない限り、いずれにせよ相互に宛てられたトラフィックを受信することはありません。各ソケットにはポートが関連付けられており、1 つのプロセスのみが同じホストの同じポートにバインドできます (ソケットは、実際にはポートとホスト アドレスのペアにすぎません)。
プログラムで生のネットワーク パケットを実際に読み取っていて、これが必要な場合は、それらを同じホストで実行するべきではありません。代わりに、仮想化を使用して、相互に宛てられたパケットを別の仮想ホストに表示することを許可されていないプログラムを配置し、かなり複雑なプログラムによるソリューションを使用する代わりに、それらを完全に分離します。
他のすべてが失敗した場合は、複数のプログラムから同時にネットワークパケットをキャプチャできるlibpcapをよく見てください。それらをルートとして実行する必要がありますが、ネットワークインターフェイスを無差別モードにするなどのために必要です。これは、ネットワークから何かを読み取るための簡単な例です。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 */