"Fossies" - the Fresh Open Source Software Archive

Member "n2n-3.1.1/src/wire.c" (31 Mar 2022, 21815 Bytes) of package /linux/misc/n2n-3.1.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "wire.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.0_vs_3.1.1.

    1 /**
    2  * (C) 2007-22 - ntop.org and contributors
    3  *
    4  * This program is free software; you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation; either version 3 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not see see <http://www.gnu.org/licenses/>
   16  *
   17  */
   18 
   19 /** Routines for encoding and decoding n2n packets on the wire.
   20  *
   21  *  encode_X(base,idx,v) prototypes are inspired by the erlang internal
   22  *  encoding model. Passing the start of a buffer in base and a pointer to an
   23  *  integer (initially set to zero). Each encode routine increases idx by the
   24  *  amount written and returns the amount written. In this way complex sequences
   25  *  of encodings can be represented cleanly. See encode_register() for an
   26  *  example.
   27  */
   28 
   29 #include "n2n.h"
   30 
   31 
   32 int encode_uint8 (uint8_t * base,
   33                   size_t * idx,
   34                   const uint8_t v) {
   35 
   36     *(base + (*idx)) = (v & 0xff);
   37     ++(*idx);
   38 
   39     return 1;
   40 }
   41 
   42 int decode_uint8 (uint8_t * out,
   43                   const uint8_t * base,
   44                   size_t * rem,
   45                   size_t * idx) {
   46 
   47     if(*rem < 1) {
   48         return 0;
   49     }
   50 
   51     *out = ( base[*idx] & 0xff );
   52     ++(*idx);
   53     --(*rem);
   54 
   55     return 1;
   56 }
   57 
   58 int encode_uint16 (uint8_t * base,
   59                    size_t * idx,
   60                    const uint16_t v) {
   61 
   62     *(base + (*idx))     = ( v >> 8) & 0xff;
   63     *(base + (1 + *idx)) = ( v & 0xff );
   64     *idx += 2;
   65 
   66     return 2;
   67 }
   68 
   69 int decode_uint16 (uint16_t * out,
   70                    const uint8_t * base,
   71                    size_t * rem,
   72                    size_t * idx) {
   73 
   74     if(*rem < 2) {
   75         return 0;
   76     }
   77 
   78     *out  = ( base[*idx] & 0xff ) << 8;
   79     *out |= ( base[1 + *idx] & 0xff );
   80     *idx += 2;
   81     *rem -= 2;
   82 
   83     return 2;
   84 }
   85 
   86 int encode_uint32 (uint8_t * base,
   87                    size_t * idx,
   88                    const uint32_t v) {
   89 
   90     *(base + (0 + *idx)) = ( v >> 24) & 0xff;
   91     *(base + (1 + *idx)) = ( v >> 16) & 0xff;
   92     *(base + (2 + *idx)) = ( v >> 8) & 0xff;
   93     *(base + (3 + *idx)) = ( v & 0xff );
   94     *idx += 4;
   95 
   96     return 4;
   97 }
   98 
   99 int decode_uint32 (uint32_t * out,
  100                    const uint8_t * base,
  101                    size_t * rem,
  102                    size_t * idx) {
  103 
  104     if(*rem < 4) {
  105         return 0;
  106     }
  107 
  108     *out  = ( base[0 + *idx] & 0xff ) << 24;
  109     *out |= ( base[1 + *idx] & 0xff ) << 16;
  110     *out |= ( base[2 + *idx] & 0xff ) << 8;
  111     *out |= ( base[3 + *idx] & 0xff );
  112     *idx += 4;
  113     *rem -= 4;
  114 
  115     return 4;
  116 }
  117 
  118 int encode_uint64 (uint8_t * base,
  119                    size_t * idx,
  120                    const uint64_t v) {
  121 
  122     *(uint64_t*)(base + *idx) = htobe64(v);
  123     *idx += 8;
  124 
  125     return 8;
  126 }
  127 
  128 int decode_uint64 (uint64_t * out,
  129                    const uint8_t * base,
  130                    size_t * rem,
  131                    size_t * idx) {
  132 
  133     if(*rem < 8) {
  134         return 0;
  135     }
  136 
  137     *out  = be64toh(*(uint64_t*)base + *idx);
  138     *idx += 8;
  139     *rem -= 8;
  140 
  141     return 8;
  142 }
  143 
  144 int encode_buf (uint8_t * base,
  145                 size_t * idx,
  146                 const void * p,
  147                 size_t s) {
  148 
  149     memcpy((base + (*idx)), p, s);
  150     *idx += s;
  151 
  152     return s;
  153 }
  154 
  155 /* Copy from base to out of size bufsize */
  156 int decode_buf (uint8_t * out,
  157                 size_t bufsize,
  158                 const uint8_t * base,
  159                 size_t * rem,
  160                 size_t * idx) {
  161 
  162     if(*rem < bufsize) {
  163         return 0;
  164     }
  165 
  166     memcpy(out, (base + *idx), bufsize);
  167     *idx += bufsize;
  168     *rem -= bufsize;
  169 
  170     return bufsize;
  171 }
  172 
  173 
  174 int encode_mac (uint8_t * base,  /* n2n_mac_t is typedefed array type which is always passed by reference */
  175                 size_t * idx,
  176                 const n2n_mac_t m) {
  177 
  178     return encode_buf(base, idx, m, N2N_MAC_SIZE);
  179 }
  180 
  181 int decode_mac (n2n_mac_t out,
  182                 const uint8_t * base,
  183                 size_t * rem,
  184                 size_t * idx) {
  185 
  186     return decode_buf(out, N2N_MAC_SIZE, base, rem, idx);
  187 }
  188 
  189 int encode_cookie (uint8_t * base,
  190                    size_t * idx,
  191                    const n2n_cookie_t c) {
  192 
  193     return encode_uint32(base, idx, c);
  194 }
  195 
  196 int decode_cookie (n2n_cookie_t * out,  /* cookies are typedef'd as uint32_t which needs to correspond to this code */
  197                    const uint8_t * base,
  198                    size_t * rem,
  199                    size_t * idx) {
  200 
  201     return decode_uint32(out, base, rem, idx);
  202 }
  203 
  204 
  205 int encode_common (uint8_t * base,
  206                    size_t * idx,
  207                    const n2n_common_t * common) {
  208 
  209     uint16_t flags = 0;
  210 
  211     encode_uint8(base, idx, N2N_PKT_VERSION);
  212     encode_uint8(base, idx, common->ttl);
  213 
  214     flags  = common->pc & N2N_FLAGS_TYPE_MASK;
  215     flags |= common->flags & N2N_FLAGS_BITS_MASK;
  216 
  217     encode_uint16(base, idx, flags);
  218     encode_buf(base, idx, common->community, N2N_COMMUNITY_SIZE);
  219 
  220     return -1;
  221 }
  222 
  223 int decode_common (n2n_common_t * out,
  224                    const uint8_t * base,
  225                    size_t * rem,
  226                    size_t * idx) {
  227 
  228     size_t idx0 = *idx;
  229     uint8_t dummy = 0;
  230 
  231     decode_uint8(&dummy, base, rem, idx);
  232 
  233     if(N2N_PKT_VERSION != dummy) {
  234         return -1;
  235     }
  236 
  237     decode_uint8(&(out->ttl), base, rem, idx);
  238     decode_uint16(&(out->flags), base, rem, idx);
  239     out->pc = (out->flags & N2N_FLAGS_TYPE_MASK);
  240     out->flags &= N2N_FLAGS_BITS_MASK;
  241 
  242     decode_buf(out->community, N2N_COMMUNITY_SIZE, base, rem, idx);
  243 
  244     return (*idx - idx0);
  245 }
  246 
  247 
  248 int encode_sock (uint8_t * base,
  249                  size_t * idx,
  250                  const n2n_sock_t * sock) {
  251 
  252     int retval = 0;
  253     uint16_t f;
  254 
  255     switch(sock->family) {
  256         case AF_INET: {
  257             f = 0;
  258             retval += encode_uint16(base, idx, f);
  259             retval += encode_uint16(base, idx, sock->port);
  260             retval += encode_buf(base, idx, sock->addr.v4, IPV4_SIZE);
  261             break;
  262         }
  263 
  264         case AF_INET6: {
  265             f = 0x8000;
  266             retval += encode_uint16(base, idx, f);
  267             retval += encode_uint16(base, idx, sock->port);
  268             retval += encode_buf(base, idx, sock->addr.v6, IPV6_SIZE);
  269             break;
  270         }
  271 
  272         default:
  273             retval = -1;
  274     }
  275 
  276     return retval;
  277 }
  278 
  279 
  280 int decode_sock (n2n_sock_t * sock,
  281                  const uint8_t * base,
  282                  size_t * rem,
  283                  size_t * idx) {
  284 
  285     size_t * idx0 = idx;
  286     uint16_t f = 0;
  287 
  288     decode_uint16(&f, base, rem, idx);
  289 
  290     if(f & 0x8000) {
  291 
  292         /* IPv6 */
  293         sock->family = AF_INET6;
  294         decode_uint16(&(sock->port), base, rem, idx);
  295         decode_buf(sock->addr.v6, IPV6_SIZE, base, rem, idx);
  296     } else {
  297         /* IPv4 */
  298         sock->family = AF_INET;
  299         decode_uint16(&(sock->port), base, rem, idx);
  300         memset(sock->addr.v6, 0, IPV6_SIZE); /* so memcmp() works for equality. */
  301         decode_buf(sock->addr.v4, IPV4_SIZE, base, rem, idx);
  302     }
  303 
  304     return (idx - idx0);
  305 }
  306 
  307 
  308 int encode_REGISTER (uint8_t *base,
  309                      size_t *idx,
  310                      const n2n_common_t *common,
  311                      const n2n_REGISTER_t *reg) {
  312 
  313     int retval = 0;
  314 
  315     retval += encode_common(base, idx, common);
  316     retval += encode_cookie(base, idx, reg->cookie);
  317     retval += encode_mac(base, idx, reg->srcMac);
  318     retval += encode_mac(base, idx, reg->dstMac);
  319     if(common->flags & N2N_FLAGS_SOCKET) {
  320         retval += encode_sock(base, idx, &(reg->sock));
  321     }
  322     retval += encode_uint32(base, idx, reg->dev_addr.net_addr);
  323     retval += encode_uint8(base, idx, reg->dev_addr.net_bitlen);
  324     retval += encode_buf(base, idx, reg->dev_desc, N2N_DESC_SIZE);
  325 
  326     return retval;
  327 }
  328 
  329 
  330 int decode_REGISTER (n2n_REGISTER_t *reg,
  331                      const n2n_common_t *cmn, /* info on how to interpret it */
  332                      const uint8_t *base,
  333                      size_t *rem,
  334                      size_t *idx) {
  335 
  336     size_t retval = 0;
  337     memset(reg, 0, sizeof(n2n_REGISTER_t));
  338 
  339     retval += decode_cookie(&reg->cookie, base, rem, idx);
  340     retval += decode_mac(reg->srcMac, base, rem, idx);
  341     retval += decode_mac(reg->dstMac, base, rem, idx);
  342     if(cmn->flags & N2N_FLAGS_SOCKET) {
  343         retval += decode_sock(&(reg->sock), base, rem, idx);
  344     }
  345     retval += decode_uint32(&(reg->dev_addr.net_addr), base, rem, idx);
  346     retval += decode_uint8(&(reg->dev_addr.net_bitlen), base, rem, idx);
  347     retval += decode_buf(reg->dev_desc, N2N_DESC_SIZE, base, rem, idx);
  348 
  349     return retval;
  350 }
  351 
  352 
  353 int encode_REGISTER_SUPER (uint8_t *base,
  354                            size_t *idx,
  355                            const n2n_common_t *common,
  356                            const n2n_REGISTER_SUPER_t *reg) {
  357 
  358     int retval = 0;
  359 
  360     retval += encode_common(base, idx, common);
  361     retval += encode_cookie(base, idx, reg->cookie);
  362     retval += encode_mac(base, idx, reg->edgeMac);
  363     if(common->flags & N2N_FLAGS_SOCKET) {
  364         retval += encode_sock(base, idx, &(reg->sock));
  365     }
  366     retval += encode_uint32(base, idx, reg->dev_addr.net_addr);
  367     retval += encode_uint8(base, idx, reg->dev_addr.net_bitlen);
  368     retval += encode_buf(base, idx, reg->dev_desc, N2N_DESC_SIZE);
  369     retval += encode_uint16(base, idx, reg->auth.scheme);
  370     retval += encode_uint16(base, idx, reg->auth.token_size);
  371     retval += encode_buf(base, idx, reg->auth.token, reg->auth.token_size);
  372     retval += encode_uint32(base, idx, reg->key_time);
  373 
  374     return retval;
  375 }
  376 
  377 
  378 int decode_REGISTER_SUPER (n2n_REGISTER_SUPER_t *reg,
  379                            const n2n_common_t *cmn, /* info on how to interpret it */
  380                            const uint8_t *base,
  381                            size_t *rem,
  382                            size_t *idx) {
  383 
  384     size_t retval = 0;
  385     memset(reg, 0, sizeof(n2n_REGISTER_SUPER_t));
  386 
  387     retval += decode_cookie(&reg->cookie, base, rem, idx);
  388     retval += decode_mac(reg->edgeMac, base, rem, idx);
  389     if(cmn->flags & N2N_FLAGS_SOCKET) {
  390         retval += decode_sock(&(reg->sock), base, rem, idx);
  391     }
  392     retval += decode_uint32(&(reg->dev_addr.net_addr), base, rem, idx);
  393     retval += decode_uint8(&(reg->dev_addr.net_bitlen), base, rem, idx);
  394     retval += decode_buf(reg->dev_desc, N2N_DESC_SIZE, base, rem, idx);
  395     retval += decode_uint16(&(reg->auth.scheme), base, rem, idx);
  396     retval += decode_uint16(&(reg->auth.token_size), base, rem, idx);
  397     retval += decode_buf(reg->auth.token, reg->auth.token_size, base, rem, idx);
  398     retval += decode_uint32(&(reg->key_time), base, rem, idx);
  399 
  400     return retval;
  401 }
  402 
  403 
  404 int encode_UNREGISTER_SUPER (uint8_t *base,
  405                              size_t *idx,
  406                              const n2n_common_t *common,
  407                              const n2n_UNREGISTER_SUPER_t *unreg) {
  408 
  409     int retval = 0;
  410 
  411     retval += encode_common(base, idx, common);
  412     retval += encode_uint16(base, idx, unreg->auth.scheme);
  413     retval += encode_uint16(base, idx, unreg->auth.token_size);
  414     retval += encode_buf(base, idx, unreg->auth.token, unreg->auth.token_size);
  415     retval += encode_mac(base, idx, unreg->srcMac);
  416 
  417     return retval;
  418 }
  419 
  420 
  421 int decode_UNREGISTER_SUPER (n2n_UNREGISTER_SUPER_t *unreg,
  422                              const n2n_common_t *cmn, /* info on how to interpret it */
  423                              const uint8_t *base,
  424                              size_t *rem,
  425                              size_t *idx) {
  426 
  427     size_t retval = 0;
  428     memset(unreg, 0, sizeof(n2n_UNREGISTER_SUPER_t));
  429 
  430     retval += decode_uint16(&(unreg->auth.scheme), base, rem, idx);
  431     retval += decode_uint16(&(unreg->auth.token_size), base, rem, idx);
  432     retval += decode_buf(unreg->auth.token, unreg->auth.token_size, base, rem, idx);
  433     retval += decode_mac(unreg->srcMac, base, rem, idx);
  434 
  435     return retval;
  436 }
  437 
  438 
  439 int encode_REGISTER_ACK (uint8_t *base,
  440                          size_t *idx,
  441                          const n2n_common_t *common,
  442                          const n2n_REGISTER_ACK_t *reg) {
  443 
  444     int retval = 0;
  445 
  446     retval += encode_common(base, idx, common);
  447     retval += encode_cookie(base, idx, reg->cookie);
  448     retval += encode_mac(base, idx, reg->dstMac);
  449     retval += encode_mac(base, idx, reg->srcMac);
  450 
  451     /* The socket in REGISTER_ACK is the socket from which the REGISTER
  452      * arrived. This is sent back to the sender so it knows what its public
  453      * socket is. */
  454     if(common->flags & N2N_FLAGS_SOCKET) {
  455         retval += encode_sock(base, idx, &(reg->sock));
  456     }
  457 
  458     return retval;
  459 }
  460 
  461 
  462 int decode_REGISTER_ACK (n2n_REGISTER_ACK_t *reg,
  463                          const n2n_common_t *cmn, /* info on how to interpret it */
  464                          const uint8_t *base,
  465                          size_t *rem,
  466                          size_t *idx) {
  467 
  468     size_t retval = 0;
  469     memset(reg, 0, sizeof(n2n_REGISTER_ACK_t));
  470 
  471     retval += decode_cookie(&reg->cookie, base, rem, idx);
  472     retval += decode_mac(reg->dstMac, base, rem, idx);
  473     retval += decode_mac(reg->srcMac, base, rem, idx);
  474 
  475     /* The socket in REGISTER_ACK is the socket from which the REGISTER
  476      * arrived. This is sent back to the sender so it knows what its public
  477      * socket is. */
  478     if(cmn->flags & N2N_FLAGS_SOCKET) {
  479         retval += decode_sock(&(reg->sock), base, rem, idx);
  480     }
  481 
  482     return retval;
  483 }
  484 
  485 
  486 int encode_REGISTER_SUPER_ACK (uint8_t *base,
  487                                size_t *idx,
  488                                const n2n_common_t *common,
  489                                const n2n_REGISTER_SUPER_ACK_t *reg,
  490                                uint8_t *tmpbuf) {
  491 
  492     int retval = 0;
  493 
  494     retval += encode_common(base, idx, common);
  495     retval += encode_cookie(base, idx, reg->cookie);
  496     retval += encode_mac(base, idx, reg->srcMac);
  497     retval += encode_uint32(base, idx, reg->dev_addr.net_addr);
  498     retval += encode_uint8(base, idx, reg->dev_addr.net_bitlen);
  499     retval += encode_uint16(base, idx, reg->lifetime);
  500 
  501     retval += encode_sock(base, idx, &(reg->sock));
  502 
  503     retval += encode_uint16(base, idx, reg->auth.scheme);
  504     retval += encode_uint16(base, idx, reg->auth.token_size);
  505     retval += encode_buf(base, idx, reg->auth.token, reg->auth.token_size);
  506 
  507     retval += encode_uint8(base, idx, reg->num_sn);
  508     retval += encode_buf(base, idx, tmpbuf, (reg->num_sn*REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE));
  509 
  510     retval += encode_uint32(base, idx, reg->key_time);
  511 
  512     return retval;
  513 }
  514 
  515 
  516 int decode_REGISTER_SUPER_ACK (n2n_REGISTER_SUPER_ACK_t *reg,
  517                                const n2n_common_t *cmn, /* info on how to interpret it */
  518                                const uint8_t *base,
  519                                size_t *rem,
  520                                size_t *idx,
  521                                uint8_t *tmpbuf) {
  522 
  523     size_t retval = 0;
  524     memset(reg, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
  525 
  526     retval += decode_cookie(&reg->cookie, base, rem, idx);
  527     retval += decode_mac(reg->srcMac, base, rem, idx);
  528     retval += decode_uint32(&(reg->dev_addr.net_addr), base, rem, idx);
  529     retval += decode_uint8(&(reg->dev_addr.net_bitlen), base, rem, idx);
  530     retval += decode_uint16(&(reg->lifetime), base, rem, idx);
  531 
  532     /* Socket is mandatory in this message type */
  533     retval += decode_sock(&(reg->sock), base, rem, idx);
  534 
  535     retval += decode_uint16(&(reg->auth.scheme), base, rem, idx);
  536     retval += decode_uint16(&(reg->auth.token_size), base, rem, idx);
  537     retval += decode_buf(reg->auth.token, reg->auth.token_size, base, rem, idx);
  538 
  539     /* Following the edge socket are an array of backup supernodes. */
  540     retval += decode_uint8(&(reg->num_sn), base, rem, idx);
  541     retval += decode_buf(tmpbuf, (reg->num_sn * REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE), base, rem, idx);
  542 
  543     retval += decode_uint32(&(reg->key_time), base, rem, idx);
  544 
  545     return retval;
  546 }
  547 
  548 
  549 int encode_REGISTER_SUPER_NAK (uint8_t *base,
  550                                size_t *idx,
  551                                const n2n_common_t *common,
  552                                const n2n_REGISTER_SUPER_NAK_t *nak) {
  553 
  554     int retval = 0;
  555 
  556     retval += encode_common(base, idx, common);
  557     retval += encode_cookie(base, idx, nak->cookie);
  558     retval += encode_mac(base, idx, nak->srcMac);
  559 
  560     retval += encode_uint16(base, idx, nak->auth.scheme);
  561     retval += encode_uint16(base, idx, nak->auth.token_size);
  562     retval += encode_buf(base, idx, nak->auth.token, nak->auth.token_size);
  563 
  564     return retval;
  565 }
  566 
  567 
  568 int decode_REGISTER_SUPER_NAK (n2n_REGISTER_SUPER_NAK_t *nak,
  569                                const n2n_common_t *cmn, /* info on how to interpret it */
  570                                const uint8_t *base,
  571                                size_t *rem,
  572                                size_t *idx) {
  573 
  574     size_t retval = 0;
  575     memset(nak, 0, sizeof(n2n_REGISTER_SUPER_NAK_t));
  576 
  577     retval += decode_cookie(&nak->cookie, base, rem, idx);
  578     retval += decode_mac(nak->srcMac, base, rem, idx);
  579 
  580     retval += decode_uint16(&(nak->auth.scheme), base, rem, idx);
  581     retval += decode_uint16(&(nak->auth.token_size), base, rem, idx);
  582     retval += decode_buf(nak->auth.token, nak->auth.token_size, base, rem, idx);
  583 
  584     return retval;
  585 }
  586 
  587 
  588 int fill_sockaddr (struct sockaddr * addr,
  589                    size_t addrlen,
  590                    const n2n_sock_t * sock) {
  591 
  592     int retval = -1;
  593 
  594     if(AF_INET == sock->family) {
  595         if(addrlen >= sizeof(struct sockaddr_in)) {
  596             struct sockaddr_in * si = (struct sockaddr_in *)addr;
  597             si->sin_family = sock->family;
  598             si->sin_port = htons(sock->port);
  599             memcpy(&(si->sin_addr.s_addr), sock->addr.v4, IPV4_SIZE);
  600             retval = 0;
  601         }
  602     }
  603 
  604     return retval;
  605 }
  606 
  607 
  608 int encode_PACKET (uint8_t * base,
  609                    size_t * idx,
  610                    const n2n_common_t * common,
  611                    const n2n_PACKET_t * pkt) {
  612 
  613     int retval = 0;
  614 
  615     retval += encode_common(base, idx, common);
  616     retval += encode_mac(base, idx, pkt->srcMac);
  617     retval += encode_mac(base, idx, pkt->dstMac);
  618     if(common->flags & N2N_FLAGS_SOCKET) {
  619         retval += encode_sock(base, idx, &(pkt->sock));
  620     }
  621     retval += encode_uint8(base, idx, pkt->compression);
  622     retval += encode_uint8(base, idx, pkt->transform);
  623 
  624     return retval;
  625 }
  626 
  627 
  628 int decode_PACKET (n2n_PACKET_t * pkt,
  629                    const n2n_common_t * cmn, /* info on how to interpret it */
  630                    const uint8_t * base,
  631                    size_t * rem,
  632                    size_t * idx) {
  633 
  634     size_t retval = 0;
  635     memset(pkt, 0, sizeof(n2n_PACKET_t));
  636 
  637     retval += decode_mac(pkt->srcMac, base, rem, idx);
  638     retval += decode_mac(pkt->dstMac, base, rem, idx);
  639 
  640     if(cmn->flags & N2N_FLAGS_SOCKET) {
  641         retval += decode_sock(&(pkt->sock), base, rem, idx);
  642     }
  643 
  644     retval += decode_uint8(&(pkt->compression), base, rem, idx);
  645     retval += decode_uint8(&(pkt->transform), base, rem, idx);
  646 
  647     return retval;
  648 }
  649 
  650 
  651 int encode_PEER_INFO (uint8_t *base,
  652                       size_t *idx,
  653                       const n2n_common_t *cmn,
  654                       const n2n_PEER_INFO_t *pkt) {
  655 
  656     int retval = 0;
  657 
  658     retval += encode_common(base, idx, cmn);
  659     retval += encode_uint16(base, idx, pkt->aflags);
  660     retval += encode_mac(base, idx, pkt->srcMac);
  661     retval += encode_mac(base, idx, pkt->mac);
  662     retval += encode_sock(base, idx, &pkt->sock);
  663     if(cmn->flags & N2N_FLAGS_SOCKET) {
  664         retval += encode_sock(base, idx, &pkt->preferred_sock);
  665     }
  666     retval += encode_uint32(base, idx, (uint32_t)pkt->load);
  667     retval += encode_uint32(base, idx, (uint32_t)pkt->uptime);
  668     retval += encode_buf(base, idx, pkt->version, sizeof(n2n_version_t));
  669 
  670     return retval;
  671 }
  672 
  673 
  674 int decode_PEER_INFO (n2n_PEER_INFO_t *pkt,
  675                       const n2n_common_t *cmn, /* info on how to interpret it */
  676                       const uint8_t *base,
  677                       size_t *rem,
  678                       size_t *idx) {
  679 
  680     size_t retval = 0;
  681     memset(pkt, 0, sizeof(n2n_PEER_INFO_t));
  682 
  683     retval += decode_uint16(&(pkt->aflags), base, rem, idx);
  684     retval += decode_mac(pkt->srcMac, base, rem, idx);
  685     retval += decode_mac(pkt->mac, base, rem, idx);
  686     retval += decode_sock(&pkt->sock, base, rem, idx);
  687     if(cmn->flags & N2N_FLAGS_SOCKET) {
  688         retval += decode_sock(&pkt->preferred_sock, base, rem, idx);
  689     }
  690     retval += decode_uint32(&pkt->load, base, rem, idx);
  691     retval += decode_uint32((uint32_t*)&pkt->uptime, base, rem, idx);
  692     retval += decode_buf((uint8_t*)pkt->version, sizeof(n2n_version_t), base, rem, idx);
  693 
  694     return retval;
  695 }
  696 
  697 
  698 int encode_QUERY_PEER (uint8_t * base,
  699                        size_t * idx,
  700                        const n2n_common_t * common,
  701                        const n2n_QUERY_PEER_t * pkt) {
  702 
  703     int retval = 0;
  704 
  705     retval += encode_common(base, idx, common);
  706     retval += encode_mac(base, idx, pkt->srcMac);
  707     retval += encode_mac(base, idx, pkt->targetMac);
  708     retval += encode_uint16(base, idx, pkt->aflags);
  709 
  710     return retval;
  711 }
  712 
  713 int decode_QUERY_PEER (n2n_QUERY_PEER_t * pkt,
  714                        const n2n_common_t * cmn, /* info on how to interpret it */
  715                        const uint8_t * base,
  716                        size_t * rem,
  717                        size_t * idx) {
  718 
  719     size_t retval = 0;
  720     memset(pkt, 0, sizeof(n2n_QUERY_PEER_t));
  721 
  722     retval += decode_mac(pkt->srcMac, base, rem, idx);
  723     retval += decode_mac(pkt->targetMac, base, rem, idx);
  724     retval += decode_uint16(&(pkt->aflags), base, rem, idx);
  725 
  726     return retval;
  727 }