параметр данных имеет тип char **, который в этом случае можно рассматривать как указатель на список символов. Вызов устанавливает данные в список символов пакета. Однако, несмотря на то, что «строка c» также имеет тип char *, возвращаемые здесь данные не являются строкой c, поскольку содержат встроенные нули. Если вы попытаетесь распечатать его с% s, вы получите данные только до первого нуля.
Могу поспорить, что вы получаете IP-пакет, потому что первый байт заголовка IP-пакета почти всегда равен 0x45, что в ASCII - буква 'E'. Это, если за ним следует поле TOS, которое почти всегда равно 0, или NULL. Этот 0x45,0x00 является допустимой c-строкой, поэтому вы получаете E.
Вы действительно хотите использовать возвращаемое значение ret в качестве счетчика цикла и печатать каждый байт пакета:
for (int i = 0; i < ret; i++) {
printf(" 0x%1X ", data[i] );
}
Взгляните на Почему printf не печатает только один байт при печати в шестнадцатеричном формате? для обсуждения буферов печати.