示例#1
0
文件: x_stun.c 项目: biddyweb/xwbot
/**
 * returns x-mapped address buffer
 */
static char *
stun_x_mapped(struct sockaddr_in *saddr)
{
  uint16_t port;
  uint32_t ip;
  char *xmapped;

  ENTER;

  xmapped = (char *) x_memset(x_malloc(8), 0, 8);

  xmapped[0] = 0;
  xmapped[1] = 1; // ipv4

  TRACE("MAPPING %s:%d\n", inet_ntoa(saddr->sin_addr), ntohs(saddr->sin_port));

  ip = ntohl(saddr->sin_addr.s_addr);
  port = ntohs(saddr->sin_port);
  port ^= 0x2112;
  ip ^= STUN_M_COOKIE;

  port = htons(port);
  ip = htonl(ip);

  x_memcpy(xmapped + 2, &port, 2);
  x_memcpy(xmapped + 4, &ip, 4);

  EXIT;
  return xmapped;
}
示例#2
0
文件: x_stun.c 项目: biddyweb/xwbot
static char *
jingle_get_hmac_sha1(const char *key, int keylen, char *data, int datalen)
{

  unsigned char k_ipad[65];
  unsigned char k_opad[65];
  SHA1Context sha;
  SHA1Context sha2;
  int i;
  uint8_t Message_Digest[20];
  uint8_t *Message_Digest2;
  md5_state_t state;
  md5_byte_t digest[16];
  md5_byte_t *__key = (md5_byte_t *) key;
  int __keylen = keylen;

  x_memset(digest, 0, 16);

  if (__keylen > 64)
    {
      md5_init(&state);
      md5_append(&state, (const md5_byte_t *) __key, __keylen);
      md5_finish(&state, digest);
      __key = digest;
      __keylen = 16;
    }

  x_memset(k_ipad, 0, sizeof(k_ipad));
  x_memset(k_opad, 0, sizeof(k_opad));
  x_memcpy(k_ipad, __key, __keylen);
  x_memcpy(k_opad, __key, __keylen);

  /* XOR key with ipad and opad values */
  for (i = 0; i < 64; i++)
    {
      k_ipad[i] ^= IPAD;
      k_opad[i] ^= OPAD;
    }

  SHA1Reset(&sha);
  SHA1Input(&sha, (const uint8_t *) k_ipad, 64);
  SHA1Input(&sha, (const uint8_t *) data, datalen);
  SHA1Result(&sha, Message_Digest);

  Message_Digest2 = x_malloc(20);
  SHA1Reset(&sha2);
  SHA1Input(&sha2, (const uint8_t *) k_opad, 64);
  SHA1Input(&sha2, (const uint8_t *) Message_Digest, 20);
  SHA1Result(&sha2, Message_Digest2);

  // TRACE("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n");
  //TRACE("HMAC-SHA1: ");
  // hexdump((char *)Message_Digest2,20);
  //TRACE("\n");

  return (char *) Message_Digest2;
}
示例#3
0
文件: MIB.C 项目: JoeAltmaier/Odyssey
mib_object_t *
MibRegister( ul32 *Id, u16 IdLen, mib_callback_t Rqs, u16 Type, u16 Support, void *Param )
{
    mib_object_t *object;

    object = (mib_object_t *)x_malloc(sizeof(mib_object_t));
    if (object == 0) {
        x_dbg("XSNMP, MibRegister: object is 0\n", TRUE);
        return 0;
    }
    if( !IdLen )
        x_dbg("XSNMP, MibRegister: Idlen == 0\n", TRUE);
    object->Id = (ul32 *)x_malloc(IdLen * sizeof(l32));
    if (object->Id == 0) {
        x_dbg("XSNMP, MibRegister: object->ID is 0\n", TRUE);
        return 0;
    }
    x_memcpy(object->Id, Id, IdLen * sizeof(l32));
    object->IdLen	= IdLen;
    object->Rqs		= Rqs;
    object->Type	= Type;
    object->Support	= Support;
    object->Param	= Param;

    if (!MibObjectInsert(object)) {
        x_free(object->Id);
        x_free(object);
        x_dbg("XSNMP, MibRegister: MibObjectInsert fail\n", TRUE);
        return 0;
    }

    return object;
}
示例#4
0
文件: x_stun.c 项目: biddyweb/xwbot
/**
 * set attribute of type to malloc'ed value copy of val.
 */
