ядро linux конвертирует char * в uint8_t [6] (чтение строки в mac) - PullRequest
0 голосов
/ 13 октября 2011

Мне нужно преобразовать строку "00: 11: 22: 33: 44: 55" в uint8_t [6], представляющий mac. Я пробовал сам, где-то читал, что char можно привести к uint8_t, но я немного устал, чтобы попробовать сам. (

Возможно, в ядре есть функция, которая делает то, что я хочу.

Если нет, то вот мой код, что я делаю не так?

char * cleaned_mac =NULL;
char * extractMac(unsigned char * shared_user_buffer, size_t offset) {
    char * buffer = kmalloc(17, GFP_KERNEL);
    cleaned_mac = kmalloc(13, GFP_KERNEL);
    int i = 0;
    strncpy(buffer, shared_user_buffer + offset, 17);
    printk("BUFFER [%s]\n", buffer);
    while (*buffer && i < 12) {
        if (isxdigit(*buffer)) {
            printk("BUFFER [%c]\n", *buffer);
            cleaned_mac[i] = *buffer;
            printk("CLEANED BUFFER [%c]\n", *cleaned_mac);
            i++;
        }
        ++buffer;
    }
    cleaned_mac[12]=0x00;
    printk("CLEANED BUFFER [%s]\n", cleaned_mac);
    return cleaned_mac;
}

называя это как:

uint8_t * mac;
mac = extractMac(shared_user_buffer, strlen(tmq_server_prefix));
printk(KERN_DEBUG "MAC[%s]\n", mac);

printk(KERN_DEBUG "MAC[%02x:%02x:%02x:%02x:%02x:%02x]\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

поэтому, когда я даю в функции «08: 00: 27: 19: 1f: 02», получается:

Oct 13 17:41:28 client2 kernel: [ 1953.179271] CLEANED BUFFER [080027191f02]
Oct 13 17:41:28 client2 kernel: [ 1953.179273] MAC[080027191f02]
Oct 13 17:41:28 client2 kernel: [ 1953.179276] MAC[30:38:30:30:32:37]

Значит, 08 стало 30 и 38? Это почему?

Решение, вдохновленное Дейвом (спасибо):

uint8_t * cleaned_mac = NULL;
uint8_t * extractMac(unsigned char * shared_user_buffer, size_t offset) {
    char *c;
    char * buffer = kmalloc(17, GFP_KERNEL);
    int p = 0;
    const char * sep = ":";
    cleaned_mac = kmalloc(ETH_ALEN * sizeof(uint8_t), GFP_KERNEL);
    strncpy(buffer, shared_user_buffer + offset, 17);

    while ((c = strsep(&buffer, sep))) {
        cleaned_mac[p++] = simple_strtol(c, NULL, 16);
    }
    return cleaned_mac;
}

Использование тогда:

uint8_t *  mac;
mac = extractMac(shared_user_buffer, strlen(tmq_server_prefix));
        printk(KERN_DEBUG "---------------MAC [%02x:%02x:%02x:%02x:%02x:%02x]\n",
                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

Ответы [ 5 ]

4 голосов
/ 13 октября 2011

Я не могу понять, как должен работать ваш код, поэтому я просто напишу, как бы я это сделал:

char* macIn = "08:00:27:19:1f:02";
uint8_t macOut[6] = {0};

sscanf(macIn, "%2x:%2x:%2x:%2x:%2x:%2x", macOut, macOut+1, macOut+2, macOut+3, macOut+4, macOut+5);

printf("MAC IN: [%s]\n", macIn);
printf("MAC OUT (hex): [%02x:%02x:%02x:%02x:%02x:%02x]\n",
     macOut[0], macOut[1], macOut[2], macOut[3], macOut[4], macOut[5]);
printf("MAC OUT (decimal): [%02d:%02d:%02d:%02d:%02d:%02d]\n",
     macOut[0], macOut[1], macOut[2], macOut[3], macOut[4], macOut[5]);
1 голос
/ 13 октября 2011

Токенизируйте строку и вызывайте strtol для каждого результата

char *c;
int p = 0;
for(c=strtok(buffer, ",");c;c=strtok(NULL, ","))
     mac[p++] = strtol(c, NULL, 16);
1 голос
/ 13 октября 2011

Формат %02x printf интерпретирует mac[0] как целое число и печатает его как строку, преобразовывая его в двузначный шестнадцатеричный код.

Поскольку mac[0] содержит символ ASCII 0, чей код ASCII равен 0x30, то вполне нормально, что вы получаете вывод, который у вас есть.

0 голосов
/ 25 марта 2017

Я допустил ту же проблему, наконец решил с помощью этого простого кода, это в ядре Linux.

char *mac_local = "e4:95:6e:4e:ee:6c"; 
for(i=0;i<6;i++)
    buffAssco[i+START_POS] = simple_strtol(mac_local+3*i,NULL,16)&0xff;
0 голосов
/ 13 октября 2011

Вы должны взять каждую пару символов, убедитесь, что они действительно находятся в диапазоне '0' .. '9', 'A' .. 'F' или 'a' .. 'f'.Затем вы берете первое, сопоставляете его с его «значением» (0..15), умножаете его на 16 и добавляете второе, также сопоставленное.

...