Итак, вкратце: моя программа получает буфер необработанных байтов (u_char), который представляет собой сетевой пакет. Я пытаюсь разобрать информацию в этом пакете, и делаю это, используя определенные системой структуры заголовков (ether_header, ip, ip6, tcphdr, udphdr). Я реализовал это как в Linux, так и в AIX, и это сработало, но по какой-то причине я продолжаю получать ошибку шины, когда делаю это в Solaris.
То, как я получаю данные, в основном просто отбрасывает каждую часть буфера как одну из структур и читает данные. Например, если у меня есть
u_char buffer[] = {...some bytes...};
struct ether_header *ethdr = (struct ether_header *)buffer;
struct ip *iphdr = (struct ip *) (buffer + sizeof(struct ether_header));
etc. etc.
Затем я могу получить необходимую мне информацию, например:
iphdr->ip_v; //to get the version
etc->etc; //to get whatever piece of data I need
Обычно в Linux и AIX это работает нормально (некоторые структуры имеют разные имена в разных системах, но это не имеет значения), но при попытке запустить это в Solaris я продолжаю получать ошибку шины, когда она достигает iphdr->ip_v;
после struct ip *iphdr = (struct ip *) (buffer + sizeof(struct ether_header));
. После некоторого расследования я обнаружил, что это вызвано попыткой доступа к невыровненной памяти. Это имеет смысл, поскольку размер заголовка Ethernet составляет всего 14 байт, поэтому заголовок IP не выровнен по байтам в массиве.
Я попытался обойти это, скопировав соответствующие части в отдельный буфер, прежде чем пытаться их прочитать.
memcpy(&buffer_copy, buffer + sizeof(struct ether_header), sizeof(struct ip));
struct ip *iphdr = &buffer_copy;
iphdr->ip_v;
etc.
Это работает, но я не понимаю, почему. Почему memcpy не выдает ошибку шины, когда пытается получить доступ к тому же месту в памяти? Мне не нравится решение, которое я придумал, и я пытаюсь лучше понять ситуацию, чтобы придумать что-то другое. Может быть, я пропустил часть головоломки?
struct ip *iphdr = (struct ip *) (buffer + sizeof(struct ether_header));
выдает ошибку шины? Вернее, почему попытка доступа к данным внутри него выдает ошибку. - person monkeygame7   schedule 31.07.2015uname -a
? - person Andrew Henle   schedule 31.07.2015