static int
stun_set_attr_d(stun_packet_t *pkt, int atype, int len, char *val)
{
  int i;

  i = stun_attr_id(pkt, atype);
  //TRACE("))))))))))))))))) 2 i=%d, attrnum(%d)\n",i,(int)pkt->attrnum);

  if (i < 0)
    {
      pkt->attrs = x_realloc(pkt->attrs,
          sizeof(stun_attr_t) * (pkt->attrnum + 2));
      i = pkt->attrnum;
    }

  //TRACE("))))))))))))))))) 3\n");

  pkt->attrs[i].type = (uint16_t) atype;
  pkt->attrs[i].len = (uint16_t) len;
  if (pkt->attrs[pkt->attrnum].len)
    {
      //      TRACE("))))))))))))))))) 4\n");

      pkt->attrs[i].data = x_malloc(pkt->attrs[i].len);
      x_memcpy(pkt->attrs[pkt->attrnum].data, val, len);
    }
  else
    pkt->attrs[i].data = NULL;
  // end with NULL
  pkt->attrs[++pkt->attrnum].type = 0;

  // TRACE("))))))))))))))))) 5\n");

  return 0;
}
示例#5
0
文件: x_stun.c 项目: biddyweb/xwbot
static stun_hdr_t *
stun_add_integrity(stun_hdr_t *pkt, const char *key)
{
  stun_hdr_t *hdr;
  char *ptr;
  char *msg_integrity;
  uint16_t mlen;
  char tdata[128];

  ENTER;

  mlen = ntohs(pkt->mlen) + sizeof(stun_hdr_t);
  // TRACE("----------------------- %d (%d,%d) \n", mlen,ntohs(pkt->mlen), sizeof(stun_packet_t));
  // add message integrity attribute
  hdr = x_realloc(pkt, mlen + 24);

  ptr = ((char *) hdr) + mlen;
  *(uint16_t*) ptr = htons(STUN_MSG_INTEGRITY);
  ptr += sizeof(uint16_t);
  *(uint16_t*) ptr = htons(20);
  ptr += sizeof(uint16_t);

  //TRACE("----------------------- %d\n",mlen);
  mlen += 24;
  //TRACE("----------------------- %d\n",mlen);
  hdr->mlen = htons(mlen - sizeof(stun_hdr_t));
  //TRACE("----------------------- %d\n",ntohs(hdr->mlen));

  x_memset(tdata, 0, sizeof(tdata));
  x_memcpy(tdata, hdr, mlen - 24);

  // Calc Message integrity
  msg_integrity = jingle_get_hmac_sha1(key, strlen(key), (char *) tdata,
      mlen - 24);

  x_memcpy(ptr, msg_integrity, 20);

  if (msg_integrity)
    x_free(msg_integrity);

  EXIT;
  return hdr;
}
示例#6
0
		virtual udx_address*	create(void* addrin, u32 addrinlen)
		{
			udx_hash hash = compute_hash(addrin, addrinlen);
			udx_haddress* h = find_by_hash(hash);
			if (h == nullptr)
			{
				h = (udx_haddress*)m_allocator->alloc(sizeof(udx_haddress));
				h->m_hash = hash;
				h->m_addrin.m_len = addrinlen;
				x_memcpy(h->m_addrin.m_data, addrin, addrinlen);
				add(h);
			}
			return h;
		}
