Pergunta

Estou escrevendo um módulo do kernel que registra um gancho com netfilter. O manipulador não está a ser accionado se eu ssh / telnet na máquina, onde o módulo é carregado.

struct nf_hook_ops my_hook_ops;
my_hook_ops.hook = hook_handler;
my_hook_ops.pf = PF_INET;
my_hook_ops.hooknum = NF_INET_PRE_ROUTING;
my_hook_ops.priority =  NF_IP_PRI_FIRST;
nf_register_hook(&my_hook_ops);

A função de manipulador:

unsigned int hook_handler(unsigned int hooknum,
                   struct sk_buff *skb,
                   const struct net_device *in,
                   const struct net_device *out,
                   int (*okfn)(struct sk_buff *))
{


    if(!skb)
        return NF_ACCEPT;

    struct iphdr* ip_header;
    struct tcphdr* tcp_header;
    union  ip_address ipaddr;

    printk(KERN_INFO "Entered handler\n");

    if(skb->protocol == 8)
        return NF_ACCEPT;

    // Log the received packet
    ip_header  = ip_hdr(skb);
    tcp_header = tcp_hdr(skb);
    ipaddr.saddr = ip_header->saddr;
    printk(KERN_INFO "Received packet:\nIP Address: %u.%u.%u.%u\nProtocol: %d\nSource port: %d\nDestination port: %d\n",
            ipaddr.a[0],ipaddr.a[1],ipaddr.a[2],ipaddr.a[3],
            skb->protocol,
            tcp_header->source,
            tcp_header->dest);

    return NF_ACCEPT;
}

O gancho está sendo chamado para o protocolo 8 (Exterior Gateway Protocol). A segunda printk nunca é impresso. Estou faltando alguma coisa?

Foi útil?

Solução

O protocolo utilizado aqui é diferente do número de protocolo IP como atribuído pela IANA, para a qual é 8 para EGP e EGP foi ultrapassada.

O campo protocolo para sk_buff é definida em, para a qual é 8 para ETH_P_IP. Como seus dados são allways tráfego IP, a primeira verificação condicional sempre é verdade. Assim, a segunda parte do código nunca são executados.

Outras dicas

Um casal de pensamentos:

  • um manipulador de gancho leva um (skbuff struct **), não um (struct skbuff *)
  • na sequência do acima, skb->protocol não existe. Você quer quer (*skb)->protocol ou você quer a seguinte expressão:
struct sk_buff *sock_buf =  *skb;
if(sock_buff->protocol)
  • Se o pacote é um pacote EGP, você não deve estar esperando a saída do segundo printk, porque você voltar antes.

Você precisa estudar como funciona sk_buff, o campo de protocolo inicializados pela função `eth_type_trans', que leva em ETH_P_ * valores. Todos os valores ETH_P_ * são definidos no if_ether . Aqui estão alguns desses valores.

#define ETH_P_LOOP      0x0060          /* Ethernet Loopback packet     */
#define ETH_P_PUP       0x0200          /* Xerox PUP packet             */
#define ETH_P_PUPAT     0x0201          /* Xerox PUP Addr Trans packet  */
#define ETH_P_IP        0x0800          /* Internet Protocol packet     */

Você vê claramente que 0x08 é definido para Internet Protocol packet. E o seu código de retorno claramente no caso de 8 (que é pacote IP)

 if(skb->protocol == 8)
    return NF_ACCEPT;

Seu ssh/telnet claramente IP pacote (s) e rejeitado por código acima. Utilize valores de protocolo definido adequados definidos na if_ethr

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top