c - inet_pton() 对应的链路层地址

标签 c linux sockets networking mac-address

我有两个与我的实现相关的问题 -

  1. 我需要一个函数,可以将给定的链路层地址从文本转换为标准格式,就像我们在 n/w 层有一个类似的 IP 地址函数 inet_pton() ,它可以将从文本到标准 IPv4/IPv6 格式的给定 IP 地址。

  2. 链路层地址和 48 位 MAC 地址之间有什么区别吗 (特别是 IPv6 的情况)?

    如果不是,那么如果我没记错的话,链路层地址的长度也应该始终是 48 位。

提前致谢。如果我遗漏了一些微不足道的东西,请原谅。

编辑:

好的..我很清楚黑白链路层地址和以太网 MAC 地址的区别。数据链路层地址有多种类型,以太网MAC地址只是其中一种。

现在,这又出现了一个问题......正如我在第一个问题中所说,我需要将从命令行给出的链路层地址转换为其标准形式。这里提供的解决方案仅适用于以太网 MAC 地址。

没有用于此目的的标准函数吗?我想要做的是创建一个应用程序,用户将在其中输入 ICMP 路由器通告消息中存在的不同选项的值,如 RFC 4861 中所述。

Option Formats


Neighbor Discovery messages include zero or more options, some of
which may appear multiple times in the same message.  Options should
be padded when necessary to ensure that they end on their natural
64-bit boundaries.  All options are of the form:

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |    Length     |              ...              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   ~                              ...                              ~
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Fields:

  Type           8-bit identifier of the type of option.  The
                 options defined in this document are:

                       Option Name                             Type

                    Source Link-Layer Address                    1
                    Target Link-Layer Address                    2
                    Prefix Information                           3
                    Redirected Header                            4
                    MTU                                          5

  Length         8-bit unsigned integer.  The length of the option
                 (including the type and length fields) in units of
                 8 octets.  The value 0 is invalid.  Nodes MUST
                 silently discard an ND packet that contains an
                 option with length zero.

  4.6.1. Source/Target Link-layer Address


  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |     Type      |    Length     |    Link-Layer Address ...
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


   Fields:

   Type
                 1 for Source Link-layer Address
                 2 for Target Link-layer Address

   Length         The length of the option (including the type and
                 length fields) in units of 8 octets.  For example,
                 the length for IEEE 802 addresses is 1
                 [IPv6-ETHER].

   Link-Layer Address
                 The variable length link-layer address.

                 The content and format of this field (including
                 byte and bit ordering) is expected to be specified
                 in specific documents that describe how IPv6
                 operates over different link layers.  For instance,
                 [IPv6-ETHER].

还有一件事,我对 C++ 不太熟悉,你能提供一个 C 替代方案吗? 谢谢。

最佳答案

你的第一个问题,写起来并不难,而且由于 MAC 地址由 6 字节数组表示,因此你不需要考虑机器依赖性(例如字节序等)

void str2MAC(string str,char* mac) {
    for(int i=0;i<5;i++) {
        string b = str.substr(0,str.find(':'));
        str = str.substr(str.find(':')+1);
        mac[i] = 0;
        for(int j=0;j<b.size();b++) {
            mac[i] *= 0x10;
            mac[i] += (b[j]>'9'?b[j]-'a'+10:b[j]-'0');
        }
    }
    mac[5] = 0;
    for(int i=0;i<str.size();i++) {
        mac[5] *= 0x10;
        mac[5] += (str[i]>'9'?str[i]-'a'+10:str[i]-'0');
    }
}

关于你的第二个问题,IP(特别是 IPv6)是一个网络层协议(protocol),位于链路层之上,因此不必与链路层做任何事情。 如果您所说的链路层指的是以太网,那么以太网地址始终是 48 位,但是存在其他链路层协议(protocol),它们可能使用其他格式。

关于c - inet_pton() 对应的链路层地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13807918/

相关文章:

android - Android 中的回调和自定义套接字客户端

java - Android 不抛出 SocketException?

c - 如何修复我的代码以从函数返回指向结构的指针

c - socket.h 的 recv() 上的段错误

c - unistd 的 execl() 不传递任何参数

linux - 匹配一个模式,插入模式,直到下一次匹配

linux - 如果服务器重新启动,如何使 couchbase 服务自动启动?

c - 如何使用mingw从另一个文件中存在的主要方法运行文件中存在的方法

Linux:将 sleep() 与信号结合起来

sockets - 使用luasocket HTTP GET 汉字