AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 77849528
Accepted
intrigued_66
intrigued_66
Asked: 2024-01-20 09:15:18 +0800 CST2024-01-20 09:15:18 +0800 CST 2024-01-20 09:15:18 +0800 CST

O soquete bruto não captura pacotes DHCP na interface correta, mas o Wireshark está

  • 772

Estou seguindo este exemplo de aplicação C de um sniffer de soquete bruto:

https://www.binarytides.com/packet-sniffer-code-c-linux/

Exceto que vinculei o soquete à minha interface depois de criar o soquete:

const std::string& iff = "wlp3s0";

int r = setsockopt(sock_raw, SOL_SOCKET, SO_BINDTODEVICE, iff.c_str(), iff.length());
if (r == -1)
{
    std::abort();
}

Deixo então o aplicativo em execução:

sudo ./the_app

Abro o Wireshark e ouço a interface sem fio wlp3s0. Removi a interface Ethernet com fio da captura.

Em seguida, executo sudo dhclient -re sudo dhclientparo/inicio o DHCP e o Wireshark detecta 4 ou 5 pacotes DHCP, conforme esperado:

insira a descrição da imagem aqui

No entanto, o sniffer de soquete bruto C não mostra absolutamente nenhum pacote UDP recebido.

Se eu abrir um navegador da web, ele começará a mostrar pacotes TCP (o Wireshark relatou que os pacotes DHCP eram UDP).

O que está acontecendo? Estou usando Ubuntu 22.04

Exemplo mínimo:

#include<stdio.h>   //For standard things
#include<stdlib.h>  //malloc
#include<string.h>  //memset
#include<netinet/ip_icmp.h> //Provides declarations for icmp header
#include<netinet/udp.h> //Provides declarations for udp header
#include<netinet/tcp.h> //Provides declarations for tcp header
#include<netinet/ip.h>  //Provides declarations for ip header
#include<sys/socket.h>
#include<arpa/inet.h>
#include <unistd.h>

void ProcessPacket(unsigned char* , int);

int tcp=0,udp=0,icmp=0,others=0,igmp=0,total=0,i,j;
struct sockaddr_in source,dest;

int main()
{    
    unsigned char *buffer = (unsigned char *)malloc(65536); //Its Big!
    
    printf("Starting...\n");
    int sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);

    if(sock_raw < 0)
    {
        std::abort();
    }

    int r = setsockopt(sock_raw, SOL_SOCKET, SO_BINDTODEVICE, "wlp3s0", strlen("wlp3s0"));
    
    if (r == -1)
    {
        std::abort();
    }
   
    while(1)
    {
        int data_size = recv(sock_raw , buffer , 65536 , 0);
        
        if(data_size <0 )
        {
            std::abort();
        }

        ProcessPacket(buffer , data_size);
    }
    
    ::close(sock_raw);
    return 0;
}

void ProcessPacket(unsigned char* buffer, int size)
{
    //Get the IP Header part of this packet
    struct iphdr *iph = (struct iphdr*)buffer;
    ++total;
    switch (iph->protocol) //Check the Protocol and do accordingly...
    {
        case 1:  //ICMP Protocol
            ++icmp;
            //print_icmp_packet(buffer, size);
            break;
        
        case 2:  //IGMP Protocol
            ++igmp;
            break;
        
        case 6:  //TCP Protocol
            ++tcp;
            //print_tcp_packet(buffer , size);
            break;
        
        case 17: //UDP Protocol
            ++udp;
            //print_udp_packet(buffer , size);
            break;
        
        default: //Some Other Protocol like ARP etc.
            ++others;
            break;
    }

    printf("TCP : %d   UDP : %d   ICMP : %d   IGMP : %d   Others : %d   Total : %d\r",tcp,udp,icmp,igmp,others,total);
}
c
  • 1 1 respostas
  • 45 Views

1 respostas

  • Voted
  1. Best Answer
    Marco Bonelli
    2024-01-20T10:48:52+08:002024-01-20T10:48:52+08:00

    Bem, é claro que você não está recebendo pacotes UDP. Você está solicitando explicitamente apenas pacotes TCP com IPPROTO_TCP:

    int sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
    

    Afinal, o próprio guia que você está seguindo diz o seguinte:

    1. O sniffer acima pega apenas pacotes TCP, por causa da declaração:

      sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);
      

    Agora você pode pensar em usar IPPROTO_RAW, mas isso só é possível para envio , conforme man 7 rawexplica:

    Um protocolo de IPPROTO_RAWimplica habilitado IP_HDRINCLe é capaz de enviar qualquer protocolo IP que esteja especificado no cabeçalho passado. O recebimento de todos os protocolos IP IPPROTO_RAWnão é possível usando soquetes brutos .

    Portanto, você não pode receber vários protocolos com um AF_INETsoquete. Você precisará de um AF_PACKETsoquete e de um código um pouco mais complexo. Veja man 7 packetpara mais informações.

    Observe que neste caso você terá que vincular usando bind(2)e struct sockaddr_ll, não pode usar setsockopt(SO_BINDTODEVICE, ...)com AF_PACKETsoquetes, como man 7 socketafirma:

    SO_BINDTODEVICE

    [...] Observe que isso funciona apenas para alguns tipos de soquete, principalmente AF_INETsoquetes. Não é suportado para soquetes de pacotes (use normal bind(2)lá).

    • 2

relate perguntas

  • Multiplicação mais rápida que *

  • Usando uma macro para comprimento de string no especificador de formato scanf () em C

  • Como você pode definir o tipo de dados de #define para long double?

  • Ponteiros const incompatíveis

  • Mudança de cor não gradual no OpenGL

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve