// File: /workspace/github_c_makefile_star2_O2/jech[P]shncpd/receive.c
// Function: parse_packet
int
parse_packet(const unsigned char *buf, int buflen,
             struct sockaddr_in6 *from, int unicast,
             struct interface *interface)
{
    unsigned char id[4];
    unsigned int eid = 42;      /* silence gcc */
    int have_id = 0;
    int i = 0, rc;
    int recompute = 0;

    if(debug_level >= 3)
        debugf("Received %d bytes.\n", buflen);

    while(i < buflen) {
        unsigned const char *tlv = buf + i;
        int type, bodylen;

        if(buflen - i < 4) {
            fprintf(stderr, "Received truncated TLV.\n");
            goto fail;
        }

        DO_NTOHS(type, tlv);
        DO_NTOHS(bodylen, tlv + 2);
        if(buflen - i < 4 + bodylen) {
            fprintf(stderr, "Received truncated TLV.\n");
            goto fail;
        }

        switch(type) {
        case 1: {
            debugf("   REQ-NETWORK-STATE\n");
            int i;
            buffer_network_state(from, NULL);
            for(i = 0; i < numnodes; i++)
                buffer_node_state(&nodes[i], 0, from, NULL);
            break;
        }
        case 2: {
            struct node *node;
            if(bodylen < 4) {
                fprintf(stderr, "Truncated REQ-NODE-STATE\n");
                goto fail;
            }
            debugf("   REQ-NODE-STATE %s\n", format_32(tlv + 4));
            node = find_node(tlv + 4, 0);
            if(node)
                buffer_node_state(node, 1, from, NULL);
            break;
        }
        case 3: {
            struct neighbour *neigh;
            if(bodylen < 8) {
                fprintf(stderr, "Truncated NODE-ENDPOINT.\n");
                break;
            }
            if(have_id) {
                fprintf(stderr, "Duplicate NODE-ENDPOINT.\n");
                break;
            }
            memcpy(id, tlv + 4, 4);
            DO_NTOHL(eid, tlv + 8);
            debugf("   NODE-ENDPOINT %s %u\n", format_32(id), eid);
            if(id_eq(id, myid)) {
                fprintf(stderr, "Node id collision.\n");
                goto fail;
            }
            have_id = 1;
            if(unicast) {
                neigh = find_neighbour(interface, id, eid, from);
                if(neigh && unicast)
                    neigh->last_contact = now;
            }
            break;
        }
        case 4: {
            int rc;
            unsigned char h[8];
            struct neighbour *neigh = NULL;
            struct timespec t;

            if(have_id)
                neigh = find_neighbour(interface, id, eid, NULL);

            if(bodylen < 8) {
                fprintf(stderr, "Truncated NETWORK-STATE.\n");
                goto fail;
            }

            rc = network_hash(h);
            if(rc < 0) {
                fprintf(stderr, "Eek!\n");
                goto fail;
            }

            if(memcmp(h, tlv + 4, 8) == 0) {
                debugf("   NETWORK-STATE %s (consistent)\n",
                       format_64(tlv + 4));
                if(neigh)
                    neigh->last_contact = now;
                trickle_reset(&interface->trickle, 1);
                break;
            }

            debugf("   NETWORK-STATE %s (inconsistent, %s)\n",
                   format_64(tlv + 4), format_64(h));
            /* But don't reset Trickle. */

            ts_add_msec(&t, &interface->last_request_sent, HNCP_I_min);
            if(ts_compare(&now, &t) >= 0) {
                interface->last_request_sent = now;
                debugf("-> REQ-NETWORK-STATE\n");
                buffer_tlv(1, NULL, 0, from, NULL);
            }
            break;
        }
        case 5: {
            struct node *node;
            unsigned int seqno;
            int msecs, mine;
            int datalen = bodylen - 20;

            if(bodylen < 20) {
                fprintf(stderr, "Truncated NODE-STATE.\n");
                goto fail;
            }

            if(!have_id) {
                fprintf(stderr, "NODE-STATE with no NODE-ENDPOINT.\n");
            }

            DO_NTOHL(seqno, tlv + 8);
            DO_NTOHL(msecs, tlv + 12);

            debugf("   NODE-STATE %s %d %d", format_32(tlv + 4), seqno, msecs);

            mine = id_eq(tlv + 4, myid);
            if(mine)
                debugf(" (mine)");

            node = find_node(tlv + 4, 0);

            if(node && (seqno - node->seqno) & 0x80000000) {
                debugf(" (older)\n");
            } else if(!node || seqno != node->seqno ||
                      memcmp(tlv + 16, node->datahash, 8) != 0) {
                debugf(" (newer%s, %s)\n",
                       datalen ? ", data" : "", format_64(tlv + 16));

                if(mine) {
                    fprintf(stderr,
                            "Duplicate node identifier -- reclaiming.\n");
                    node->seqno = seqno + 42;
                    break;
                }

                if(datalen) {
                    unsigned char *new_data;
                    unsigned char h[8];
                    int rc;

                    node_hash(h, tlv + 24, datalen);
                    if(memcmp(h, tlv + 16, 8) != 0) {
                        fprintf(stderr, "Corrupt hash.\n");
                        goto fail;
                    }

                    if(!node)
                        node = find_node(tlv + 4, 1);
                    if(!node) {
                        fprintf(stderr, "Couldn't create node.\n");
                        goto fail;
                    }

                    new_data = realloc(node->data, datalen);
                    if(new_data == NULL) {
                        fprintf(stderr, "Eek!\n");
                        goto fail;
                    }
                    node->interface = interface;
                    node->seqno = seqno;
                    ts_add_msec(&node->orig_time, &now, msecs + 1);
                    node->data = new_data;
                    memcpy(node->data, tlv + 24, datalen);
                    node->datalen = datalen;
                    memcpy(node->datahash, tlv + 16, 8);
                    rc = parse_node_state(node);
                    if(rc < 0)
                        fprintf(stderr, "Couldn't parse node state.\n");
                    else
                        trickle_reset_all();
                    recompute = 1;
                } else {
                    struct neighbour *neigh = NULL;
                    if(have_id)
                        neigh = find_neighbour(interface, id, eid, from);
                    if(neigh) {
                        debugf("-> REQ-NODE-STATE %s\n", format_32(tlv + 4));
                        buffer_tlv(2, tlv + 4, 4, from, NULL);
                    } else
                        fprintf(stderr, "No neighbour to send request to.\n");
                }
            } else {
                debugf(" (consistent)\n");
            }
            break;
        }
        default:
            if(debug_level >= 3)
                debugf("   %d: %d\n", type, bodylen);
            break;
            break;
        }
        i += 4 + bodylen;
        i += -i & 3;
    }