示例#7
0
文件: x_stun.c 项目: biddyweb/xwbot
static uint32_t
stun_get_fingerprint(stun_hdr_t *pkt)
{
  uint32_t crc;
  uint16_t mlen;
  unsigned char tdata[128];

  ENTER;

  mlen = ntohs(pkt->mlen) + sizeof(stun_hdr_t);
  x_memset(tdata, 0, sizeof(tdata));
  x_memcpy(tdata, pkt, mlen - 8);
  crc = chksum_crc32(tdata, mlen - 8);

  EXIT;
  return crc;
}
示例#8
0
文件: x_stun.c 项目: biddyweb/xwbot
/**
 * set attribute of type to x_malloc'ed value copy of val.
 */
static stun_hdr_t *
stun_hdr_from_packet(stun_packet_t *pkt)
{
  int i;
  stun_attr_t *attrs = NULL;
  stun_hdr_t *hdr = NULL;
  char *ptr = NULL;
  uint16_t mlen, alen;

  ENTER;

  mlen = sizeof(stun_hdr_t);
  hdr = x_malloc(mlen);
  x_memset(hdr, 0, mlen);

  for (attrs = pkt->attrs, i = 0; i < pkt->attrnum; i++)
    {
      alen = ADDRLEN_ALIGN(attrs[i].len);

      hdr = x_realloc(hdr, mlen + alen + 2 * sizeof(uint16_t));
      ptr = ((char *) hdr) + mlen;

      // copy type
      *(uint16_t*) ptr = htons(attrs[i].type);
      ptr += sizeof(uint16_t);
      *(uint16_t*) ptr = htons(attrs[i].len);
      ptr += sizeof(uint16_t);
      // copy value
      x_memcpy(ptr, attrs[i].data, attrs[i].len);

      mlen += alen + 2 * sizeof(uint16_t);
      //  TRACE("----------------------> %d\n",mlen);
    }

  TRACE("--------------------->> %d (%d)\n", mlen, mlen - sizeof(stun_hdr_t));
  hdr->mlen = htons(mlen - sizeof(stun_hdr_t));

  EXIT;
  return hdr;
}
示例#9
0
文件: MIB.C 项目: JoeAltmaier/Odyssey
bool
MibInit ( mib_element_t *mib, u16 mibsize )
{
    i32 			commnr, i, n;
    agent_comm_t	*comm;
    u16 			support;
    mib_community_t	*mibprf, *p;

    mibprf = NULL;
    commnr = 0;

    for( n=1, comm = AgentCommunity(n); comm != 0; comm=comm->next, n++) {
        if( !comm ) {
            x_dbg("XSNMP, MibInit: no community defined in agent\n", TRUE);
        } else {
            switch( comm->access ) {
            case XSNMP_READ_ONLY:
                support = MIB_READ;
                break;
            case XSNMP_WRITE_ONLY:
                support = MIB_WRITE;
                break;
            case XSNMP_READ_WRITE:
                support = MIB_READ | MIB_WRITE;
                break;
            default:
                x_dbg("XSNMP, mib: invalid access specified\n", TRUE);
                break;
            }
            if( mibprf )
                p = (mib_community_t *)x_realloc(mibprf, (n+1)*sizeof(mib_community_t));
            else
                p = (mib_community_t *)x_malloc(sizeof(mib_community_t));
            if( !p ) {
                x_dbg("XSNMP, MibInit: out of community name space\n", TRUE);
            } else {
                mibprf = p;
                x_bzero( (i8 *)(mibprf[commnr].Comm), SNMP_SIZE_COMM );
                x_memcpy((i8 *)mibprf[commnr].Comm, (i8*)comm->comm, comm->commLen);
                mibprf[commnr].CommLen = comm->commLen;
                mibprf[commnr].Support = support;
                commnr++;
            }
        }
    }

    if(commnr == 0) {
        x_dbg("XSNMP, mib: no external access possible\n", TRUE);
        return FALSE;
    }

    Mib.Prf = mibprf;
    Mib.PrfSze = commnr;

    Mib.Obj = mib;
    Mib.ObjSze = mibsize;

    x_qsort((void *)Mib.Prf, Mib.PrfSze, sizeof(mib_community_t), (void *)MibCmpProfil);
    x_qsort((void *)Mib.Obj, Mib.ObjSze, sizeof(mib_element_t), (void *)MibCmpObject);

    MibRoot = (mib_root_t *)x_malloc(sizeof(mib_root_t));
    if( MibRoot == NULL )
        x_dbg("XSNMP, MibInit: could not allocate MibRoot\n", TRUE);
    MibRoot->Size = 100/*67*/;
    MibRoot->Count = 0;
    if( !MibRoot->Size )
        x_dbg("XSNMP, MibInit: MibRoot->Size == 0\n", TRUE);
    MibRoot->Table = (mib_object_t **)x_malloc(MibRoot->Size * sizeof(mib_object_t *));
    if( MibRoot->Table == NULL )
        x_dbg("XSNMP, MibInit: could not allocate MibRoot\n", TRUE);

    for (i=0; i<mibsize; i++) {
        if (!MibRegister(mib[i].Id, mib[i].IdLen, mib[i].Rqs, mib[i].Type,
                         mib[i].Support, 0)) {
            x_dbg("XSNMP, MibInit: register failed\n", TRUE);
            break;
        }
    }

    return TRUE;
}
示例#10
0
文件: MIB.C 项目: JoeAltmaier/Odyssey
static u16
Request( snmp_object_t *Obj, i32 *lastindex )
{
    i32 mindex, cmp;
    u16 error;

    if (MibRoot == NULL) {
        return SNMP_GENERROR;
    }

    error = SNMP_NOSUCHNAME;

    cmp = MibCmpObjId(MibRoot->Table[*lastindex]->Id, (u16)MibRoot->Table[*lastindex]->IdLen, Obj->Id, (u16)Obj->IdLen);

    if(cmp == -2 && Obj->Request == SNMP_PDU_NEXT &&
            ++(*lastindex) < MibRoot->Count) {
        cmp = MibCmpObjId(MibRoot->Table[*lastindex]->Id, (u16)MibRoot->Table[*lastindex]->IdLen, Obj->Id, (u16)Obj->IdLen);
    }

    if ( (cmp == -1) || (cmp == 0) ) {
        mindex = *lastindex;
    } else {
        mindex = *lastindex = MibObjectFind(Obj->Id, Obj->IdLen, &cmp);
    }

    switch(Obj->Request) {
    case SNMP_PDU_GET:
        if( ((cmp != -1) && (cmp != 0)) || MibRoot->Table[mindex]->Rqs == NULL) {
            return error;
        }
        if(!(MibRoot->Table[mindex]->Support & MIB_READ)) {
            return error;
        }
        error = MibRoot->Table[mindex]->Rqs(Obj, MibRoot->Table[mindex]->IdLen, MibRoot->Table[mindex]->Param);
        if(error == SNMP_NOERROR) {
            Obj->Type = MibRoot->Table[mindex]->Type;
        }
        return error;
    case SNMP_PDU_SET:
        if( ((cmp != -1) && (cmp != 0)) || MibRoot->Table[mindex]->Rqs == NULL) {
            return error;
        }
        if(!(MibRoot->Table[mindex]->Support & MIB_WRITE)) {
            return SNMP_BADVALUE;
        }
        if(Obj->Type == SNMP_OBJECTID && Obj->SyntaxLen > SNMP_SIZE_BUFINT) {
            return SNMP_BADVALUE;
        }
        if((Obj->Type == SNMP_OCTETSTR ||
                Obj->Type == SNMP_DISPLAYSTR ||
                Obj->Type == SNMP_OPAQUE) &&
                (Obj->SyntaxLen > SNMP_SIZE_BUFCHR)) {
            return SNMP_BADVALUE;
        }
        error = MibRoot->Table[mindex]->Rqs(Obj, MibRoot->Table[mindex]->IdLen, MibRoot->Table[mindex]->Param);
        return error;
    case SNMP_PDU_NEXT:
        switch(cmp) {
        case -2:
            return error;
        case -1:
        case 0:
            if(MibRoot->Table[mindex]->Support & MIB_READ &&
                    MibRoot->Table[mindex]->Rqs != NULL) {
                error = MibRoot->Table[mindex]->Rqs(Obj, MibRoot->Table[mindex]->IdLen, MibRoot->Table[mindex]->Param);
                if (error == SNMP_NOERROR) {
                    Obj->Type = MibRoot->Table[mindex]->Type;
                    break;
                }
            }
            mindex++;
            break;
        }
        while(error == SNMP_NOSUCHNAME && mindex < MibRoot->Count) {
            x_memcpy(Obj->Id, MibRoot->Table[mindex]->Id,
                     MibRoot->Table[mindex]->IdLen * sizeof(l32));
            Obj->IdLen = MibRoot->Table[mindex]->IdLen;
            if(MibRoot->Table[mindex]->Support & MIB_READ &&
                    MibRoot->Table[mindex]->Rqs != NULL) {
                error = MibRoot->Table[mindex]->Rqs(Obj, MibRoot->Table[mindex]->IdLen, MibRoot->Table[mindex]->Param);
                if(error == SNMP_NOERROR) {
                    Obj->Type = MibRoot->Table[mindex]->Type;
                    break;
                }
            }
            mindex++;
        }
        return error;
    case SNMP_PDU_COMMIT:
    case SNMP_PDU_UNDO:
        if( ((cmp != -1) && (cmp != 0)) || MibRoot->Table[mindex]->Rqs == NULL) {
            return error;
        }
        error = MibRoot->Table[mindex]->Rqs(Obj, MibRoot->Table[mindex]->IdLen, MibRoot->Table[mindex]->Param);
        return error;
    }

    return SNMP_GENERROR;
}
示例#11
0
文件: ncbistr.c 项目: fbtestrepo/hw
NLM_EXTERN Nlm_CharPtr LIBCALL Nlm_rule_line(const Nlm_Char FAR PNTR str,
                                             size_t len,
                                             enumRuleLine method)
{
  size_t str_len;
  size_t n_space;

  /* allocate and initialize the resulting string */
  Nlm_CharPtr s = (Nlm_CharPtr) Nlm_MemNew(len + 1);
  Nlm_MemSet(s, SPACE, len);
  s[len] = '\0';

  /* skip leading and trailing spaces */
  while ( IS_WHITESP(*str) )
    str++;
  if ( !*str )
    return s;
  for (str_len = Nlm_StringLen( str );  IS_WHITESP(str[str_len-1]); str_len--) continue;


  /* truncate the original string if doesn't fit */
  if (len <= str_len) {
    x_memcpy(s, str, len);
    return s;
  }

  n_space = len - str_len;
  switch ( method )
    {
    case RL_Left:
      {
        x_memcpy(s, str, str_len);
        break;
      }
    case RL_Right:
      {
        x_memcpy(s + n_space, str, str_len);
        break;
      }
    case RL_Spread:
      {
        size_t n_gap = 0;

        int prev_space = 0;
        const Nlm_Char FAR PNTR _str = str;
        size_t i = str_len;
        for ( ;  i--;  _str++)
          {
            ASSERT ( *_str );
            if ( IS_WHITESP(*_str) )
              {
                if ( !prev_space ) {
                  n_gap++;
                  prev_space = 1;
                }
                n_space++;
              }
            else
              prev_space = 0;
          }
        ASSERT ( !prev_space );

        if ( n_gap )
          {
            size_t n_div = n_space / n_gap;
            size_t n_mod = n_space % n_gap;

            Nlm_CharPtr _s = s;
            for (_str = str;  *_str; )
              {
                if ( !IS_WHITESP( *_str ) )
                  *_s++ = *_str++;
                else if ( n_space )
                  {
                    size_t n_add = n_div;
                    if (n_mod > 0) {
                      n_add++;
                      n_mod--;
                    }
                    n_space -= n_add;
                    while ( n_add-- )
                      *_s++ = SPACE;

                    for (_str++;  IS_WHITESP(*_str);  _str++) continue;
                  }
                else
                  break;
              }
            ASSERT ( _s == s + len );
            break;
          }  /* else -- use RL_Center */
      }

    case RL_Center:
      {
        x_memcpy(s + n_space/2, str, str_len);
        break;
      }

    default:
      ASSERT ( 0 );
      Nlm_MemFree( s );
      return 0;
    }

  return s;
}
示例#12
0
文件: x_stun.c 项目: biddyweb/xwbot
stun_packet_t *
stun_packet_from_hdr(stun_hdr_t *req, const char *key)
{
  stun_hdr_t *hdr;
  stun_packet_t *pkt = NULL;
  char *ptr = 0;
  uint16_t tmplen;
  uint32_t crc;
  char *msg_integrity;
  char tdata[128];

  ENTER;

  if (!req)
    return NULL;
  pkt = x_malloc(sizeof(stun_packet_t));

  pkt->hdr = req;
  pkt->len = sizeof(stun_hdr_t) + ntohs(req->mlen);

  TRACE("STUN PACKET: LEN[%d]\n", pkt->len);

  pkt->attrs = x_malloc(sizeof(stun_attr_t) * 1);
  pkt->attrnum = 0;
  pkt->attrs[0].type = 0;

  // parse attributes
  for (ptr = ((char *) req) + sizeof(stun_hdr_t);
      ptr < ((char *) req) + pkt->len;)
    {
      pkt->attrs = x_realloc(pkt->attrs,
          sizeof(stun_hdr_t) * (pkt->attrnum + 2));

      pkt->attrs[pkt->attrnum].type = ntohs(*((uint16_t *) ptr));
      /* check message integrity */
      if (STUN_MSG_INTEGRITY == pkt->attrs[pkt->attrnum].type && key)
        {

          TRACE(
              "Calculating MESSAGE-INTEGRITY with key='%s',keylen(%d),datalen(%d)\n",
              key, (int)strlen(key), (int)(ptr-(char *)req + 4));

          /* setup data */
          // _req = (stun_hdr_t *)tdata;
          tmplen = ptr - (char *) req;
          x_memset(tdata, 0, sizeof(tdata));
          x_memcpy(tdata, (char *) req, tmplen);
          hdr = (stun_hdr_t *) tdata;
          hdr->mlen = htons(tmplen - sizeof(stun_hdr_t) + 24);

          // Test print
          // hexdump(ptr+4,20);
          TRACE("MLEN(%d)(%d)(%d)\n",
              (int)sizeof(stun_hdr_t), (int)tmplen, (int)(tmplen - sizeof(stun_hdr_t) + 24));

          // Calc Message integrity
          msg_integrity = jingle_get_hmac_sha1("1234", 4, (char *) tdata,
              tmplen);
          if (msg_integrity)
            x_free(msg_integrity);
        }

      ptr += sizeof(uint16_t);
      pkt->attrs[pkt->attrnum].len = ntohs(*((uint16_t *) ptr));
      ptr += sizeof(uint16_t);

      // if attribute has value
      if (pkt->attrs[pkt->attrnum].len)
        {
          // copy data
          pkt->attrs[pkt->attrnum].data = x_malloc(
              pkt->attrs[pkt->attrnum].len);
          x_memcpy(pkt->attrs[pkt->attrnum].data, ptr,
              pkt->attrs[pkt->attrnum].len);
          ptr += ADDRLEN_ALIGN(pkt->attrs[pkt->attrnum].len);
        }
      else
        pkt->attrs[pkt->attrnum].data = NULL;

      TRACE("-- ATTRIBUTE, (%d): TYPE[0x%x],LEN[%d],DATA[%s]\n",
          pkt->attrnum, pkt->attrs[pkt->attrnum].type, pkt->attrs[pkt->attrnum].len, pkt->attrs[pkt->attrnum].data);

      pkt->attrs[++pkt->attrnum].type = 0;
    }

  crc = stun_get_fingerprint(req);
  TRACE("-- CRC (0x%x[0x%x])\n", crc, crc^STUN_FINGERPRINT_XOR);

  EXIT;

  return pkt;
}
示例#13
0
文件: x_stun.c 项目: biddyweb/xwbot
stun_hdr_t *
stun_get_response(const char *stun_key, stun_hdr_t *req, struct sockaddr *saddr)
{
  int i;
  char *ptr = 0;
  uint32_t crc;
  stun_packet_t *pkt, *pkt2;
  stun_hdr_t *resp = NULL;
  struct sockaddr_in _sai;

  ENTER;

  if (!stun_key || !req || !saddr)
    return NULL;

  pkt2 = stun_packet_from_hdr(req, stun_key);
  if (!pkt2)
    goto _ret_free_3;
  pkt = stun_pkt_new();
  if (!pkt)
    goto _ret_free_2;

  x_memcpy(&_sai, saddr, sizeof(_sai));

  // add xmapped
  // TRACE("\n");
  if ((ptr = stun_x_mapped(&_sai)))
    {
      stun_set_attr_d(pkt, STUN_X_MAPPED_ADDRESS, 8, ptr);
      x_free(ptr);
    }

  // copy username
  i = stun_attr_id(pkt2, STUN_USERNAME);
  if (i >= 0)
    {
      TRACE("STUN PACKET ADDING ATTRIBUTE: [%s] %d bytes\n",
          pkt2->attrs[i].data, pkt2->attrs[i].len);
      stun_set_attr_d(pkt, STUN_USERNAME, pkt2->attrs[i].len,
          pkt2->attrs[i].data);
    }

  //TRACE("++++++++++=== > stun_hdr_from_packet()\n");
  resp = stun_hdr_from_packet(pkt);
  //TRACE("++++++++++=== < stun_hdr_from_packet()\n");

  resp->mcookie = STUN_NET_M_COOKIE;
  resp->ver_type.raw = htons(STUN_RESP);

  // copy transction id
  x_memcpy(resp->trans_id, req->trans_id, 12);
  resp = stun_add_integrity(resp, stun_key);

  // TRACE("REPLYING STUN2 HEADER: ");
  i = ntohs(resp->mlen);
  // hexdump((char *)resp,i + 20);
  // TRACE("\n");
  // TRACE("STUN2 MLEN=%d\n",i);
  // _stun_packet_printf(pkt);

  // add CRC32
  i = ntohs(resp->mlen) + sizeof(stun_hdr_t);
  resp = x_realloc(resp, i + 8);
  resp->mlen = htons(i + 8 - sizeof(stun_hdr_t));

  crc = stun_get_fingerprint(resp);

  ptr = (char *) resp + i;
  *(uint16_t *) ptr = htons(STUN_FINGERPRINT);
  ptr += sizeof(uint16_t);
  *(uint16_t *) ptr = htons(4);
  ptr += sizeof(uint16_t);
  *(uint32_t *) ptr = htonl(crc ^ STUN_FINGERPRINT_XOR);

  if (pkt)
    stun_pkt_free(pkt);
  _ret_free_2: if (pkt2)
    stun_pkt_free(pkt2);
  _ret_free_3:

  EXIT;
  return resp;
}