Чтение ответа ICMP с использованием сокетов RAW - PullRequest
2 голосов
/ 26 октября 2019

У меня есть следующая рабочая функция, которая принимает сокет, готовый для ответа ICMP, и считывает его в буфер, но я изо всех сил пытаюсь понять поток кода и хотел, чтобы кто-то исправил / подтвердил мое понимание. Насколько я понимаю, следующее:

  1. Указатель массива из 1024 символов, называемый «буфер», определен для использования в качестве буфера.
  2. Два указателя, называемые «ip» и «icmp», являютсясоздан для указания на структуры iphdr и icmphdr.
  3. Указатель 'ip' настроен так, чтобы указывать на указатель 'buffer', который теперь преобразуется в указатель структуры iphdr
  4. Указатель 'icmp'устанавливается указатель на буферный указатель + размер struct iphdr, который теперь преобразуется в указатель структуры icmphdr

Это четвертый момент, который я не совсем понимаю. Расположен ли адрес указателя 'icmp' под адресом указателя 'ip', а '(buff + sizeof (struct iphdr)) "ссылается на точку в памяти, на которую должен указывать указатель' icmp '? Могу ли я где-нибудь прочитать о приведении типов, используя этот тип смещения? `

int read_icmp_answer(int *sock){

  char buff[1024];
  struct iphdr *ip;   
  struct icmphdr *icmp;   
  ip = (struct iphdr *)buff;
  icmp = (struct icmphdr *) (buff + sizeof(struct iphdr));

  if(read(*sock, buff, sizeof(buff)) > 0) {
      if(icmp->type == 0 && icmp->code == 0) return 1;
      else return -1;
  }

  return 0;

}

`

1 Ответ

2 голосов
/ 26 октября 2019

Не о чем читать.

Автор создал 1024 байта. Затем они солгали компилятору, убеждая его, что в начале этого блока существует struct iphdr, а сразу после него struct icmphdr (используя довольно простую арифметику с указателями и пару приведений).

Это не так, и код имеет неопределенное поведение.

Вы можете проверить объект типа T, используя char*;вы не можете проверить char[], как если бы это был объект типа T. Это нарушает строгие правила наложения имен. К сожалению, поскольку более старые и более простые компиляторы с большей вероятностью допустили этот слайд на практике, существует распространенное заблуждение относительно кода, подобного этому, и он продолжает появляться в примерах. 101

Вместо этого автор должен был объявить struct iphdr и прочитать sizeof(iphdr) байт, затем объявить struct icmphdr и прочитать sizeof(icmphdr) байт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...