zoukankan      html  css  js  c++  java
  • Stun协议的格式记录

    Stun协议的格式,定义在https://www.ietf.org/rfc/rfc3489.txt

    11.1  Message Header
    
       All STUN messages consist of a 20 byte header:
    
        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
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |      STUN Message Type        |         Message Length        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                Transaction ID
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                                                       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    
       The Message Types can take on the following values:
    
          0x0001  :  Binding Request
          0x0101  :  Binding Response
          0x0111  :  Binding Error Response
          0x0002  :  Shared Secret Request
          0x0102  :  Shared Secret Response
          0x0112  :  Shared Secret Error Response
    11.2  Message Attributes
    
       After the header are 0 or more attributes.  Each attribute is TLV
       encoded, with a 16 bit type, 16 bit length, and variable value:
    
        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             |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                             Value                             ....
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    
       The following types are defined:
    
       0x0001: MAPPED-ADDRESS
       0x0002: RESPONSE-ADDRESS
       0x0003: CHANGE-REQUEST
       0x0004: SOURCE-ADDRESS
       0x0005: CHANGED-ADDRESS
       0x0006: USERNAME
       0x0007: PASSWORD
       0x0008: MESSAGE-INTEGRITY
       0x0009: ERROR-CODE
       0x000a: UNKNOWN-ATTRIBUTES
       0x000b: REFLECTED-FROM

    基本格式是消息体之后,跟着Attribute,Attribute的type有很多种,根据不同的类型进行解析。

    Value值基本上是Mapped-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
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |x x x x x x x x|    Family     |           Port                |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                             Address                           |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    在https://tools.ietf.org/html/rfc5389中,对STUN进行了新的兼容定义,现在好多都使用5389了

    5389的新定义如下:

           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
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |0 0|     STUN Message Type     |         Message Length        |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                         Magic Cookie                          |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
          |                                                               |
          |                     Transaction ID (96 bits)                  |
          |                                                               |
          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    
                      Figure 2: Format of STUN Message Header
    将原来的128bit的TransactionID分割为2部分,一部分是magic cookie,一部分是id。
    The magic cookie field MUST contain the fixed value 0x2112A442 in
       network byte order
    magic cookie是一个常量
    比3489多了一个属性:

    15.2. XOR-MAPPED-ADDRESS

    
    
       The XOR-MAPPED-ADDRESS attribute is identical to the MAPPED-ADDRESS
       attribute, except that the reflexive transport address is obfuscated
       through the XOR function.
    
       The format of the XOR-MAPPED-ADDRESS is:
    
          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
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |x x x x x x x x|    Family     |         X-Port                |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |                X-Address (Variable)
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    
                 Figure 6: Format of XOR-MAPPED-ADDRESS Attribute
    
       The Family represents the IP address family, and is encoded
       identically to the Family in MAPPED-ADDRESS.
    
    
    
    
    
    Rosenberg, et al.           Standards Track                    [Page 33]

    
    RFC 5389                          STUN                      October 2008
    
    
       X-Port is computed by taking the mapped port in host byte order,
       XOR'ing it with the most significant 16 bits of the magic cookie, and
       then the converting the result to network byte order.  If the IP
       address family is IPv4, X-Address is computed by taking the mapped IP
       address in host byte order, XOR'ing it with the magic cookie, and
       converting the result to network byte order.  If the IP address
       family is IPv6, X-Address is computed by taking the mapped IP address
       in host byte order, XOR'ing it with the concatenation of the magic
       cookie and the 96-bit transaction ID, and converting the result to
       network byte order.
    如果使用XOR-MAPPED-ADDRESS,需要做异或操作。

    贴上一段代码:
    struct StunMessageHeader
    {
        unsigned short msg_type;
        unsigned short msg_len;
        unsigned int magic;
        unsigned char id[12];
    };
    
    #define STUN_MAGIC 0x2112A442
    #define STUN_MSG_TYPE_BINDING_REQUEST 0x0001
    #define STUN_MSG_TYPE_BINDING_RESPONSE 0x0101
    #define STUN_MSG_TYPE_BINDING_ERR_RESPONS 0x0111
    #define STUN_MSG_TYPE_SHARED_SECRET_REQUEST    0x0002
    #define STUN_MSG_TYPE_SHARED_SECRET_RESPONSE 0x0102
    #define STUN_MSG_TYPE_SHARED_SECRET_ERR_RESPONSE 0x0112
    #define STUN_ATTR_MAPPED_ADDRESS        0x0001
    #define STUN_ATTR_RESPONSE_ADDRESS        0x0002
    #define STUN_ATTR_CHANGE_REQUEST        0x0003
    #define STUN_ATTR_SOURCE_ADDRESS        0x0004
    #define STUN_ATTR_CHANGE_ADDRESS        0x0005
    #define STUN_ATTR_USERNAME                0x0006
    #define STUN_ATTR_PASSWORD                0x0007
    #define STUN_ATTR_MESSAGE_INTEGRITY        0x0008
    #define STUN_ATTR_ERROR_CODE            0x0009
    #define STUN_ATTR_UNKNOWN_ATTRIBUTES    0x000a
    #define STUN_ATTR_REFLECTED_FROM        0x000b
    #define STUN_ATTR_REALM                    0x0014
    #define STUN_ATTR_NONCE                    0x0015
    #define STUN_ATTR_XOR_MAPPED_ADDRESS    0x0020
    
    struct StunAttributeHeader
    {
        unsigned short type;
        unsigned short length;
    };
    struct MappedAddress
    {
        unsigned char reseved;
        unsigned char family;
        unsigned short port;
        unsigned int address;
    };
    
    void GetBindingRequest(unsigned char* buf, int* len)
    {
        StunMessageHeader binding;
        memset(&binding, 0, sizeof(binding));
        binding.msg_type = htons(STUN_MSG_TYPE_BINDING_REQUEST);
        binding.magic = htonl(STUN_MAGIC);
      unsigned long long temp = srand();
    memcpy(binding.id, (unsigned char*)&temp, 8); memcpy(buf, &binding, sizeof(binding)); *len = sizeof(binding); } bool ParseMappedAddr(unsigned char* buf, int len, std::string& mappedIp, int* mappedPort) { StunMessageHeader* head = (StunMessageHeader*)buf; head->msg_type = htons(head->msg_type); head->msg_len = htons(head->msg_len); if (head->msg_type == STUN_MSG_TYPE_BINDING_RESPONSE) { if (head->msg_len > 0) { StunAttributeHeader* attr = (StunAttributeHeader*)(buf + 20); attr->type = htons(attr->type); attr->length = htons(attr->length); if (attr->type == STUN_ATTR_XOR_MAPPED_ADDRESS) { if (attr->length > 0) { MappedAddress* mapaddr = (MappedAddress*)(buf + 24); mapaddr->port = htons(mapaddr->port); mapaddr->port ^= STUN_MAGIC >> 16; mapaddr->address = htonl(mapaddr->address); mapaddr->address ^= STUN_MAGIC; char buf[16]; sprintf(buf, "%d.%d.%d.%d", mapaddr->address >> 24, mapaddr->address >> 16 & 0xff, mapaddr->address >> 8 & 0xff, mapaddr->address & 0xff); mappedIp = buf; *mappedPort = mapaddr->port; return true; } } else if (attr->type == STUN_ATTR_MAPPED_ADDRESS) { if (attr->length > 0) { MappedAddress* mapaddr = (MappedAddress*)(buf + 24); mapaddr->port = htons(mapaddr->port); mapaddr->address = htonl(mapaddr->address); char buf[16]; sprintf(buf, "%d.%d.%d.%d", mapaddr->address >> 24, mapaddr->address >> 16 & 0xff, mapaddr->address >> 8 & 0xff, mapaddr->address & 0xff); mappedIp = buf; *mappedPort = mapaddr->port; return true; } } } } return false;
    }



  • 相关阅读:
    js简单的下拉选中效果
    简单的JS+HTML+CSS达成图片轮播
    JQ延时对象
    javascript特效----碰壁运动
    PHP---封装
    PHP---面向对象
    PHP----基础
    MySQL查询实例
    JS下拉列表
    MySQL基础操作
  • 原文地址:https://www.cnblogs.com/limedia/p/stun.html
Copyright © 2011-2022 走看看