    rc = 1;
    goto done;

 fail:
    rc = -1;

 done:
    if(recompute) {
        int r;
        silly_walk(find_node(myid, 0));
        r = prefix_assignment(1);
        if(r > 0)
            republish(0, 1);
    }
    return rc;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %r8, %rbx
movl %ecx, 0x40(%rsp)
movq %rdx, %rbp
movl %esi, 0x2c(%rsp)
movq %rdi, 0x60(%rsp)
leaq 0xc2b8(%rip), %rax      # 0x11258
cmpl $0x3, (%rax)
jge 0x576f
leaq 0x10(%rbx), %rax
movq %rax, 0x48(%rsp)
movq %rbx, 0x30(%rsp)
leaq 0x30(%rbx), %rax
movq %rax, 0x58(%rsp)
pushq $0x2a
popq %rax
movl %eax, 0xc(%rsp)
pushq $0x1
popq %r12
movl $0x0, 0x4(%rsp)
xorl %r13d, %r13d
movl $0x0, 0x8(%rsp)
movq %rbp, 0x20(%rsp)
movl 0x2c(%rsp), %eax
subl %r13d, %eax
jle 0x5729
cmpl $0x3, %eax
jle 0x5709
movslq %r13d, %r14
addq 0x60(%rsp), %r14
movzwl 0x2(%r14), %ebp
rolw $0x8, %bp
movzwl %bp, %ebx
leal 0x4(%rbx), %r15d
cmpl %r15d, %eax
jb 0x5709
movzwl (%r14), %eax
rolw $0x8, %ax
movzwl %ax, %edx
leal -0x1(%rdx), %eax
cmpl $0x4, %eax
ja 0x5327
leaq 0x7798(%rip), %rcx      # 0xc7d0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0xc210(%rip), %rax      # 0x11258
cmpl $0x2, (%rax)
jge 0x54d6
movq 0x20(%rsp), %rbp
movq %rbp, %rdi
xorl %esi, %esi
callq 0x46c9
leaq 0xd829(%rip), %rbx      # 0x12890
xorl %r14d, %r14d
leaq 0xc233(%rip), %rax      # 0x112a4
movslq (%rax), %rax
cmpq %rax, %r14
jge 0x567c
movq %rbx, %rdi
xorl %esi, %esi
movq %rbp, %rdx
xorl %ecx, %ecx
callq 0x4741
incq %r14
addq $0x70, %rbx
jmp 0x506a
cmpw $0x13, %bp
jbe 0x57a1
cmpl $0x0, 0x8(%rsp)
je 0x5502
movl 0x8(%r14), %eax
movl 0xc(%r14), %ebp
bswapl %eax
movl %eax, 0x14(%rsp)
bswapl %ebp
leaq 0xc197(%rip), %rax      # 0x11258
cmpl $0x2, (%rax)
movl %ebp, 0x44(%rsp)
jge 0x5523
xorl %r12d, %r12d
leaq 0x4(%r14), %rdi
movq %rdi, 0x18(%rsp)
leaq 0xc19f(%rip), %rsi      # 0x11280
callq 0x5827
movl %eax, %ebp
testl %eax, %eax
je 0x50f5
testb %r12b, %r12b
jne 0x54ec
movq 0x18(%rsp), %rdi
xorl %esi, %esi
callq 0x3d24
movq %rax, %r12
testq %rax, %rax
je 0x5129
movl 0x14(%rsp), %eax
cmpl 0x24(%r12), %eax
js 0x5473
jne 0x5129
movq 0x10(%r14), %rax
cmpq 0x1c(%r12), %rax
je 0x548f
addl $-0x14, %ebx
leaq 0xc125(%rip), %rax      # 0x11258
cmpl $0x2, (%rax)
jge 0x55c4
testl %ebp, %ebp
jne 0x5604
testl %ebx, %ebx
movq 0x20(%rsp), %rbp
je 0x541a
leaq 0x18(%r14), %rbp
leaq 0x68(%rsp), %rdi
movq %rbp, %rsi
movl %ebx, %edx
callq 0x420c
movq 0x68(%rsp), %rax
cmpq 0x10(%r14), %rax
jne 0x57fc
testq %r12, %r12
jne 0x5191
movq 0x18(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x3d24
movq %rax, %r12
testq %rax, %rax
je 0x5814
movq %rbp, 0x18(%rsp)
movq 0x10(%r12), %rdi
movslq %ebx, %rsi
movq %rsi, 0x38(%rsp)
callq 0x2290
testq %rax, %rax
je 0x5789
movq %rax, %rbp
addq $0x10, %r14
movq 0x30(%rsp), %rax
movq %rax, (%r12)
movl 0x14(%rsp), %eax
movl %eax, 0x24(%r12)
leaq 0x28(%r12), %rdi
movl 0x44(%rsp), %edx
incl %edx
leaq 0xc094(%rip), %rsi      # 0x11270
callq 0xa7e7
movq %rbp, 0x10(%r12)
movq %rbp, %rdi
movq 0x18(%rsp), %rsi
movq 0x38(%rsp), %rdx
callq 0x2220
movl %ebx, 0x18(%r12)
movq (%r14), %rax
movq %rax, 0x1c(%r12)
movq %r12, %rdi
callq 0x5831
testl %eax, %eax
js 0x5691
callq 0x38bc
pushq $0x1
popq %r12
movl %r12d, 0x4(%rsp)
jmp 0x567c
cmpw $0x7, %bp
jbe 0x54b5
cmpl $0x0, 0x8(%rsp)
movq 0x20(%rsp), %rbp
jne 0x557c
movl 0x4(%r14), %eax
movl %eax, 0x10(%rsp)
movl 0x8(%r14), %eax
bswapl %eax
movl %eax, 0xc(%rsp)
leaq 0xbffd(%rip), %rax      # 0x11258
cmpl $0x2, (%rax)
jge 0x559d
leaq 0x10(%rsp), %rdi
leaq 0xc010(%rip), %rsi      # 0x11280
callq 0x5827
testl %eax, %eax
jne 0x57e4
cmpl $0x0, 0x40(%rsp)
je 0x52ad
movq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rsi
movl 0xc(%rsp), %edx
movq %rbp, %rcx
callq 0x3951
testq %rax, %rax
je 0x52ad
leaq 0xbfca(%rip), %rcx      # 0x11270
movups (%rcx), %xmm0
movups %xmm0, 0x28(%rax)
movl %r12d, 0x8(%rsp)
jmp 0x567c
cmpl $0x0, 0x8(%rsp)
je 0x534f
movq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rsi
movl 0xc(%rsp), %edx
xorl %ecx, %ecx
callq 0x3951
movq %rax, %rbx
jmp 0x5351
cmpw $0x4, %bp
jb 0x57b9
leaq 0xbf6b(%rip), %rax      # 0x11258
cmpl $0x2, (%rax)
movq 0x20(%rsp), %rbp
jge 0x555a
addq $0x4, %r14
movq %r14, %rdi
xorl %esi, %esi
callq 0x3d24
testq %rax, %rax
je 0x567c
movq %rax, %rdi
movl %r12d, %esi
movq %rbp, %rdx
xorl %ecx, %ecx
callq 0x4741
jmp 0x567c
leaq 0xbf2a(%rip), %rax      # 0x11258
cmpl $0x3, (%rax)
jl 0x567c
pushq $0x2
popq %rdi
leaq 0x7927(%rip), %rsi      # 0xcc68
movl %ebx, %ecx
xorl %eax, %eax
callq 0x23c0
jmp 0x567c
xorl %ebx, %ebx
cmpw $0x7, %bp
jbe 0x57cc
leaq 0x50(%rsp), %rdi
callq 0x4259
testl %eax, %eax
js 0x5789
leaq 0x4(%r14), %rdi
movq 0x50(%rsp), %rcx
leaq 0xbedb(%rip), %rax      # 0x11258
movl (%rax), %eax
cmpq 0x4(%r14), %rcx
je 0x53ec
cmpl $0x2, %eax
movq 0x20(%rsp), %rbp
jge 0x562e
leaq 0x68(%rsp), %rbx
movq %rbx, %rdi
movq 0x48(%rsp), %rsi
movl $0xc8, %edx
callq 0xa7e7
leaq 0xbebf(%rip), %rdi      # 0x11270
movq %rbx, %rsi
callq 0xa742
testl %eax, %eax
js 0x567c
leaq 0xbea8(%rip), %rax      # 0x11270
movups (%rax), %xmm0
movq 0x48(%rsp), %rax
movups %xmm0, (%rax)
leaq 0xbe7e(%rip), %rax      # 0x11258
cmpl $0x2, (%rax)
jge 0x56b2
movl %r12d, %edi
xorl %esi, %esi
xorl %edx, %edx
jmp 0x5463
cmpl $0x2, %eax
jge 0x56c8
testq %rbx, %rbx
je 0x5408
leaq 0xbe6f(%rip), %rax      # 0x11270
movups (%rax), %xmm0
movups %xmm0, 0x28(%rbx)
movq 0x58(%rsp), %rdi
movl %r12d, %esi
callq 0xa3a1
jmp 0x567c
cmpl $0x0, 0x8(%rsp)
je 0x565c
movq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rsi
movl 0xc(%rsp), %edx
movq %rbp, %rcx
callq 0x3951
testq %rax, %rax
je 0x565c
leaq 0xbe0d(%rip), %rax      # 0x11258
cmpl $0x2, (%rax)
pushq $0x1
popq %r12
jge 0x56e6
pushq $0x2
popq %rdi
movq 0x18(%rsp), %rsi
pushq $0x4
popq %rdx
movq %rbp, %rcx
xorl %r8d, %r8d
callq 0x44e5
jmp 0x567c
leaq 0xbdde(%rip), %rax      # 0x11258
cmpl $0x2, (%rax)
jl 0x5678
pushq $0x2
popq %rdi
leaq 0x7517(%rip), %rsi      # 0xc9a4
jmp 0x54a9
leaq 0xbdc2(%rip), %rax      # 0x11258
cmpl $0x2, (%rax)
jl 0x5678
pushq $0x2
popq %rdi
leaq 0x7455(%rip), %rsi      # 0xc8fe
xorl %eax, %eax
callq 0x23c0
jmp 0x5678
movq 0xbb3c(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x73a5(%rip), %rdi      # 0xc86b
pushq $0x19
popq %rsi
pushq $0x1
popq %rdx
callq 0x2340
jmp 0x567c
pushq $0x2
popq %rdi
leaq 0x7345(%rip), %rsi      # 0xc825
xorl %eax, %eax
callq 0x23c0
jmp 0x5051
pushq $0x2
popq %rdi
leaq 0x74a6(%rip), %rsi      # 0xc99c
xorl %eax, %eax
callq 0x23c0
jmp 0x50f5
movq 0xbaef(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x744f(%rip), %rdi      # 0xc962
pushq $0x22
popq %rsi
pushq $0x1
popq %rdx
callq 0x2340
jmp 0x50aa
leaq 0x4(%r14), %rdi
callq 0xa86d
pushq $0x2
popq %rdi
leaq 0x744f(%rip), %rsi      # 0xc985
movq %rax, %rdx
movl 0x14(%rsp), %ecx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x23c0
leaq 0xbd0a(%rip), %rax      # 0x11258
cmpl $0x2, (%rax)
setge %r12b
jmp 0x50d1
leaq 0x4(%r14), %rdi
callq 0xa86d
pushq $0x2
popq %rdi
leaq 0x72e8(%rip), %rsi      # 0xc855
movq %rax, %rdx
xorl %eax, %eax
callq 0x23c0
jmp 0x52fb
movq 0xba75(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x72f8(%rip), %rdi      # 0xc885
pushq $0x19
popq %rsi
pushq $0x1
popq %rdx
callq 0x2340
jmp 0x52ad
leaq 0x10(%rsp), %rdi
callq 0xa86d
pushq $0x2
popq %rdi
leaq 0x72ee(%rip), %rsi      # 0xc89f
movq %rax, %rdx
movl 0xc(%rsp), %ecx
xorl %eax, %eax
callq 0x23c0
jmp 0x5264
testl %ebx, %ebx
leaq 0x73f1(%rip), %rcx      # 0xc9be
leaq 0x7316(%rip), %rax      # 0xc8ea
cmoveq %rax, %rcx
movq %rcx, 0x38(%rsp)
leaq 0x10(%r14), %rdi
callq 0xa8cb
pushq $0x2
popq %rdi
leaq 0x73be(%rip), %rsi      # 0xc9ae
movq 0x38(%rsp), %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x23c0
jmp 0x513c
movq 0xb9ed(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x73b0(%rip), %rdi      # 0xc9c5
pushq $0x29
popq %rsi
pushq $0x1
popq %rdx
callq 0x2340
movl 0x14(%rsp), %eax
addl $0x2a, %eax
movl %eax, 0x24(%r12)
jmp 0x5678
callq 0xa8cb
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0xa8cb
pushq $0x2
popq %rdi
leaq 0x72c3(%rip), %rsi      # 0xc90d
movq %rbx, %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x23c0
jmp 0x5393
movq 0xb995(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x73da(%rip), %rdi      # 0xca47
pushq $0x21
popq %rsi
pushq $0x1
popq %rdx
callq 0x2340
pushq $0x1
popq %r12
addl %r13d, %r15d
movl %r15d, %r13d
negl %r13d
andl $0x3, %r13d
addl %r15d, %r13d
jmp 0x4fe3
movq 0xb960(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x7373(%rip), %rdi      # 0xca15
pushq $0x1b
popq %rsi
pushq $0x1
popq %rdx
callq 0x2340
jmp 0x521a
pushq $0x2
popq %rdi
leaq 0x7279(%rip), %rsi      # 0xc935
xorl %eax, %eax
callq 0x23c0
jmp 0x53e3
callq 0xa8cb
pushq $0x2
popq %rdi
leaq 0x7214(%rip), %rsi      # 0xc8eb
movq %rax, %rdx
xorl %eax, %eax
callq 0x23c0
jmp 0x53f5
movq 0x18(%rsp), %rdi
callq 0xa86d
pushq $0x2
popq %rdi
leaq 0x7337(%rip), %rsi      # 0xca31
movq %rax, %rdx
xorl %eax, %eax
callq 0x23c0
jmp 0x5458
movq 0xb8e8(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x70f2(%rip), %rdi      # 0xc80c
pushq $0x18
popq %rsi
pushq $0x1
popq %rdx
callq 0x2340
pushq $-0x1
popq %r12
movl 0x4(%rsp), %eax
testl %eax, %eax
je 0x575d
leaq 0xbb48(%rip), %rdi      # 0x11280
xorl %esi, %esi
callq 0x3d24
movq %rax, %rdi
callq 0x3f31
pushq $0x1
popq %rdi
callq 0x9bf9
testl %eax, %eax
jle 0x575d
pushq $0x1
popq %rsi
xorl %edi, %edi
callq 0x3b1d
movl %r12d, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x7082(%rip), %rsi      # 0xc7f8
pushq $0x2
popq %rdi
movl 0x2c(%rsp), %edx
xorl %eax, %eax
callq 0x23c0
jmp 0x4fa9
movq 0xb868(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x714b(%rip), %rdi      # 0xc8e5
pushq $0x5
jmp 0x571c
movq 0xb850(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x7199(%rip), %rdi      # 0xc94b
pushq $0x16
jmp 0x571c
movq 0xb838(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x7071(%rip), %rdi      # 0xc83b
jmp 0x57dd
movq 0xb825(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x70ee(%rip), %rdi      # 0xc8cb
pushq $0x19
jmp 0x571c
movq 0xb80d(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x70c2(%rip), %rdi      # 0xc8b7
pushq $0x13
jmp 0x571c
movq 0xb7f5(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x71e2(%rip), %rdi      # 0xc9ef
pushq $0xe
jmp 0x571c
movq 0xb7dd(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x71d9(%rip), %rdi      # 0xc9fe
jmp 0x57b2