// File: /workspace/github_c_makefile_star2_O3/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, 0x30(%rsp)
movl %ecx, 0x38(%rsp)
movq %rdx, %r12
movl %esi, %ecx
movq %rdi, 0x60(%rsp)
leaq 0xd4dc(%rip), %rax      # 0x13258
cmpl $0x3, (%rax)
movl %esi, 0x4(%rsp)
jge 0x6421
testl %ecx, %ecx
jle 0x640b
movq 0x30(%rsp), %rax
leaq 0x10(%rax), %rdx
movq %rdx, 0x40(%rsp)
addq $0x30, %rax
movq %rax, 0x50(%rsp)
movl $0x2a, 0x10(%rsp)
movl $0x0, 0xc(%rsp)
xorl %r14d, %r14d
movl $0x0, 0x8(%rsp)
movq %r12, 0x28(%rsp)
movl %ecx, %eax
subl %r14d, %eax
cmpl $0x3, %eax
jle 0x643f
movslq %r14d, %r13
addq 0x60(%rsp), %r13
movzwl 0x2(%r13), %r15d
rolw $0x8, %r15w
movzwl %r15w, %ebx
leal 0x4(%rbx), %ebp
cmpl %ebp, %eax
jb 0x6446
movzwl (%r13), %eax
rolw $0x8, %ax
movzwl %ax, %edx
leal -0x1(%rdx), %eax
cmpl $0x4, %eax
ja 0x60f8
leaq 0x79ba(%rip), %rdx      # 0xd7d0
movslq (%rdx,%rax,4), %rax
addq %rdx, %rax
jmpq *%rax
leaq 0xd432(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x629b
movq %r12, %rdi
xorl %esi, %esi
callq 0x5304
leaq 0xd464(%rip), %r13      # 0x132a4
cmpl $0x0, (%r13)
jle 0x623e
leaq 0xea3e(%rip), %rbx      # 0x14890
xorl %r15d, %r15d
movq %rbx, %rdi
xorl %esi, %esi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x535f
incq %r15
movslq (%r13), %rax
addq $0x70, %rbx
cmpq %rax, %r15
jl 0x5e55
jmp 0x623e
cmpw $0x13, %r15w
jbe 0x6463
cmpl $0x0, 0xc(%rsp)
je 0x62a5
movl 0x8(%r13), %eax
movl 0xc(%r13), %r15d
bswapl %eax
movl %eax, 0x24(%rsp)
bswapl %r15d
leaq 0x4(%r13), %rdi
leaq 0xd3ad(%rip), %rax      # 0x13258
cmpl $0x1, (%rax)
movl %r15d, 0x3c(%rsp)
jg 0x62af
movl (%rdi), %eax
leaq 0xd3be(%rip), %rcx      # 0x13280
cmpl (%rcx), %eax
sete %r12b
movq %rdi, 0x18(%rsp)
xorl %esi, %esi
callq 0x49a3
movq %rax, %r15
testq %rax, %rax
movl 0x4(%rsp), %ecx
je 0x5efe
movl 0x24(%rsp), %eax
cmpl 0x24(%r15), %eax
js 0x6260
jne 0x5efe
movq 0x10(%r13), %rax
cmpq 0x1c(%r15), %rax
je 0x627a
addl $-0x14, %ebx
leaq 0xd350(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x6353
testb %r12b, %r12b
jne 0x6362
testl %ebx, %ebx
movq 0x28(%rsp), %r12
je 0x61ea
leaq 0x18(%r13), %r12
leaq 0x68(%rsp), %rdi
movq %r12, %rsi
movl %ebx, %edx
callq 0x4e2c
movq 0x68(%rsp), %rax
cmpq 0x10(%r13), %rax
jne 0x6478
testq %r15, %r15
jne 0x5f69
movq 0x18(%rsp), %rdi
movl $0x1, %esi
callq 0x49a3
movq %rax, %r15
testq %rax, %rax
je 0x6486
movq %r12, 0x18(%rsp)
movq 0x10(%r15), %rdi
movslq %ebx, %rsi
movq %rsi, 0x58(%rsp)
callq 0x2280
testq %rax, %rax
je 0x647f
movq %rax, %r12
movq 0x30(%rsp), %rax
movq %rax, (%r15)
movl 0x24(%rsp), %eax
movl %eax, 0x24(%r15)
leaq 0x28(%r15), %rdi
movl 0x3c(%rsp), %edx
incl %edx
leaq 0xd2c4(%rip), %rsi      # 0x13270
callq 0xb514
movq %r12, 0x10(%r15)
movq %r12, %rdi
movq 0x18(%rsp), %rsi
movq 0x58(%rsp), %rdx
callq 0x2210
movl %ebx, 0x18(%r15)
movq 0x10(%r13), %rax
movq %rax, 0x1c(%r15)
movq %r15, %rdi
callq 0x648d
testl %eax, %eax
js 0x6395
callq 0x45b0
movq 0x28(%rsp), %r12
movl $0x1, 0x8(%rsp)
jmp 0x623e
cmpw $0x7, %r15w
jbe 0x6294
cmpl $0x0, 0xc(%rsp)
jne 0x6310
movl 0x4(%r13), %eax
movl %eax, 0x14(%rsp)
movl 0x8(%r13), %eax
bswapl %eax
movl %eax, 0x10(%rsp)
leaq 0xd22f(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x6326
movl 0x14(%rsp), %eax
leaq 0xd243(%rip), %rdx      # 0x13280
cmpl (%rdx), %eax
je 0x6471
movl $0x1, 0xc(%rsp)
cmpl $0x0, 0x38(%rsp)
je 0x6242
movq 0x30(%rsp), %rdi
leaq 0x14(%rsp), %rsi
movl 0x10(%rsp), %edx
movq %r12, %rcx
callq 0x4646
testq %rax, %rax
je 0x623e
leaq 0xd1f2(%rip), %rcx      # 0x13270
movups (%rcx), %xmm0
movups %xmm0, 0x28(%rax)
jmp 0x623e
cmpl $0x0, 0xc(%rsp)
je 0x6122
movq 0x30(%rsp), %rdi
leaq 0x14(%rsp), %rsi
movl 0x10(%rsp), %edx
xorl %ecx, %ecx
callq 0x4646
movq %rax, %rbx
jmp 0x6124
cmpw $0x4, %r15w
jb 0x6455
leaq 0xd197(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x6303
addq $0x4, %r13
movq %r13, %rdi
xorl %esi, %esi
callq 0x49a3
testq %rax, %rax
je 0x623e
movq %rax, %rdi
movl $0x1, %esi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x535f
jmp 0x623e
leaq 0xd159(%rip), %rax      # 0x13258
cmpl $0x3, (%rax)
jl 0x6242
movl $0x2, %edi
leaq 0x7b7c(%rip), %rsi      # 0xdc90
movl %ebx, %ecx
xorl %eax, %eax
callq 0x30a8
jmp 0x623e
xorl %ebx, %ebx
cmpw $0x7, %r15w
jbe 0x645c
leaq 0x48(%rsp), %rdi
callq 0x4e79
testl %eax, %eax
js 0x646a
leaq 0x4(%r13), %rdi
movq 0x48(%rsp), %rcx
leaq 0xd107(%rip), %rax      # 0x13258
movl (%rax), %eax
cmpq 0x4(%r13), %rcx
je 0x61bd
cmpl $0x2, %eax
jge 0x637c
leaq 0x68(%rsp), %rbx
movq %rbx, %rdi
movq 0x40(%rsp), %rsi
movl $0xc8, %edx
callq 0xb514
leaq 0xd0f0(%rip), %rdi      # 0x13270
movq %rbx, %rsi
callq 0xb464
testl %eax, %eax
js 0x623e
leaq 0xd0d9(%rip), %rax      # 0x13270
movups (%rax), %xmm0
movq 0x40(%rsp), %rax
movups %xmm0, (%rax)
leaq 0xd0af(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x639f
movl $0x1, %edi
xorl %esi, %esi
xorl %edx, %edx
jmp 0x6233
cmpl $0x2, %eax
jge 0x63a9
testq %rbx, %rbx
je 0x61d9
leaq 0xd09e(%rip), %rax      # 0x13270
movups (%rax), %xmm0
movups %xmm0, 0x28(%rbx)
movq 0x50(%rsp), %rdi
movl $0x1, %esi
callq 0xb05f
jmp 0x623e
cmpl $0x0, 0xc(%rsp)
je 0x638b
movq 0x30(%rsp), %rdi
leaq 0x14(%rsp), %rsi
movl 0x10(%rsp), %edx
movq %r12, %rcx
callq 0x4646
testq %rax, %rax
je 0x638b
leaq 0xd03d(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x63b3
movl $0x2, %edi
movq 0x18(%rsp), %rsi
movl $0x4, %edx
movq %r12, %rcx
xorl %r8d, %r8d
callq 0x5106
movl 0x4(%rsp), %ecx
addl %r14d, %ebp
movl %ebp, %r14d
negl %r14d
andl $0x3, %r14d
addl %ebp, %r14d
cmpl %ecx, %r14d
jl 0x5dc8
jmp 0x63cc
leaq 0xcff1(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jl 0x6372
callq 0x26cb
jmp 0x636e
leaq 0xcfd7(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jl 0x6372
callq 0x26e2
jmp 0x636e
callq 0x2943
jmp 0x623e
callq 0x29aa
jmp 0x5e2f
callq 0x2692
jmp 0x5e8f
movq %rdi, 0x18(%rsp)
callq 0xb657
movl $0x2, %edi
leaq 0x76e8(%rip), %rsi      # 0xd9ad
movq %rax, %rdx
movl 0x24(%rsp), %ecx
movl %r15d, %r8d
xorl %eax, %eax
callq 0x30a8
movl 0x4(%r13), %eax
leaq 0xcf9f(%rip), %rcx      # 0x13280
cmpl (%rcx), %eax
sete %r12b
jne 0x62f9
leaq 0xcf68(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x63c2
movq 0x18(%rsp), %rdi
jmp 0x5ec8
movq %r13, %rdi
callq 0x2987
jmp 0x60ca
callq 0x28ff
movl 0x4(%rsp), %ecx
movl $0x1, 0xc(%rsp)
jmp 0x6242
leaq 0x14(%rsp), %rdi
callq 0xb657
movl $0x2, %edi
leaq 0x758b(%rip), %rsi      # 0xd8c7
movq %rax, %rdx
movl 0x10(%rsp), %ecx
xorl %eax, %eax
callq 0x30a8
movl 0x4(%rsp), %ecx
jmp 0x6032
movl %ebx, %edi
movq %r13, %rsi
callq 0x26f9
jmp 0x5f11
movl 0x24(%rsp), %edi
movq %r15, %rsi
callq 0x27fc
movl 0x4(%rsp), %ecx
movq 0x28(%rsp), %r12
jmp 0x6242
leaq 0x48(%rsp), %rsi
callq 0x284f
jmp 0x6162
callq 0x27da
jmp 0x623e
callq 0x2755
jmp 0x5fe8
callq 0x2885
jmp 0x61b2
callq 0x289c
jmp 0x61c6
movq 0x18(%rsp), %rdi
callq 0x27bb
jmp 0x6224
callq 0x26b4
jmp 0x62f9
movl $0x1, %ebx
movl 0x8(%rsp), %eax
testl %eax, %eax
je 0x6410
leaq 0xcea0(%rip), %rdi      # 0x13280
xorl %esi, %esi
callq 0x49a3
movq %rax, %rdi
callq 0x4bb6
movl $0x1, %edi
callq 0xa8a6
testl %eax, %eax
jle 0x6410
xorl %edi, %edi
movl $0x1, %esi
callq 0x47aa
jmp 0x6410
movl $0x1, %ebx
movl %ebx, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x73f8(%rip), %rsi      # 0xd820
movl $0x2, %edi
movl %ecx, %edx
xorl %eax, %eax
callq 0x30a8
movl 0x4(%rsp), %ecx
jmp 0x5d89
callq 0x29e3
jmp 0x644b
callq 0x29c1
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0x63d1
callq 0x2965
jmp 0x644b
callq 0x28dd
jmp 0x644b
callq 0x282d
jmp 0x644b
callq 0x28bb
jmp 0x644b
callq 0x2921
jmp 0x644b
callq 0x2733
jmp 0x644b
callq 0x2777
jmp 0x644b
callq 0x2799
jmp 0x644b