// File: greenpau[P]mnpa/main.cpp
// Function: gen_pkt_payload(unsigned long&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long long&, unsigned int&, unsigned int&)
const char * gen_pkt_payload(size_t& pkt_content_size, std::string& pkt_tag, unsigned long long& pi, unsigned int& psl, unsigned int& psh) {
    size_t ptr_pos = 0;
    char * pkt_content = nullptr;
    // pre-populated fields: 65 chars
    //  * headers:   42 chars, i.e. Ethernet (14 bytes), IP (20 bytes) and UDP (8 bytes)
    //  * timestamp: 20 chars
    //  * separators: 3 chars
    //  * id:         x chars
    //  * tag:        y chars
    std::string pkt_id = std::to_string(pi);
    size_t pkt_header_size = 23 + pkt_id.size() + pkt_tag.size();
    pkt_content_size = pkt_header_size;
    // randomize a packet size
    if (psl != psh) {
        std::uniform_int_distribution<> distr(psl, psh);
        pkt_content_size = distr(eng);
    }
    //printf("pkt_content_size: %zu\n", pkt_content_size);
    //printf("pkt_header_size: %zu\n", pkt_header_size);
    if ((pkt_content_size - pkt_header_size) < 42)  {
        //printf("new pkt_content_size (for header packets only): %zu\n", pkt_content_size);
        pkt_content = new char[pkt_content_size];
    } else {
        pkt_content_size -= 42;
        pkt_content = new char[pkt_content_size];
        memcpy(pkt_content, rand_pkt_payload, pkt_content_size);
        //printf("new pkt_content_size: %zu\n", pkt_content_size);
    }
    // setting the pointer's position to 20, because taking ns timestamp closer to the end of
    // this function improves accuracy of measurements.
    ptr_pos = 20;
    pkt_content[ptr_pos] = ';';
    ptr_pos++;
    pkt_id.copy(pkt_content+ptr_pos, pkt_id.size(), 0);
    ptr_pos += pkt_id.size();
    pkt_content[ptr_pos] = ';';
    ptr_pos++;
    pkt_tag.copy(pkt_content+ptr_pos, pkt_tag.size(), 0);
    ptr_pos += pkt_tag.size();
    pkt_content[ptr_pos] = ';';
    ptr_pos++;
    std::string nts = std::to_string(duration_cast<nanoseconds>(high_resolution_clock::now().time_since_epoch()).count());
    nts.insert(10,".");
    nts.copy(pkt_content, nts.size(), 0);
    return pkt_content;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rsi
leaq -0x58(%rbp), %rdi
callq 0x23d90
leaq -0x58(%rbp), %rdi
callq 0xcf690
addq $0x17, %rax
movq %rax, -0xb8(%rbp)
movq -0x10(%rbp), %rdi
callq 0xcf690
movq %rax, %rcx
movq -0xb8(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rax
movl (%rax), %eax
movq -0x28(%rbp), %rcx
cmpl (%rcx), %eax
je 0x1b4d8
movq -0x20(%rbp), %rax
movl (%rax), %esi
movq -0x28(%rbp), %rax
movl (%rax), %edx
leaq -0x68(%rbp), %rdi
callq 0x23700
jmp 0x1b49d
leaq 0x1431b4(%rip), %rsi    # 0x15e658
leaq -0x68(%rbp), %rdi
callq 0x23730
movl %eax, -0xbc(%rbp)
jmp 0x1b4b5
movl -0xbc(%rbp), %eax
movslq %eax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
jmp 0x1b4d8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x1b75f
movq -0x8(%rbp), %rax
movq (%rax), %rax
subq -0x60(%rbp), %rax
cmpq $0x2a, %rax
jae 0x1b50b
movq -0x8(%rbp), %rax
movq (%rax), %rdi
callq 0x54910
movq %rax, -0xc8(%rbp)
jmp 0x1b4fe
movq -0xc8(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x1b550
movq -0x8(%rbp), %rax
movq (%rax), %rcx
addq $-0x2a, %rcx
movq %rcx, (%rax)
movq -0x8(%rbp), %rax
movq (%rax), %rdi
callq 0x54910
movq %rax, -0xd0(%rbp)
jmp 0x1b52e
movq -0xd0(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
movq -0x8(%rbp), %rax
movq (%rax), %rdx
leaq 0x1415b5(%rip), %rsi    # 0x15cb00
callq 0x16890
movq $0x14, -0x30(%rbp)
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
movb $0x3b, (%rax,%rcx)
movq -0x30(%rbp), %rax
incq %rax
movq %rax, -0x30(%rbp)
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0xd8(%rbp)
leaq -0x58(%rbp), %rdi
movq %rdi, -0xe0(%rbp)
callq 0xcf690
movq -0xe0(%rbp), %rdi
movq -0xd8(%rbp), %rsi
movq %rax, %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0xd0d20
jmp 0x1b5ad
leaq -0x58(%rbp), %rdi
callq 0xcf690
movq %rax, %rcx
movq -0x30(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
movb $0x3b, (%rax,%rcx)
movq -0x30(%rbp), %rax
incq %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0xf0(%rbp)
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0xe8(%rbp)
callq 0xcf690
movq -0xf0(%rbp), %rdi
movq -0xe8(%rbp), %rsi
movq %rax, %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0xd0d20
jmp 0x1b619
movq -0x10(%rbp), %rdi
callq 0xcf690
movq %rax, %rcx
movq -0x30(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
movb $0x3b, (%rax,%rcx)
movq -0x30(%rbp), %rax
incq %rax
movq %rax, -0x30(%rbp)
callq 0x5d160
movq %rax, -0xb0(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x23fd0
movq %rax, -0xf8(%rbp)
jmp 0x1b668
movq -0xf8(%rbp), %rax
movq %rax, -0xa8(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x23fa0
movq %rax, -0x100(%rbp)
jmp 0x1b68b
movq -0x100(%rbp), %rax
movq %rax, -0xa0(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x23ff0
movq %rax, -0x108(%rbp)
jmp 0x1b6ae
movq -0x108(%rbp), %rsi
leaq -0x98(%rbp), %rdi
callq 0x23e70
jmp 0x1b6c3
leaq 0xe777a(%rip), %rdx     # 0x102e44
leaq -0x98(%rbp), %rdi
movl $0xa, %esi
callq 0xd05d0
jmp 0x1b6dd
movq -0x38(%rbp), %rax
movq %rax, -0x110(%rbp)
leaq -0x98(%rbp), %rdi
movq %rdi, -0x118(%rbp)
callq 0xcf690
movq -0x118(%rbp), %rdi
movq -0x110(%rbp), %rsi
movq %rax, %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0xd0d20
jmp 0x1b717
movq -0x38(%rbp), %rax
movq %rax, -0x120(%rbp)
leaq -0x98(%rbp), %rdi
callq 0xcf470
leaq -0x58(%rbp), %rdi
callq 0xcf470
movq -0x120(%rbp), %rax
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x98(%rbp), %rdi
callq 0xcf470
leaq -0x58(%rbp), %rdi
callq 0xcf470
movq -0x70(%rbp), %rdi
callq 0xfeff0
nopw %cs:(%rax,%rax)