// File: /workspace/github_c_makefile_star2_O1/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, %r12
movl %ecx, 0x44(%rsp)
movq %rdx, %rbp
movl %esi, 0x2c(%rsp)
movq %rdi, 0x60(%rsp)
leaq 0xd288(%rip), %rax      # 0x13258
cmpl $0x3, (%rax)
jge 0x673f
leaq 0x10(%r12), %rax
movq %rax, 0x58(%rsp)
leaq 0x30(%r12), %rax
movq %rax, 0x50(%rsp)
movl $0x2a, 0x10(%rsp)
movl $0x0, 0x1c(%rsp)
xorl %r13d, %r13d
movl $0x0, 0x4(%rsp)
movq %r12, 0x8(%rsp)
movq %rbp, 0x20(%rsp)
movl 0x2c(%rsp), %eax
subl %r13d, %eax
jle 0x66f2
cmpl $0x3, %eax
jle 0x63aa
movslq %r13d, %rbx
addq 0x60(%rsp), %rbx
movzwl 0x2(%rbx), %ebp
rolw $0x8, %bp
movzwl %bp, %r14d
leal 0x4(%r14), %r15d
cmpl %r15d, %eax
jl 0x6469
movzwl (%rbx), %eax
rolw $0x8, %ax
movzwl %ax, %edx
leal -0x1(%rdx), %eax
cmpl $0x4, %eax
ja 0x637f
leaq 0x776a(%rip), %rcx      # 0xd7d0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0xd1e2(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x6573
movq 0x20(%rsp), %rbp
movq %rbp, %rdi
xorl %esi, %esi
callq 0x5520
leaq 0xd20f(%rip), %rax      # 0x132a4
cmpl $0x0, (%rax)
jle 0x663a
leaq 0xe7eb(%rip), %rbx      # 0x14890
xorl %r14d, %r14d
movq %rbx, %rdi
xorl %esi, %esi
movq %rbp, %rdx
xorl %ecx, %ecx
callq 0x557b
incq %r14
leaq 0xd1e3(%rip), %rax      # 0x132a4
movslq (%rax), %rax
addq $0x70, %rbx
cmpq %rax, %r14
jl 0x60a8
jmp 0x663a
cmpw $0x13, %bp
jbe 0x6553
cmpl $0x0, 0x4(%rsp)
je 0x6596
movl 0x8(%rbx), %eax
movl 0xc(%rbx), %ebp
bswapl %eax
movl %eax, 0x18(%rsp)
bswapl %ebp
leaq 0xd15c(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x65a0
movl %ebp, 0x40(%rsp)
movl 0x4(%rbx), %eax
xorl %ebp, %ebp
leaq 0xd16b(%rip), %rcx      # 0x13280
cmpl (%rcx), %eax
setne 0x38(%rsp)
jne 0x612e
leaq 0xd133(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x658c
leaq 0x4(%rbx), %rdi
movq %rdi, 0x30(%rsp)
xorl %esi, %esi
callq 0x4b4e
movq %rax, %r12
testq %rax, %rax
je 0x6166
movl 0x18(%rsp), %eax
cmpl 0x24(%r12), %eax
js 0x6515
jne 0x6166
movq 0x10(%rbx), %rax
cmpq 0x1c(%r12), %rax
je 0x6534
addl $-0x14, %r14d
leaq 0xd0e7(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x666a
movb 0x38(%rsp), %al
movb %al, %bpl
testl %ebp, %ebp
je 0x6659
testl %r14d, %r14d
movq 0x20(%rsp), %rbp
je 0x64b1
leaq 0x18(%rbx), %rsi
leaq 0x68(%rsp), %rdi
movq %rsi, 0x38(%rsp)
movl %r14d, %edx
callq 0x4fd2
movq 0x68(%rsp), %rax
cmpq 0x10(%rbx), %rax
jne 0x6693
testq %r12, %r12
jne 0x61d3
movq 0x30(%rsp), %rdi
movl $0x1, %esi
callq 0x4b4e
movq %rax, %r12
testq %r12, %r12
je 0x669a
movq 0x10(%r12), %rdi
movslq %r14d, %rsi
movq %rsi, 0x30(%rsp)
callq 0x2280
testq %rax, %rax
je 0x66ab
movq %rax, %rbp
movq 0x8(%rsp), %rax
movq %rax, (%r12)
movl 0x18(%rsp), %eax
movl %eax, 0x24(%r12)
leaq 0x28(%r12), %rdi
movl 0x40(%rsp), %edx
incl %edx
leaq 0xd052(%rip), %rsi      # 0x13270
callq 0xbae6
movq %rbp, 0x10(%r12)
movq %rbp, %rdi
movq 0x38(%rsp), %rsi
movq 0x30(%rsp), %rdx
callq 0x2210
movl %r14d, 0x18(%r12)
movq 0x10(%rbx), %rax
movq %rax, 0x1c(%r12)
movq %r12, %rdi
callq 0x675b
testl %eax, %eax
js 0x66cf
callq 0x4730
movl $0x1, 0x1c(%rsp)
movl $0xb, %ebx
jmp 0x66b5
cmpw $0x7, %bp
jbe 0x6562
cmpl $0x0, 0x4(%rsp)
jne 0x65cb
movl 0x4(%rbx), %eax
movl %eax, 0x14(%rsp)
movl 0x8(%rbx), %eax
bswapl %eax
movl %eax, 0x10(%rsp)
leaq 0xcfbd(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x65f8
movl 0x14(%rsp), %eax
leaq 0xcfd1(%rip), %rcx      # 0x13280
cmpl (%rcx), %eax
je 0x6621
movl $0x1, 0x4(%rsp)
movl $0xb, %ebx
movb $0x1, %bpl
cmpl $0x0, 0x44(%rsp)
je 0x6635
movq %r12, %rdi
leaq 0x14(%rsp), %rsi
movl 0x10(%rsp), %edx
movq 0x20(%rsp), %rcx
callq 0x47c6
testq %rax, %rax
je 0x6635
leaq 0xcf78(%rip), %rcx      # 0x13270
movups (%rcx), %xmm0
movups %xmm0, 0x28(%rax)
jmp 0x6635
cmpl $0x0, 0x4(%rsp)
je 0x63b4
movq %r12, %rdi
leaq 0x14(%rsp), %rsi
movl 0x10(%rsp), %edx
xorl %ecx, %ecx
callq 0x47c6
movq %rax, %r14
jmp 0x63b7
cmpw $0x3, %bp
jbe 0x657d
leaq 0xcf1d(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x65eb
addq $0x4, %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x4b4e
movl $0xb, %ebx
testq %rax, %rax
je 0x6370
movq %rax, %rdi
movl $0x1, %esi
movq 0x20(%rsp), %rdx
xorl %ecx, %ecx
callq 0x557b
cmpw $0x3, %bp
ja 0x663a
jmp 0x664c
leaq 0xced2(%rip), %rax      # 0x13258
cmpl $0x3, (%rax)
jl 0x663a
movl $0x2, %edi
leaq 0x7915(%rip), %rsi      # 0xdcb0
movl %r14d, %ecx
xorl %eax, %eax
callq 0x319e
jmp 0x663a
callq 0x2a05
jmp 0x646e
xorl %r14d, %r14d
cmpw $0x7, %bp
jbe 0x656c
leaq 0x48(%rsp), %rdi
callq 0x501f
testl %eax, %eax
js 0x65dd
leaq 0x4(%rbx), %rdi
movq 0x48(%rsp), %rcx
leaq 0xce75(%rip), %rax      # 0x13258
movl (%rax), %eax
cmpq 0x4(%rbx), %rcx
je 0x6478
cmpl $0x2, %eax
movq 0x58(%rsp), %rbx
jge 0x667a
leaq 0x68(%rsp), %rbp
movq %rbp, %rdi
movq %rbx, %rsi
movl $0xc8, %edx
callq 0xbae6
leaq 0xce57(%rip), %r14      # 0x13270
movq %r14, %rdi
movq %rbp, %rsi
callq 0xba38
movq %rbx, %rcx
movl $0xb, %ebx
movb $0x1, %bpl
testl %eax, %eax
js 0x6635
movups (%r14), %xmm0
movups %xmm0, (%rcx)
leaq 0xce13(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jge 0x66a1
movl $0x1, %edi
xorl %esi, %esi
xorl %edx, %edx
movq 0x20(%rsp), %rcx
xorl %r8d, %r8d
callq 0x5300
jmp 0x6635
callq 0x29e3
movl $0x6, %ebx
jmp 0x664c
cmpl $0x2, %eax
jge 0x66c5
testq %r14, %r14
leaq 0xcde5(%rip), %rax      # 0x13270
je 0x6495
movups (%rax), %xmm0
movups %xmm0, 0x28(%r14)
movq 0x50(%rsp), %rdi
movl $0x1, %esi
callq 0xb630
movl $0xb, %ebx
movb $0x1, %bpl
jmp 0x6635
cmpl $0x0, 0x4(%rsp)
movq 0x8(%rsp), %r12
je 0x6689
movq %r12, %rdi
leaq 0x14(%rsp), %rsi
movl 0x10(%rsp), %edx
movq %rbp, %rcx
callq 0x47c6
testq %rax, %rax
je 0x6689
leaq 0xcd73(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
movq 0x30(%rsp), %rbx
jge 0x66d9
movl $0x2, %edi
movq %rbx, %rsi
movl $0x4, %edx
movq %rbp, %rcx
xorl %r8d, %r8d
callq 0x5300
movl $0xb, %ebx
jmp 0x66ba
movl $0xb, %ebx
leaq 0xcd37(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jl 0x66b5
callq 0x26ed
jmp 0x66b5
movl $0xb, %ebx
leaq 0xcd18(%rip), %rax      # 0x13258
cmpl $0x2, (%rax)
jl 0x66b5
callq 0x2704
jmp 0x66b5
callq 0x284f
movl $0x6, %ebx
jmp 0x66ba
callq 0x2965
jmp 0x64a4
callq 0x28ff
jmp 0x65e2
callq 0x29cc
jmp 0x607f
callq 0x2987
movl $0x6, %ebx
jmp 0x6370
callq 0x26d6
jmp 0x612e
callq 0x26b4
jmp 0x60e7
leaq 0x4(%rbx), %rdi
callq 0xbc25
movl $0x2, %edi
leaq 0x7418(%rip), %rsi      # 0xd9cd
movq %rax, %rdx
movl 0x18(%rsp), %ecx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x319e
jmp 0x6105
callq 0x2921
movl $0x1, 0x4(%rsp)
jmp 0x64a4
callq 0x28dd
movl $0x6, %ebx
xorl %ebp, %ebp
jmp 0x6635
movq %rbx, %rdi
callq 0x29a9
jmp 0x6344
leaq 0x14(%rsp), %rdi
callq 0xbc25
movl $0x2, %edi
leaq 0x72d9(%rip), %rsi      # 0xd8e7
movq %rax, %rdx
movl 0x10(%rsp), %ecx
xorl %eax, %eax
callq 0x319e
jmp 0x62a4
callq 0x2943
xorl %ebp, %ebp
movl $0x6, %ebx
movl $0x0, 0x4(%rsp)
testb %bpl, %bpl
je 0x664c
addl %r13d, %r15d
movl %r15d, %r13d
negl %r13d
andl $0x3, %r13d
addl %r15d, %r13d
xorl %ebx, %ebx
testl %ebx, %ebx
je 0x6012
jmp 0x66e6
movl 0x18(%rsp), %edi
movq %r12, %rsi
callq 0x281e
jmp 0x6265
movl %r14d, %edi
movq %rbx, %rsi
callq 0x271b
jmp 0x617a
leaq 0x48(%rsp), %rsi
callq 0x2871
jmp 0x63fd
callq 0x27fc
jmp 0x650b
callq 0x2755
jmp 0x66b0
callq 0x27bb
jmp 0x66b0
callq 0x28a7
jmp 0x644e
callq 0x2799
movl $0x6, %ebx
movq 0x8(%rsp), %r12
cmpl $0xb, %ebx
je 0x663a
jmp 0x664c
callq 0x28be
jmp 0x6481
callq 0x2777
jmp 0x625d
movq %rbx, %rdi
callq 0x27dd
jmp 0x64f3
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
cmpl $0x6, %ebx
je 0x66f7
jmp 0x672e
movl $0x1, %ebp
cmpl $0x0, 0x1c(%rsp)
je 0x672e
leaq 0xcb7b(%rip), %rdi      # 0x13280
xorl %esi, %esi
callq 0x4b4e
movq %rax, %rdi
callq 0x4d60
movl $0x1, %edi
callq 0xae8b
testl %eax, %eax
jle 0x672e
xorl %edi, %edi
movl $0x1, %esi
callq 0x492a
movl %ebp, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x70fa(%rip), %rsi      # 0xd840
movl $0x2, %edi
movl 0x2c(%rsp), %edx
xorl %eax, %eax
callq 0x319e
jmp 0x5fd9