C: сохранить полученный пакет Winsock в файл как шестнадцатеричный - PullRequest
0 голосов
/ 21 июля 2010

Мне нужно сделать то, что делает большинство программ мониторинга пакетов (Wireshark, tcpdump и т. Д.).Когда данные поступают через Winsock, мне просто нужно преобразовать пакет в шестнадцатеричное представление и сохранить его в файл.

Данные представляют собой простой массив символов.

Я много пробовалтаких вещей, как спринтф, но без удачи.Я также не хочу использовать itoa, так как это не стандартный C из того, что я узнал.

Пример:

Если пакет содержит «test», тогдаон должен быть выгружен в файл как "74 65 73 74".

Я могу сделать все, что касается обработки файлов, и код Winsock работает, я думаю, мне просто нужно написать функцию для преобразования символамассив в шестнадцатеричное представление, и я не могу его получить.

Ответы [ 4 ]

4 голосов
/ 21 июля 2010

Возможно, вам следует показать, что вы пробовали, так как printf () и его варианты - безусловно, самое простое решение.

int emit_hex( FILE* file, const char* data, size_t len )
{
    int length = 0 ;
    size_t i ;

    for( i = 0; i < len; i++ )
    {
        length += fprintf( file, "%2.2X", (unsigned)pkt[i] ) ;
        if( i < len - 1)
        {
            length += fprintf( " " ) ;
        }
    }

    return length ;
}
3 голосов
/ 21 июля 2010

чуть более продвинутая функция:


#include <stdio.h>
#include <string.h>
#include <error.h>

void dump(FILE* pFile, const char* szData, unsigned long ulSize)
{
  const char* pBuff = szData;
  unsigned long i = 0;
  unsigned long j = 0;

  for(i = 0; i < ulSize; i += 0x10)
  {
    if((i % 0x10) == 0)
      fprintf(pFile, "\n0x%8p   ", (i + szData));

    for(j = 0; ((i + j) < ulSize) && (j < 0x10); j++)
      fprintf(pFile, "%.2x ", (unsigned char)pBuff[i+j]);

    for(; j < 0x10; j++)
      fprintf(pFile, "   ");

    fprintf(pFile, "  ");

    for(j = 0; ((i + j) < ulSize) && (j < 0x10); j++)
      fprintf(pFile, "%c", (unsigned char)pBuff[i+j] > ' ' ? pBuff[i+j] : '.');
  }
  fprintf(pFile, "\n\n");
  fflush(pFile);
}


int main()
{
  FILE* pFile = fopen("dump.txt", "wt+");
  if (!pFile)
  {
    perror("error while opening file");
    return 1;
  }

  const char* szData = "1234567890qwertyuiop"; // received data
  unsigned long ulSize = (unsigned long)strlen(szData); // data length just for example

  dump(pFile, szData, ulSize);
  fclose(pFile);
}

выходной формат (указатель, шестнадцатеричный, символ): 0x0x400a9c 31 32 33 34 35 36 37 38 39 30 71 77 65 72 74 79 1234567890qwerty 0x0x400aac 75 69 6f 70 uiop

1 голос
/ 21 июля 2010

sprintf использует преобразование %x для шестнадцатеричного числа, поэтому вы обычно используете что-то вроде этого:

cvt2hex(unsigned len, char const *input, char *output) { 
    int i;
    for (i=0; i<len; i++)
        sprintf(output+i*3, "%2.2x ", input[i]);
}

Конечно, output должен указывать на достаточное количество памяти для хранения преобразованногоданные.Обычно вам нужно вставлять новую строку после каждых 16 или 32 байтов или где-то поблизости.

0 голосов
/ 21 июля 2010

Другой способ - использовать модификатор длины для символа (чч):

printf("%hhx", c);
...