Программа на C для получения значений полей заголовка IP из стека IP Linux - PullRequest
2 голосов
/ 14 июля 2011

Я разрабатываю программу, в которой мне нужно знать значения полей заголовка IP внутри моей программы. Поскольку заголовок IP состоит из 20 байтов:

struct ipheader {

     unsigned char ip_hl:4, ip_v:4; /* this means that each member is 4 bits */
     unsigned char ip_tos;
     unsigned short int ip_len;
     unsigned short int ip_id;
     unsigned short int ip_off;
     unsigned char ip_ttl;
     unsigned char ip_p;
     unsigned short int ip_sum;
     unsigned int ip_src;
     unsigned int ip_dst;
    }; 

Есть ли способ узнать значения этих полей? внутри моей программы на C?

Ответы [ 3 ]

1 голос
/ 14 июля 2011

Некоторые из этих значений можно установить / получить с помощью вызовов setsockopt()/getsockopt() на уровне SOL_IP/IPPROTO/IP.Обратитесь к документации вашей ОС (например: в Linux man 7 ip).

1 голос
/ 14 июля 2011

Если ваш компилятор не вводит какие-либо блоки выравнивания в этой структуре (убедитесь, что CHAR_BIT равен 8, а sizeof(struct ipheader) равен 20), вы просто сможете включить его в свой код как есть, а затемдобавьте что-то вроде:

struct ipheader *iph = (struct ipheader *)blk;
printf ("TTL = %d\n", iph->ip_ttl);

В этом коде у вас будет заголовок IP, на который указывает blk, что, вероятно, char*.Приведение его к правильному типу указателя позволит вам легко получить доступ к полям.

Следующая полная программа показывает это в действии:

#include <stdio.h>
#include <limits.h>

struct ipheader {
    /* 0 */ unsigned char ip_hl:4, ip_v:4;
    /* 1 */ unsigned char ip_tos;
    /* 2 */ unsigned short int ip_len;
    /* 3 */ unsigned short int ip_id;
    /* 4 */ unsigned short int ip_off;
    /* 5 */ unsigned char ip_ttl;
    /* 6 */ unsigned char ip_p;
    /* 7 */ unsigned short int ip_sum;
    /* 8 */ unsigned int ip_src;
    /* 9 */ unsigned int ip_dst;
};

int main (void) {
    char blk[] = {
        '\x00','\x11','\x22','\x22','\x33','\x33','\x44','\x44',
        '\x55','\x66','\x77','\x77','\x88','\x88','\x88','\x88',
        '\x99','\x99','\x99','\x99'
    };
    struct ipheader *iph = (struct ipheader *)(&blk);

    printf ("TTL = %x\n", iph->ip_ttl);
    printf ("sum = %x\n", iph->ip_sum);
    printf ("dst = %x\n", iph->ip_dst);

    return 0;
}

Вывод, как и ожидалось:

TTL = 55
sum = 7777
dst = 99999999
0 голосов
/ 19 июня 2017

Вы должны использовать setsockopt/getsockopt подпрограммы для взаимодействия с механизмом сокетов. Эти функции работают на разных уровнях (IPPROTO_IP, IPPROTO_TCP и т. Д.), И некоторые опции доступны только для определенных типов сокетов (например, опция IP_TTL доступна только для AF_INET розеток).

получить значение TTL:

int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
unsigned int opt_val;                                                         
unsigned int opt_len;                                                       
getsockopt(sock, IPPROTO_IP, IP_TTL, &opt_val, &opt_len);
printf("ttl %d\n", opt_val);

установить значение TTL:

int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
unsigned char ttl_val = 32;                                                                                                                                        
setsockopt(sock, IPPROTO_IP, IP_TTL, &ttl_val, sizeof(ttl_val));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...