【问题标题】:linux kernel convert char * to uint8_t[6] (read string to mac)linux内核将char *转换为uint8_t[6](将字符串读取到mac)
【发布时间】:2011-12-07 02:13:42
【问题描述】:

我需要将字符串 "00:11:22:33:44:55" 转换为代表 mac 的 uint8_t[6]。 我自己尝试过,在某个地方可以将 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 ?这是为什么?

受 Dave 启发的解决方案(谢谢):

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]);

【问题讨论】:

  • “0”的ASCII码是0x30,“8”是0x38。您似乎正在反向运行您的十六进制转换器,并且忘记了字符使用 ascii。
  • 是的,但它应该是 08,那么为什么 mac[0] 被解释为 '0' 而不是 0x08 ?
  • 老实说,我没有耐心理解这段极其复杂的代码在做什么,但如果mac 是一个包含“08:00:27:19:1f:02”的字符缓冲区,然后mac[0] 将返回“0”。我建议阅读有关字符串如何工作的内容。
  • mac 是 uint8_t * 不是字符串。
  • 几乎没有区别。重要的是缓冲区中包含什么:十六进制表示的原始数据或数据?显然是后者。

标签: c linux string linux-kernel type-conversion


【解决方案1】:

我无法破译您的代码应该如何工作,所以我只写我会怎么做:

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]);

【讨论】:

  • 没用。打印很好,但是将其注入 skb 不起作用,那里只是垃圾。
  • wtf 是 skb 吗?如果打印成功,那么你做错了什么。
  • 仅供参考:ftp.gnumonks.org/pub/doc/skb-doc.html 我刚刚看到我使用了错误的指针,您的解决方案也很好
【解决方案2】:

标记字符串,并在每个结果上调用strtol

char *c;
int p = 0;
for(c=strtok(buffer, ",");c;c=strtok(NULL, ","))
     mac[p++] = strtol(c, NULL, 16);

【讨论】:

  • 这并不真正起作用,因为 MAC 使用十六进制。 atoi 会给你十进制解释,这是错误的。
  • 啊,我会用strtol解决这个问题
  • 我在内核中,您使用的功能在那里丢失,但我有一个解决方案。我在我的问题中发布了 ist。
【解决方案3】:

%02x printf 格式将mac[0] 解释为整数,并通过将其转换为两位数的十六进制将其打印为字符串。

由于mac[0] 包含ASCII 字符0,其ASCII 码为0x30,所以得到你所拥有的输出是完全正常的。

【讨论】:

    【解决方案4】:

    您必须获取每对字符,确认它们确实在'0'..'9''A'..'F''a'..'f' 范围内。然后你取第一个,将它映射到它的“含义”(0..15),乘以 16 并加上第二个,映射也是如此。

    【讨论】:

      【解决方案5】:

      我遇到了同样的问题,最后用这个简单的代码解决了,它在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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-23
        • 2019-08-11
        • 1970-01-01
        相关资源
        最近更新 更多