decompiled_code:
__int64 __fastcall rrep_process(__int64 a1, unsigned int a2, unsigned int a3, unsigned int a4, __int64 a5, unsigned int a6)
{
unsigned int v7; // er14
__int64 v9; // rbx
__int64 result; // rax
unsigned int v11; // er13
const char *v12; // r15
__int64 v13; // r13
const char *v14; // rax
const char *v15; // r9
unsigned __int8 *v16; // r13
int v17; // er15
__int64 v18; // rdx
__int64 v19; // r8
__int64 v20; // rax
__int64 v21; // r10
__int64 v22; // rcx
__int64 v23; // r9
__int16 v24; // ax
unsigned int v25; // er15
__int64 v26; // r13
__int64 v27; // rdi
__int64 v28; // rsi
const char *v29; // rax
const char *v30; // rbx
const char *v31; // rax
int v32; // eax
__int64 v33; // r9
__int64 v34; // rcx
int v35; // eax
__int64 v36; // rcx
__int64 v37; // r9
__int64 v38; // rax
const char *v39; // rax
__int64 v40; // [rsp-10h] [rbp-88h]
__int64 v41; // [rsp-8h] [rbp-80h]
unsigned int v43; // [rsp+10h] [rbp-68h]
unsigned int v44; // [rsp+14h] [rbp-64h]
unsigned int v45; // [rsp+18h] [rbp-60h]
__int64 v46; // [rsp+18h] [rbp-60h]
unsigned __int8 v47; // [rsp+18h] [rbp-60h]
unsigned int v48; // [rsp+24h] [rbp-54h]
unsigned int v49; // [rsp+24h] [rbp-54h]
unsigned __int8 v50; // [rsp+28h] [rbp-50h]
__int64 v51; // [rsp+28h] [rbp-50h]
unsigned int v52; // [rsp+30h] [rbp-48h]
char v53; // [rsp+30h] [rbp-48h]
unsigned int v54; // [rsp+34h] [rbp-44h]
int v55; // [rsp+38h] [rbp-40h]
unsigned int v56; // [rsp+3Ch] [rbp-3Ch]

if ( (int)a2 <= 19 )
{
v30 = (const char *)ip_to_str(a4);
v31 = (const char *)ip_to_str(a3);
return alog(4LL, 0LL, "rrep_process", "IP data field too short (%u bytes) from %s to %s", a2, v31, v30);
}
v7 = *(_DWORD *)(a1 + 4);
v9 = a6;
result = 11LL * (unsigned int)ifindex2devindex(a6);
if ( v7 != this_host[result + 20] )
{
v11 = *(_DWORD *)(a1 + 12);
v45 = *(_DWORD *)(a1 + 8);
v43 = v11;
v48 = *(_DWORD *)(a1 + 16);
v50 = *(_BYTE *)(a1 + 3);
v12 = (const char *)ip_to_str(v7);
v13 = ip_to_str(v11);
v14 = (const char *)ip_to_str(a3);
v15 = (const char *)v13;
v16 = (unsigned __int8 *)(a1 + 20);
alog(7LL, 0LL, "rrep_process", "from %s about %s->%s", v14, v15, v12);
log_pkt_fields(a1);
v55 = 0;
v44 = 0;
if ( a2 != 20 )
{
v17 = 0;
do
{
v19 = *v16;
if ( (_BYTE)v19 == 1 )
{
alog(6LL, 0LL, "rrep_process", "RREP include EXTENSION");
}
else if ( (_BYTE)v19 == 4 && v16[1] == 4 )
{
v56 = *(_DWORD *)(v16 + 2);
v29 = (const char *)ip_to_str(v56);
alog(7LL, 0LL, "rrep_process", "RREP_INET_DEST_EXT: <%s>", v29);
v55 = 1;
v44 = 16;
}
else
{
alog(4LL, 0LL, "rrep_process", "Unknown or bad extension %d", v19);
}
v18 = v16[1];
v17 += v18 + 2;
v16 += v18 + 2;
}
while ( a2 - v17 > 0x14 );
}
v52 = _bswap_32(v45);
v54 = _bswap_32(v48);
v49 = v50 + 1;
v46 = rt_table_find(v7);
v20 = rt_table_find(v43);
v21 = v46;
v22 = v52;
v51 = v20;
if ( !v46 )
{
v25 = (unsigned __int8)v49;
v26 = rt_table_insert(v7, a3, (unsigned __int8)v49, v52, v54, 1LL, v44, v9);
v53 = 0;
v47 = 0;
goto LABEL_16;
}
v23 = *(unsigned int *)(v46 + 20);
v47 = *(_BYTE *)(v46 + 32);
if ( !(_DWORD)v23 || (int)v23 < (int)v52 )
{
v24 = *(_WORD *)(v21 + 34);
LABEL_15:
v25 = (unsigned __int8)v49;
v53 = v24;
v26 = rt_table_update(v21, a3, (unsigned __int8)v49, v22, v54, 1LL, (unsigned __int16)(v44 | v24));
LABEL_16:
if ( (*(_BYTE *)(a1 + 1) & 0x40) != 0 )
{
rrep_ack_create();
v35 = ifindex2devindex(*(_DWORD *)(v26 + 24));
aodv_socket_send(v37, *(unsigned int *)(v26 + 28), 50LL, v36, &this_host[11 * v35 + 12]);
*(_BYTE *)(a1 + 1) &= 0xBFu;
}
v27 = (unsigned int)v9;
v28 = v43;
result = 11LL * (unsigned int)ifindex2devindex(v9);
if ( v43 == this_host[result + 20] )
{
if ( v55 )
{
v38 = rt_table_find(v56);
if ( v38 )
{
if ( *(_BYTE *)(v38 + 36) && *(unsigned __int8 *)(v38 + 32) <= v49 )
{
v39 = (const char *)ip_to_str(v56);
v28 = 0LL;
v27 = 7LL;
result = alog(7LL, 0LL, "rrep_process", "INET Response, but no update %s", v39);
}
else
{
result = rt_table_update(v38, v7, v25, 0LL, v54, 1LL, *(_WORD *)(v38 + 34) | 8u);
v28 = v40;
v27 = v41;
}
}
else
{
v28 = v7;
v27 = v56;
result = rt_table_insert(v56, v7, v25, 0LL, v54, 1LL, 8LL, v9);
}
}
if ( (v53 & 2) != 0 )
{
result = v47;
if ( *(_BYTE *)(v26 + 32) > v47 )
{
v28 = *(unsigned int *)(v26 + 16);
v27 = 1LL;
result = rerr_create(1LL, v28, *(unsigned int *)(v26 + 20));
if ( *(_DWORD *)(v26 + 232) )
{
v28 = 0xFFFFFFFFLL;
v32 = ifindex2devindex(*(_DWORD *)(v26 + 24));
v27 = v33;
result = aodv_socket_send(
v33,
0xFFFFFFFFLL,
8 * (unsigned int)*(unsigned __int8 *)(v33 + 3) + 4,
v34,
&this_host[11 * v32 + 12]);
}
}
}
}
else if ( v51 && *(_BYTE *)(v51 + 36) == 1 )
{
v28 = a2;
v27 = a1;
result = rrep_forward(a1, a2, v51, v26);
}
else
{
v28 = 0LL;
v27 = 7LL;
result = alog(7LL, 0LL, "rrep_process", "Could not forward RREP - NO ROUTE!!!");
}
if ( !llfeedback )
{
result = optimized_hellos;
if ( optimized_hellos )
result = hello_start(v27, v28);
}
return result;
}
if ( (_DWORD)v23 == v52 )
{
v24 = *(_WORD *)(v21 + 34);
if ( !*(_BYTE *)(v21 + 36) || (v24 & 1) != 0 || v47 > v49 )
goto LABEL_15;
}
result = v47;
if ( v47 > 1u )
result = alog(7LL, 0LL, "rrep_process", "Dropping RREP, fwd_rt->hcnt=%d fwd_rt->seqno=%ld", v47, v23);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, unsigned int a2, unsigned int a3, unsigned int a4, __int64 a5, unsigned int a6)
{
unsigned int v7; // er14
__int64 v9; // rbx
__int64 result; // rax
unsigned int v11; // er13
const char *v12; // r15
__int64 v13; // r13
const char *v14; // rax
const char *v15; // r9
unsigned __int8 *v16; // r13
int v17; // er15
__int64 v18; // rdx
__int64 v19; // r8
__int64 v20; // rax
__int64 v21; // r10
__int64 v22; // rcx
__int64 v23; // r9
__int16 v24; // ax
unsigned int v25; // er15
__int64 v26; // r13
__int64 v27; // rdi
__int64 v28; // rsi
const char *v29; // rax
const char *v30; // rbx
const char *v31; // rax
int v32; // eax
__int64 v33; // r9
__int64 v34; // rcx
int v35; // eax
__int64 v36; // rcx
__int64 v37; // r9
__int64 v38; // rax
const char *v39; // rax
__int64 v40; // [rsp-10h] [rbp-88h]
__int64 v41; // [rsp-8h] [rbp-80h]
unsigned int v43; // [rsp+10h] [rbp-68h]
unsigned int v44; // [rsp+14h] [rbp-64h]
unsigned int v45; // [rsp+18h] [rbp-60h]
__int64 v46; // [rsp+18h] [rbp-60h]
unsigned __int8 v47; // [rsp+18h] [rbp-60h]
unsigned int v48; // [rsp+24h] [rbp-54h]
unsigned int v49; // [rsp+24h] [rbp-54h]
unsigned __int8 v50; // [rsp+28h] [rbp-50h]
__int64 v51; // [rsp+28h] [rbp-50h]
unsigned int v52; // [rsp+30h] [rbp-48h]
char v53; // [rsp+30h] [rbp-48h]
unsigned int v54; // [rsp+34h] [rbp-44h]
int v55; // [rsp+38h] [rbp-40h]
unsigned int v56; // [rsp+3Ch] [rbp-3Ch]

if ( (int)a2 <= 19 )
{
v30 = (const char *)ip_to_str(a4);
v31 = (const char *)ip_to_str(a3);
return alog(4LL, 0LL, "rrep_process", "IP data field too short (%u bytes) from %s to %s", a2, v31, v30);
}
v7 = *(_DWORD *)(a1 + 4);
v9 = a6;
result = 11LL * (unsigned int)func0(a6);
if ( v7 != this_host[result + 20] )
{
v11 = *(_DWORD *)(a1 + 12);
v45 = *(_DWORD *)(a1 + 8);
v43 = v11;
v48 = *(_DWORD *)(a1 + 16);
v50 = *(_BYTE *)(a1 + 3);
v12 = (const char *)ip_to_str(v7);
v13 = ip_to_str(v11);
v14 = (const char *)ip_to_str(a3);
v15 = (const char *)v13;
v16 = (unsigned __int8 *)(a1 + 20);
alog(7LL, 0LL, "rrep_process", "from %s about %s->%s", v14, v15, v12);
log_pkt_fields(a1);
v55 = 0;
v44 = 0;
if ( a2 != 20 )
{
v17 = 0;
do
{
v19 = *v16;
if ( (_BYTE)v19 == 1 )
{
alog(6LL, 0LL, "rrep_process", "RREP include EXTENSION");
}
else if ( (_BYTE)v19 == 4 && v16[1] == 4 )
{
v56 = *(_DWORD *)(v16 + 2);
v29 = (const char *)ip_to_str(v56);
alog(7LL, 0LL, "rrep_process", "RREP_INET_DEST_EXT: <%s>", v29);
v55 = 1;
v44 = 16;
}
else
{
alog(4LL, 0LL, "rrep_process", "Unknown or bad extension %d", v19);
}
v18 = v16[1];
v17 += v18 + 2;
v16 += v18 + 2;
}
while ( a2 - v17 > 0x14 );
}
v52 = func1(v45);
v54 = func1(v48);
v49 = v50 + 1;
v46 = rt_table_find(v7);
v20 = rt_table_find(v43);
v21 = v46;
v22 = v52;
v51 = v20;
if ( !v46 )
{
v25 = (unsigned __int8)v49;
v26 = rt_table_insert(v7, a3, (unsigned __int8)v49, v52, v54, 1LL, v44, v9);
v53 = 0;
v47 = 0;
goto LABEL_16;
}
v23 = *(unsigned int *)(v46 + 20);
v47 = *(_BYTE *)(v46 + 32);
if ( !(_DWORD)v23 || (int)v23 < (int)v52 )
{
v24 = *(_WORD *)(v21 + 34);
LABEL_15:
v25 = (unsigned __int8)v49;
v53 = v24;
v26 = rt_table_update(v21, a3, (unsigned __int8)v49, v22, v54, 1LL, (unsigned __int16)(v44 | v24));
LABEL_16:
if ( (*(_BYTE *)(a1 + 1) & 0x40) != 0 )
{
func3();
v35 = func0(*(_DWORD *)(v26 + 24));
aodv_socket_send(v37, *(unsigned int *)(v26 + 28), 50LL, v36, &this_host[11 * v35 + 12]);
*(_BYTE *)(a1 + 1) &= 0xBFu;
}
v27 = (unsigned int)v9;
v28 = v43;
result = 11LL * (unsigned int)func0(v9);
if ( v43 == this_host[result + 20] )
{
if ( v55 )
{
v38 = rt_table_find(v56);
if ( v38 )
{
if ( *(_BYTE *)(v38 + 36) && *(unsigned __int8 *)(v38 + 32) <= v49 )
{
v39 = (const char *)ip_to_str(v56);
v28 = 0LL;
v27 = 7LL;
result = alog(7LL, 0LL, "rrep_process", "INET Response, but no update %s", v39);
}
else
{
result = rt_table_update(v38, v7, v25, 0LL, v54, 1LL, *(_WORD *)(v38 + 34) | 8u);
v28 = v40;
v27 = v41;
}
}
else
{
v28 = v7;
v27 = v56;
result = rt_table_insert(v56, v7, v25, 0LL, v54, 1LL, 8LL, v9);
}
}
if ( (v53 & 2) != 0 )
{
result = v47;
if ( *(_BYTE *)(v26 + 32) > v47 )
{
v28 = *(unsigned int *)(v26 + 16);
v27 = 1LL;
result = rerr_create(1LL, v28, *(unsigned int *)(v26 + 20));
if ( *(_DWORD *)(v26 + 232) )
{
v28 = 0xFFFFFFFFLL;
v32 = func0(*(_DWORD *)(v26 + 24));
v27 = v33;
result = aodv_socket_send(
v33,
0xFFFFFFFFLL,
8 * (unsigned int)*(unsigned __int8 *)(v33 + 3) + 4,
v34,
&this_host[11 * v32 + 12]);
}
}
}
}
else if ( v51 && *(_BYTE *)(v51 + 36) == 1 )
{
v28 = a2;
v27 = a1;
result = func6(a1, a2, v51, v26);
}
else
{
v28 = 0LL;
v27 = 7LL;
result = alog(7LL, 0LL, "rrep_process", "Could not forward RREP - NO ROUTE!!!");
}
if ( !llfeedback )
{
result = optimized_hellos;
if ( optimized_hellos )
result = hello_start(v27, v28);
}
return result;
}
if ( (_DWORD)v23 == v52 )
{
v24 = *(_WORD *)(v21 + 34);
if ( !*(_BYTE *)(v21 + 36) || (v24 & 1) != 0 || v47 > v49 )
goto LABEL_15;
}
result = v47;
if ( v47 > 1u )
result = alog(7LL, 0LL, "rrep_process", "Dropping RREP, fwd_rt->hcnt=%d fwd_rt->seqno=%ld", v47, v23);
}
return result;
}

original_code:
void rrep_process(RREP * rrep, int rreplen, struct in_addr ip_src,
      struct in_addr ip_dst, int ip_ttl,
      unsigned int ifindex)
{
    u_int32_t rrep_lifetime, rrep_seqno, rrep_new_hcnt;
    u_int8_t pre_repair_hcnt = 0, pre_repair_flags = 0;
    rt_table_t *fwd_rt, *rev_rt;
    AODV_ext *ext;
    unsigned int extlen = 0;
    int rt_flags = 0;
    struct in_addr rrep_dest, rrep_orig;
    struct in_addr inet_dest_addr;
    int inet_rrep = 0;
    rrep_dest.s_addr = rrep->dest_addr;
    rrep_orig.s_addr = rrep->orig_addr;
    rrep_seqno = ntohl(rrep->dest_seqno);
    rrep_lifetime = ntohl(rrep->lifetime);
    rrep_new_hcnt = rrep->hcnt + 1;
    if (rreplen < (int) sizeof(RREP)) {
 alog(4, 0, __FUNCTION__,
      "IP data field too short (%u bytes)"
      " from %s to %s", rreplen, ip_to_str(ip_src), ip_to_str(ip_dst));
 return;
    }
    if (rrep_dest.s_addr == (this_host.devs[ifindex2devindex(ifindex)]).ipaddr.s_addr)
 return;
    alog(7, 0, __FUNCTION__, "from %s about %s->%s", ip_to_str(ip_src), ip_to_str(rrep_orig), ip_to_str(rrep_dest));
    log_pkt_fields((AODV_msg *) rrep);
    ext = (AODV_ext *) ((char *) rrep + sizeof(RREP));
    while ((rreplen - extlen) > sizeof(RREP)) {
 switch (ext->type) {
 case 1:
     alog(6, 0, __FUNCTION__, "RREP include EXTENSION");
     break;
 case 4:
     if (ext->length == sizeof(u_int32_t)) {
  memcpy(&inet_dest_addr, ((char *)((char *)ext + sizeof(AODV_ext))), ext->length);
  alog(7, 0, __FUNCTION__, "RREP_INET_DEST_EXT: <%s>", ip_to_str(inet_dest_addr));
  rt_flags |= 0x10;
  inet_rrep = 1;
  break;
     }
 default:
     alog(4, 0, __FUNCTION__, "Unknown or bad extension %d",
   ext->type);
     break;
 }
 extlen += (sizeof(AODV_ext) + ext->length);
 ext = ((AODV_ext *)((char *)ext + sizeof(AODV_ext) + ext->length));
    }
    fwd_rt = rt_table_find(rrep_dest);
    rev_rt = rt_table_find(rrep_orig);
    if (!fwd_rt) {
 fwd_rt = rt_table_insert(rrep_dest, ip_src, rrep_new_hcnt, rrep_seqno,
     rrep_lifetime, 1, rt_flags, ifindex);
    } else if (fwd_rt->dest_seqno == 0 ||
        (int32_t) rrep_seqno > (int32_t) fwd_rt->dest_seqno ||
        (rrep_seqno == fwd_rt->dest_seqno &&
  (fwd_rt->state == 0 || fwd_rt->flags & 0x1 ||
   rrep_new_hcnt < fwd_rt->hcnt))) {
 pre_repair_hcnt = fwd_rt->hcnt;
 pre_repair_flags = fwd_rt->flags;
 fwd_rt = rt_table_update(fwd_rt, ip_src, rrep_new_hcnt, rrep_seqno,
     rrep_lifetime, 1,
     rt_flags | fwd_rt->flags);
    } else {
 if (fwd_rt->hcnt > 1) {
     alog(7, 0, __FUNCTION__, "Dropping RREP, fwd_rt->hcnt=%d fwd_rt->seqno=%ld", fwd_rt->hcnt, fwd_rt->dest_seqno);
 }
 return;
    }
    if (rrep->a) {
 RREP_ack *rrep_ack;
 rrep_ack = rrep_ack_create();
 aodv_socket_send((AODV_msg *) rrep_ack, fwd_rt->next_hop,
    40 + 10, 255, &(this_host.devs[ifindex2devindex(fwd_rt->ifindex)]));
 rrep->a = 0;
    }
    if (rrep_orig.s_addr == (this_host.devs[ifindex2devindex(ifindex)]).ipaddr.s_addr) {
 if (inet_rrep) {
     rt_table_t *inet_rt;
     inet_rt = rt_table_find(inet_dest_addr);
     if (!inet_rt)
  rt_table_insert(inet_dest_addr, rrep_dest, rrep_new_hcnt, 0,
    rrep_lifetime, 1, 0x8, ifindex);
     else if (inet_rt->state == 0 || rrep_new_hcnt < inet_rt->hcnt) {
  rt_table_update(inet_rt, rrep_dest, rrep_new_hcnt, 0,
    rrep_lifetime, 1, 0x8 |
    inet_rt->flags);
     } else {
  alog(7, 0, __FUNCTION__, "INET Response, but no update %s", ip_to_str(inet_dest_addr));
     }
 }
 if (pre_repair_flags & 0x2) {
     if (fwd_rt->hcnt > pre_repair_hcnt) {
  RERR *rerr;
  u_int8_t rerr_flags = 0;
  struct in_addr dest;
  dest.s_addr = ((in_addr_t) 0xFFFFFFFF);
  rerr_flags |= 0x1;
  rerr = rerr_create(rerr_flags, fwd_rt->dest_addr,
       fwd_rt->dest_seqno);
  if (fwd_rt->nprec)
      aodv_socket_send((AODV_msg *) rerr, dest,
         (sizeof(RERR) + (rerr->dest_count-1)*sizeof(RERR_udest)), 1,
         &(this_host.devs[ifindex2devindex(fwd_rt->ifindex)]));
     }
 }
    } else {
 if (rev_rt && rev_rt->state == 1) {
     rrep_forward(rrep, rreplen, rev_rt, fwd_rt, --ip_ttl);
 } else {
     alog(7, 0, __FUNCTION__, "Could not forward RREP - NO ROUTE!!!");
 }
    }
    if (!llfeedback && optimized_hellos)
 hello_start();
}

canonical_original_code:
void rrep_process(struct RREP *rrep, int rreplen, struct in_addr ip_src, struct in_addr ip_dst, int ip_ttl, unsigned int ifindex)
{
    unsigned int rrep_lifetime; unsigned int rrep_seqno; unsigned int rrep_new_hcnt;
    unsigned int pre_repair_hcnt = 0; unsigned int pre_repair_flags = 0;
    struct rt_table *fwd_rt; struct rt_table *rev_rt;
    struct AODV_ext *ext;
    unsigned int extlen = 0;
    int rt_flags = 0;
    struct in_addr rrep_dest; struct in_addr rrep_orig;
    struct in_addr inet_dest_addr;
    int inet_rrep = 0;
    rrep_dest.s_addr = rrep->dest_addr;
    rrep_orig.s_addr = rrep->orig_addr;
    rrep_seqno = ntohl(rrep->dest_seqno);
    rrep_lifetime = ntohl(rrep->lifetime);
    rrep_new_hcnt = rrep->hcnt + 1;
    if (rreplen < (int) sizeof(RREP)) {
 alog(4, 0, __FUNCTION__,
      "IP data field too short (%u bytes)"
      " from %s to %s", rreplen, ip_to_str(ip_src), ip_to_str(ip_dst));
 return;
    }
    if (rrep_dest.s_addr == (this_host.devs[ifindex2devindex(ifindex)]).ipaddr.s_addr)
 return;
    alog(7, 0, __FUNCTION__, "from %s about %s->%s", ip_to_str(ip_src), ip_to_str(rrep_orig), ip_to_str(rrep_dest));
    log_pkt_fields((struct AODV_msg *) rrep);
    ext = (struct AODV_ext *) ((char *) rrep + sizeof(RREP));
    while ((rreplen - extlen) > sizeof(RREP)) {
 switch (ext->type) {
 case 1:
     alog(6, 0, __FUNCTION__, "RREP include EXTENSION");
     break;
 case 4:
     if (ext->length == sizeof(u_int32_t)) {
  memcpy(&inet_dest_addr, ((char *)((char *)ext + sizeof(AODV_ext))), ext->length);
  alog(7, 0, __FUNCTION__, "RREP_INET_DEST_EXT: <%s>", ip_to_str(inet_dest_addr));
  rt_flags |= 0x10;
  inet_rrep = 1;
  break;
     }
 default:
     alog(4, 0, __FUNCTION__, "Unknown or bad extension %d",
   ext->type);
     break;
 }
 extlen += (sizeof(AODV_ext) + ext->length);
 ext = ((struct AODV_ext *)((char *)ext + sizeof(AODV_ext) + ext->length));
    }
    fwd_rt = rt_table_find(rrep_dest);
    rev_rt = rt_table_find(rrep_orig);
    if (!fwd_rt) {
 fwd_rt = rt_table_insert(rrep_dest, ip_src, rrep_new_hcnt, rrep_seqno,
     rrep_lifetime, 1, rt_flags, ifindex);
    } else if (fwd_rt->dest_seqno == 0 ||
        (int) rrep_seqno > (int) fwd_rt->dest_seqno ||
        (rrep_seqno == fwd_rt->dest_seqno &&
  (fwd_rt->state == 0 || fwd_rt->flags & 0x1 ||
   rrep_new_hcnt < fwd_rt->hcnt))) {
 pre_repair_hcnt = fwd_rt->hcnt;
 pre_repair_flags = fwd_rt->flags;
 fwd_rt = rt_table_update(fwd_rt, ip_src, rrep_new_hcnt, rrep_seqno,
     rrep_lifetime, 1,
     rt_flags | fwd_rt->flags);
    } else {
 if (fwd_rt->hcnt > 1) {
     alog(7, 0, __FUNCTION__, "Dropping RREP, fwd_rt->hcnt=%d fwd_rt->seqno=%ld", fwd_rt->hcnt, fwd_rt->dest_seqno);
 }
 return;
    }
    if (rrep->a) {
 struct RREP_ack *rrep_ack;
 rrep_ack = rrep_ack_create();
 aodv_socket_send((struct AODV_msg *) rrep_ack, fwd_rt->next_hop,
    40 + 10, 255, &(this_host.devs[ifindex2devindex(fwd_rt->ifindex)]));
 rrep->a = 0;
    }
    if (rrep_orig.s_addr == (this_host.devs[ifindex2devindex(ifindex)]).ipaddr.s_addr) {
 if (inet_rrep) {
     struct rt_table *inet_rt;
     inet_rt = rt_table_find(inet_dest_addr);
     if (!inet_rt)
  rt_table_insert(inet_dest_addr, rrep_dest, rrep_new_hcnt, 0,
    rrep_lifetime, 1, 0x8, ifindex);
     else if (inet_rt->state == 0 || rrep_new_hcnt < inet_rt->hcnt) {
  rt_table_update(inet_rt, rrep_dest, rrep_new_hcnt, 0,
    rrep_lifetime, 1, 0x8 |
    inet_rt->flags);
     } else {
  alog(7, 0, __FUNCTION__, "INET Response, but no update %s", ip_to_str(inet_dest_addr));
     }
 }
 if (pre_repair_flags & 0x2) {
     if (fwd_rt->hcnt > pre_repair_hcnt) {
  struct RERR *rerr;
  unsigned int rerr_flags = 0;
  struct in_addr dest;
  dest.s_addr = ((unsigned int) 0xFFFFFFFF);
  rerr_flags |= 0x1;
  rerr = rerr_create(rerr_flags, fwd_rt->dest_addr,
       fwd_rt->dest_seqno);
  if (fwd_rt->nprec)
      aodv_socket_send((struct AODV_msg *) rerr, dest,
         (sizeof(RERR) + (rerr->dest_count-1)*sizeof(RERR_udest)), 1,
         &(this_host.devs[ifindex2devindex(fwd_rt->ifindex)]));
     }
 }
    } else {
 if (rev_rt && rev_rt->state == 1) {
     rrep_forward(rrep, rreplen, rev_rt, fwd_rt, --ip_ttl);
 } else {
     alog(7, 0, __FUNCTION__, "Could not forward RREP - NO ROUTE!!!");
 }
    }
    if (!llfeedback && optimized_hellos)
 hello_start();
}

variable_types: rreplen int

variable_types: struct AODV_ext { unsigned int type; unsigned int length; } *

variable_types:
extlen
unsigned int

variable_types: struct RERR { unsigned int type; unsigned int res1; unsigned int n; unsigned int res2; unsigned int dest_count; unsigned int dest_addr; unsigned int dest_seqno; } *


repo: frank-liu/aodv-multi-interface

decompiled_code:
__int64 __fastcall rrep_add_hello_ext(__int64 a1, int a2, int a3)
{
__int64 v3; // rax

v3 = a2 + a1 + 20;
*(_WORD *)v3 = 1026;
*(_DWORD *)(v3 + 2) = a3;
return (unsigned int)(a2 + 6);
}

original_code:
int rrep_add_hello_ext(RREP * rrep, int offset, u_int32_t interval)
{
    AODV_ext *ext;
    ext = (AODV_ext *) ((char *) rrep + sizeof(RREP) + offset);
    ext->type = 2;
    ext->length = sizeof(interval);
    memcpy(((char *)((char *)ext + sizeof(AODV_ext))), &interval, sizeof(interval));
    return (offset + (sizeof(AODV_ext) + ext->length));
}

canonical_original_code:
int rrep_add_hello_ext(struct RREP *rrep, int offset, unsigned int interval)
{
    struct AODV_ext *ext;
    ext = (struct AODV_ext *) ((char *) rrep + sizeof(RREP) + offset);
    ext->type = 2;
    ext->length = sizeof(interval);
    memcpy(((char *)((char *)ext + sizeof(AODV_ext))), &interval, sizeof(interval));
    return (offset + (sizeof(AODV_ext) + ext->length));
}

variable_types: struct RREP { unsigned int type; unsigned int res1; unsigned int a; unsigned int r; unsigned int prefix; unsigned int res2; unsigned int hcnt; unsigned int dest_addr; unsigned int dest_seqno; unsigned int orig_addr; unsigned int lifetime; } *

variable_types: offset int

variable_types:
interval
unsigned int

return_type: int

user_defined_types: struct AODV_ext { unsigned int type; unsigned int length; }


original_code:
static inline long timeval_diff(struct timeval *t1, struct timeval *t2)
{
    long long res;
    if (!t1 || !t2)
 return -1;
    else {
 res = t1->tv_sec;
 res = ((res - t2->tv_sec) * 1000000 + t1->tv_usec - t2->tv_usec) / 1000;
 return (long) res;
    }
}

variable_types: struct timeval { long tv_sec; long tv_usec; } *

variable_types:
res
long long

return_type: long


devfromsock

decompiled_code:
char *__fastcall devfromsock(int a1)
{
int v1; // ecx
unsigned __int64 v2; // rdx
int v3; // eax

v1 = *((_DWORD *)&this_host + 11);
if ( v1 <= 0 )
return 0LL;
v2 = (unsigned int)((_DWORD)&this_host + 52);
v3 = 0;
while ( *(_DWORD *)v2 != a1 )
{
++v3;
v2 += 44LL;
if ( v3 == v1 )
return 0LL;
}
return (char *)&this_host + 44 * v3 + 48;
}

canonical_decompiled_code:
char *__fastcall func1(int a1)
{
int v1; // ecx
unsigned __int64 v2; // rdx
int v3; // eax

v1 = *((_DWORD *)&this_host + 11);
if ( v1 <= 0 )
return 0LL;
v2 = (unsigned int)((_DWORD)&this_host + 52);
v3 = 0;
while ( *(_DWORD *)v2 != a1 )
{
++v3;
v2 += 44LL;
if ( v3 == v1 )
return 0LL;
}
return (char *)&this_host + 44 * v3 + 48;
}

original_code:
static inline struct dev_info *devfromsock(int sock)
{
    int i;
    for (i = 0; i < this_host.nif; i++) {
 if (this_host.devs[i].sock == sock)
     return &this_host.devs[i];
    }
    return ((void *)0);
}

variable_types: sock int

variable_types: i int

return_type: struct dev_info { int enabled; int sock; int psock; unsigned int ifindex; char ifname[16]; struct in_addr { unsigned int s_addr; } ipaddr; struct in_addr netmask; struct in_addr broadcast; } *

user_defined_types: struct dev_info { int enabled; int sock; int psock; unsigned int ifindex; char ifname[16]; struct in_addr ipaddr; struct in_addr netmask; struct in_addr broadcast; }


decompiled_code:
char *__fastcall cmsg_nxthdr_fix(__int64 a1, _QWORD *a2)
{
return _cmsg_nxthdr_fix(*(_QWORD *)(a1 + 32), *(_QWORD *)(a1 + 40), a2);
}

canonical_decompiled_code:
char *__fastcall func5(__int64 a1, _QWORD *a2)
{
return func2(*(_QWORD *)(a1 + 32), *(_QWORD *)(a1 + 40), a2);
}

original_code:
struct cmsghdr *cmsg_nxthdr_fix(struct msghdr *__msg, struct cmsghdr *__cmsg)
{
    return __cmsg_nxthdr_fix(__msg->msg_control, __msg->msg_controllen, __cmsg);
}

variable_types: struct msghdr { void *msg_name; unsigned int msg_namelen; struct iovec { void *iov_base; unsigned long iov_len; } *msg_iov; unsigned long msg_iovlen; void *msg_control; unsigned long msg_controllen; int msg_flags; } *

return_type: struct cmsghdr { unsigned long cmsg_len; int cmsg_level; int cmsg_type; unsigned char __cmsg_data[]; } *

user_defined_types: struct msghdr { void *msg_name; unsigned int msg_namelen; struct iovec *msg_iov; unsigned long msg_iovlen; void *msg_control; unsigned long msg_controllen; int msg_flags; }


decompiled_code:
void aodv_socket_init()
{
int v0; // ecx
unsigned __int64 v1; // r12
int v2; // eax
int v3; // eax
__int64 v4; // rdi
int v5; // eax
int v6; // edi
socklen_t v7; // edx
int v8; // edi
int v9; // [rsp+0h] [rbp-58h] BYREF
int optval; // [rsp+4h] [rbp-54h] BYREF
unsigned int v11; // [rsp+8h] [rbp-50h] BYREF
socklen_t optlen; // [rsp+Ch] [rbp-4Ch] BYREF
struct sockaddr v13; // [rsp+10h] [rbp-48h] BYREF
char dest[16]; // [rsp+20h] [rbp-38h] BYREF
__int128 v15; // [rsp+30h] [rbp-28h]
__int64 v16; // [rsp+40h] [rbp-18h]

v0 = *((_DWORD *)&this_host + 11);
v9 = 1;
optval = 16;
v11 = 0x40000;
optlen = 4;
if ( !v0 )
{
fwrite("No interfaces configured\n", 1uLL, 0x19uLL, stderr);
exit(-1);
}
v1 = (unsigned int)((_DWORD)&this_host + 64);
do
{
if ( *(_DWORD *)(v1 - 16) )
{
v2 = socket(2, 2, 17);
*(_DWORD *)(v1 - 12) = v2;
if ( v2 < 0 || (v3 = socket(2, 3, 255), *(_DWORD *)(v1 - 8) = v3, v3 < 0) )
{
perror(&byte_1A46);
exit(-1);
}
v16 = 0LL;
*(_OWORD *)dest = 0LL;
v15 = 0LL;
strcpy(dest, (const char *)v1);
v4 = *(unsigned int *)(v1 - 12);
if ( setsockopt(v4, 1, 25, dest, 0x28u) < 0 )
goto LABEL_30;
*(_QWORD *)&v13.sa_data[6] = 0LL;
v13.sa_family = 2;
*(_WORD *)v13.sa_data = _bswap_16_constprop_0(v4, &v13, 16LL);
v5 = _bswap_32_constprop_0(v4);
v6 = *(_DWORD *)(v1 - 12);
*(_DWORD *)&v13.sa_data[2] = v5;
if ( bind(v6, &v13, v7) < 0 )
{
perror("Bind failed ");
exit(-1);
}
if ( setsockopt(*(_DWORD *)(v1 - 12), 1, 6, &v9, 4u) < 0 )
{
perror("SO_BROADCAST failed ");
exit(-1);
}
if ( setsockopt(*(_DWORD *)(v1 - 12), 1, 12, &optval, 4u) < 0 )
{
perror("Setsockopt SO_PRIORITY failed ");
exit(-1);
}
if ( setsockopt(*(_DWORD *)(v1 - 12), 0, 12, &v9, 4u) < 0 )
{
perror("Setsockopt IP_RECVTTL failed ");
exit(-1);
}
if ( setsockopt(*(_DWORD *)(v1 - 12), 0, 8, &v9, 4u) < 0 )
{
perror("Setsockopt IP_PKTINFO failed ");
exit(-1);
}
if ( setsockopt(*(_DWORD *)(v1 - 8), 1, 25, dest, 0x28u) < 0 )
{
LABEL_30:
fprintf(stderr, "SO_BINDTODEVICE failed for %s", (const char *)v1);
perror(" ");
exit(-1);
}
v8 = *(_DWORD *)(v1 - 8);
v11 = 262140;
if ( setsockopt(v8, 1, 7, &v11, optlen) < 0 )
alog(5LL, 0LL, "aodv_socket_init", "Could not set send socket buffer size");
if ( !getsockopt(*(_DWORD *)(v1 - 8), 1, 7, &v11, &optlen) )
alog(5LL, 0LL, "aodv_socket_init", "RAW send socket buffer size set to %d", v11);
while ( setsockopt(*(_DWORD *)(v1 - 12), 1, 8, &v11, optlen) )
{
if ( v11 <= 0x32B )
{
alog(3LL, 0LL, "aodv_socket_init", "Could not set receive buffer size");
exit(-1);
}
v11 -= 1024;
}
alog(5LL, 0LL, "aodv_socket_init", "Receive buffer size set to %d", v11);
if ( (int)attach_callback_func(*(unsigned int *)(v1 - 12), aodv_socket_read) < 0 )
{
perror("register input handler failed ");
exit(-1);
}
}
v1 += 44LL;
}
while ( (struct timeval *)v1 != (struct timeval *)((char *)&this_host + 504) );
num_rreq = 0;
num_rerr = 0;
}

canonical_decompiled_code:
void func6()
{
int v0; // ecx
unsigned __int64 v1; // r12
int v2; // eax
int v3; // eax
__int64 v4; // rdi
int v5; // eax
int v6; // edi
socklen_t v7; // edx
int v8; // edi
int v9; // [rsp+0h] [rbp-58h] BYREF
int optval; // [rsp+4h] [rbp-54h] BYREF
unsigned int v11; // [rsp+8h] [rbp-50h] BYREF
socklen_t optlen; // [rsp+Ch] [rbp-4Ch] BYREF
struct sockaddr v13; // [rsp+10h] [rbp-48h] BYREF
char dest[16]; // [rsp+20h] [rbp-38h] BYREF
__int128 v15; // [rsp+30h] [rbp-28h]
__int64 v16; // [rsp+40h] [rbp-18h]

v0 = *((_DWORD *)&this_host + 11);
v9 = 1;
optval = 16;
v11 = 0x40000;
optlen = 4;
if ( !v0 )
{
fwrite("No interfaces configured\n", 1uLL, 0x19uLL, stderr);
exit(-1);
}
v1 = (unsigned int)((_DWORD)&this_host + 64);
do
{
if ( *(_DWORD *)(v1 - 16) )
{
v2 = socket(2, 2, 17);
*(_DWORD *)(v1 - 12) = v2;
if ( v2 < 0 || (v3 = socket(2, 3, 255), *(_DWORD *)(v1 - 8) = v3, v3 < 0) )
{
perror(&byte_1A46);
exit(-1);
}
v16 = 0LL;
*(_OWORD *)dest = 0LL;
v15 = 0LL;
strcpy(dest, (const char *)v1);
v4 = *(unsigned int *)(v1 - 12);
if ( setsockopt(v4, 1, 25, dest, 0x28u) < 0 )
goto LABEL_30;
*(_QWORD *)&v13.sa_data[6] = 0LL;
v13.sa_family = 2;
*(_WORD *)v13.sa_data = func4(v4, &v13, 16LL);
v5 = func3(v4);
v6 = *(_DWORD *)(v1 - 12);
*(_DWORD *)&v13.sa_data[2] = v5;
if ( bind(v6, &v13, v7) < 0 )
{
perror("Bind failed ");
exit(-1);
}
if ( setsockopt(*(_DWORD *)(v1 - 12), 1, 6, &v9, 4u) < 0 )
{
perror("SO_BROADCAST failed ");
exit(-1);
}
if ( setsockopt(*(_DWORD *)(v1 - 12), 1, 12, &optval, 4u) < 0 )
{
perror("Setsockopt SO_PRIORITY failed ");
exit(-1);
}
if ( setsockopt(*(_DWORD *)(v1 - 12), 0, 12, &v9, 4u) < 0 )
{
perror("Setsockopt IP_RECVTTL failed ");
exit(-1);
}
if ( setsockopt(*(_DWORD *)(v1 - 12), 0, 8, &v9, 4u) < 0 )
{
perror("Setsockopt IP_PKTINFO failed ");
exit(-1);
}
if ( setsockopt(*(_DWORD *)(v1 - 8), 1, 25, dest, 0x28u) < 0 )
{
LABEL_30:
fprintf(stderr, "SO_BINDTODEVICE failed for %s", (const char *)v1);
perror(" ");
exit(-1);
}
v8 = *(_DWORD *)(v1 - 8);
v11 = 262140;
if ( setsockopt(v8, 1, 7, &v11, optlen) < 0 )
alog(5LL, 0LL, "aodv_socket_init", "Could not set send socket buffer size");
if ( !getsockopt(*(_DWORD *)(v1 - 8), 1, 7, &v11, &optlen) )
alog(5LL, 0LL, "aodv_socket_init", "RAW send socket buffer size set to %d", v11);
while ( setsockopt(*(_DWORD *)(v1 - 12), 1, 8, &v11, optlen) )
{
if ( v11 <= 0x32B )
{
alog(3LL, 0LL, "aodv_socket_init", "Could not set receive buffer size");
exit(-1);
}
v11 -= 1024;
}
alog(5LL, 0LL, "aodv_socket_init", "Receive buffer size set to %d", v11);
if ( (int)attach_callback_func(*(unsigned int *)(v1 - 12), aodv_socket_read) < 0 )
{
perror("register input handler failed ");
exit(-1);
}
}
v1 += 44LL;
}
while ( (struct timeval *)v1 != (struct timeval *)((char *)&this_host + 504) );
num_rreq = 0;
num_rerr = 0;
}

original_code:
void aodv_socket_init()
{
    struct sockaddr_in aodv_addr;
    struct ifreq ifr;
    int i, retval = 0;
    int on = 1;
    int tos = 0x10;
    int bufsize = 256*1024;
    socklen_t optlen = sizeof(bufsize);
    if (this_host.nif == 0) {
 fprintf(stderr, "No interfaces configured\n");
 exit(-1);
    }
    for (i = 0; i < 10; i++) {
 if (!(this_host.devs[i]).enabled)
     continue;
 (this_host.devs[i]).sock = socket(2, SOCK_DGRAM, IPPROTO_UDP);
 if ((this_host.devs[i]).sock < 0) {
     perror("");
     exit(-1);
 }
 (this_host.devs[i]).psock = socket(2, SOCK_RAW, IPPROTO_RAW);
 if ((this_host.devs[i]).psock < 0) {
     perror("");
     exit(-1);
 }
    memset(&ifr, 0, sizeof(struct ifreq));
 strcpy(ifr.ifr_ifrn.ifrn_name, (this_host.devs[i]).ifname);
 if (setsockopt((this_host.devs[i]).sock, 1, 25,
         &ifr, sizeof(ifr)) < 0) {
     fprintf(stderr, "SO_BINDTODEVICE failed for %s", (this_host.devs[i]).ifname);
     perror(" ");
     exit(-1);
 }
 memset(&aodv_addr, 0, sizeof(aodv_addr));
 aodv_addr.sin_family = 2;
 aodv_addr.sin_port = htons(654);
 aodv_addr.sin_addr.s_addr = htonl(((in_addr_t) 0x00000000));
 retval = bind((this_host.devs[i]).sock, (struct sockaddr *) &aodv_addr,
        sizeof(struct sockaddr));
 if (retval < 0) {
     perror("Bind failed ");
     exit(-1);
 }
 if (setsockopt((this_host.devs[i]).sock, 1, 6,
         &on, sizeof(int)) < 0) {
     perror("SO_BROADCAST failed ");
     exit(-1);
 }
 if (setsockopt((this_host.devs[i]).sock, 1, 12,
         &tos, sizeof(int)) < 0) {
     perror("Setsockopt SO_PRIORITY failed ");
     exit(-1);
 }
 if (setsockopt((this_host.devs[i]).sock, 0, 12,
         &on, sizeof(int)) < 0) {
     perror("Setsockopt IP_RECVTTL failed ");
     exit(-1);
 }
 if (setsockopt((this_host.devs[i]).sock, 0, 8,
         &on, sizeof(int)) < 0) {
     perror("Setsockopt IP_PKTINFO failed ");
     exit(-1);
 }
 if (setsockopt((this_host.devs[i]).psock, 1, 25,
         &ifr, sizeof(ifr)) < 0) {
     fprintf(stderr, "SO_BINDTODEVICE failed for %s", (this_host.devs[i]).ifname);
     perror(" ");
     exit(-1);
 }
 bufsize = 4 * 65535;
 if (setsockopt((this_host.devs[i]).psock, 1, 7,
         (char *) &bufsize, optlen) < 0) {
     alog(5, 0, __FUNCTION__, "Could not set send socket buffer size");
 }
 if (getsockopt((this_host.devs[i]).psock, 1, 7,
         (char *) &bufsize, &optlen) == 0) {
     alog(5, 0, __FUNCTION__,
   "RAW send socket buffer size set to %d", bufsize);
 }
 for (;; bufsize -= 1024) {
     if (setsockopt((this_host.devs[i]).sock, 1, 8,
      (char *) &bufsize, optlen) == 0) {
  alog(5, 0, __FUNCTION__,
       "Receive buffer size set to %d", bufsize);
  break;
     }
     if (bufsize < sizeof(RERR) + 100 * sizeof(RERR_udest)) {
  alog(3, 0, __FUNCTION__,
       "Could not set receive buffer size");
  exit(-1);
     }
 }
 retval = attach_callback_func((this_host.devs[i]).sock, aodv_socket_read);
 if (retval < 0) {
     perror("register input handler failed ");
     exit(-1);
 }
    }
    num_rreq = 0;
    num_rerr = 0;
}

canonical_original_code:
void aodv_socket_init()
{
    struct sockaddr_in aodv_addr;
    struct ifreq ifr;
    int i; int retval = 0;
    int on = 1;
    int tos = 0x10;
    int bufsize = 256*1024;
    unsigned int optlen = sizeof(bufsize);
    if (this_host.nif == 0) {
 fprintf(stderr, "No interfaces configured\n");
 exit(-1);
    }
    for (i = 0; i < 10; i++) {
 if (!(this_host.devs[i]).enabled)
     continue;
 (this_host.devs[i]).sock = socket(2, SOCK_DGRAM, IPPROTO_UDP);
 if ((this_host.devs[i]).sock < 0) {
     perror("");
     exit(-1);
 }
 (this_host.devs[i]).psock = socket(2, SOCK_RAW, IPPROTO_RAW);
 if ((this_host.devs[i]).psock < 0) {
     perror("");
     exit(-1);
 }
    memset(&ifr, 0, sizeof(struct ifreq));
 strcpy(ifr.ifr_ifrn.ifrn_name, (this_host.devs[i]).ifname);
 if (setsockopt((this_host.devs[i]).sock, 1, 25,
         &ifr, sizeof(ifr)) < 0) {
     fprintf(stderr, "SO_BINDTODEVICE failed for %s", (this_host.devs[i]).ifname);
     perror(" ");
     exit(-1);
 }
 memset(&aodv_addr, 0, sizeof(aodv_addr));
 aodv_addr.sin_family = 2;
 aodv_addr.sin_port = htons(654);
 aodv_addr.sin_addr.s_addr = htonl(((unsigned int) 0x00000000));
 retval = bind((this_host.devs[i]).sock, (struct sockaddr *) &aodv_addr,
        sizeof(struct sockaddr));
 if (retval < 0) {
     perror("Bind failed ");
     exit(-1);
 }
 if (setsockopt((this_host.devs[i]).sock, 1, 6,
         &on, sizeof(int)) < 0) {
     perror("SO_BROADCAST failed ");
     exit(-1);
 }
 if (setsockopt((this_host.devs[i]).sock, 1, 12,
         &tos, sizeof(int)) < 0) {
     perror("Setsockopt SO_PRIORITY failed ");
     exit(-1);
 }
 if (setsockopt((this_host.devs[i]).sock, 0, 12,
         &on, sizeof(int)) < 0) {
     perror("Setsockopt IP_RECVTTL failed ");
     exit(-1);
 }
 if (setsockopt((this_host.devs[i]).sock, 0, 8,
         &on, sizeof(int)) < 0) {
     perror("Setsockopt IP_PKTINFO failed ");
     exit(-1);
 }
 if (setsockopt((this_host.devs[i]).psock, 1, 25,
         &ifr, sizeof(ifr)) < 0) {
     fprintf(stderr, "SO_BINDTODEVICE failed for %s", (this_host.devs[i]).ifname);
     perror(" ");
     exit(-1);
 }
 bufsize = 4 * 65535;
 if (setsockopt((this_host.devs[i]).psock, 1, 7,
         (char *) &bufsize, optlen) < 0) {
     alog(5, 0, __FUNCTION__, "Could not set send socket buffer size");
 }
 if (getsockopt((this_host.devs[i]).psock, 1, 7,
         (char *) &bufsize, &optlen) == 0) {
     alog(5, 0, __FUNCTION__,
   "RAW send socket buffer size set to %d", bufsize);
 }
 for (;; bufsize -= 1024) {
     if (setsockopt((this_host.devs[i]).sock, 1, 8,
      (char *) &bufsize, optlen) == 0) {
  alog(5, 0, __FUNCTION__,
       "Receive buffer size set to %d", bufsize);
  break;
     }
     if (bufsize < sizeof(RERR) + 100 * sizeof(RERR_udest)) {
  alog(3, 0, __FUNCTION__,
       "Could not set receive buffer size");
  exit(-1);
     }
 }
 retval = attach_callback_func((this_host.devs[i]).sock, aodv_socket_read);
 if (retval < 0) {
     perror("register input handler failed ");
     exit(-1);
 }
    }
    num_rreq = 0;
    num_rerr = 0;
}

variable_types: struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr { unsigned int s_addr; } sin_addr; unsigned char sin_zero[-1]; }

variable_types: struct ifreq { union { char ifrn_name[16]; } ifr_ifrn; union { struct sockaddr { unsigned short sa_family; char sa_data[14]; } ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; struct sockaddr ifru_netmask; struct sockaddr ifru_hwaddr; short ifru_flags; int ifru_ivalue; int ifru_mtu; struct ifmap { unsigned long mem_start; unsigned long mem_end; unsigned short base_addr; unsigned char irq; unsigned char dma; unsigned char port; } ifru_map; char ifru_slave[16]; char ifru_newname[16]; char *ifru_data; } ifr_ifru; }

variable_types: retval int

variable_types: on int

variable_types: tos int

variable_types: bufsize int

variable_types:
optlen
unsigned int

return_type: void

user_defined_types: struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr sin_addr; unsigned char sin_zero[-1]; }

user_defined_types: struct ifreq { union { char ifrn_name[16]; } ifr_ifrn; union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; struct sockaddr ifru_netmask; struct sockaddr ifru_hwaddr; short ifru_flags; int ifru_ivalue; int ifru_mtu; struct ifmap ifru_map; char ifru_slave[16]; char ifru_newname[16]; char *ifru_data; } ifr_ifru; }


decompiled_code:
__int64 __fastcall aodv_socket_process_packet(unsigned __int8 *a1, __int64 a2, unsigned int a3, unsigned int a4, unsigned int a5, unsigned int a6)
{
unsigned __int8 v10; // al
const char *v12; // rbx
const char *v13; // rax

if ( *a1 == 2 && a5 == 1 && a4 == -1 )
return hello_process(a1, a2, a6);
neighbor_add(a1, a3, a6);
v10 = *a1;
if ( *a1 == 3 )
{
alog(7LL, 0LL, "aodv_socket_process_packet", "Received RERR");
return rerr_process(a1, (unsigned int)a2, a3, a4);
}
if ( v10 > 3u )
{
if ( v10 == 4 )
{
alog(7LL, 0LL, "aodv_socket_process_packet", "Received RREP_ACK");
return rrep_ack_process(a1, (unsigned int)a2, a3, a4);
}
}
else
{
if ( v10 == 1 )
return rreq_process(a1, (unsigned int)a2, a3, a4, a5, a6);
if ( v10 == 2 )
{
alog(7LL, 0LL, "aodv_socket_process_packet", "Received RREP");
return rrep_process(a1, (unsigned int)a2, a3, a4, a5, a6);
}
}
v12 = (const char *)ip_to_str(a4);
v13 = (const char *)ip_to_str(a3);
return alog(4LL, 0LL, "aodv_socket_process_packet", "Unknown msg type %u rcvd from %s to %s", *a1, v13, v12);
}

canonical_decompiled_code:
__int64 __fastcall func7(unsigned __int8 *a1, __int64 a2, unsigned int a3, unsigned int a4, unsigned int a5, unsigned int a6)
{
unsigned __int8 v10; // al
const char *v12; // rbx
const char *v13; // rax

if ( *a1 == 2 && a5 == 1 && a4 == -1 )
return hello_process(a1, a2, a6);
neighbor_add(a1, a3, a6);
v10 = *a1;
if ( *a1 == 3 )
{
alog(7LL, 0LL, "aodv_socket_process_packet", "Received RERR");
return rerr_process(a1, (unsigned int)a2, a3, a4);
}
if ( v10 > 3u )
{
if ( v10 == 4 )
{
alog(7LL, 0LL, "aodv_socket_process_packet", "Received RREP_ACK");
return rrep_ack_process(a1, (unsigned int)a2, a3, a4);
}
}
else
{
if ( v10 == 1 )
return rreq_process(a1, (unsigned int)a2, a3, a4, a5, a6);
if ( v10 == 2 )
{
alog(7LL, 0LL, "aodv_socket_process_packet", "Received RREP");
return rrep_process(a1, (unsigned int)a2, a3, a4, a5, a6);
}
}
v12 = (const char *)ip_to_str(a4);
v13 = (const char *)ip_to_str(a3);
return alog(4LL, 0LL, "aodv_socket_process_packet", "Unknown msg type %u rcvd from %s to %s", *a1, v13, v12);
}

original_code:
void aodv_socket_process_packet(AODV_msg * aodv_msg, int len,
      struct in_addr src,
      struct in_addr dst,
      int ttl, unsigned int ifindex)
{
    if ((aodv_msg->type == 2 && ttl == 1 &&
  dst.s_addr == ((in_addr_t) 0xFFFFFFFF))) {
 hello_process((RREP *) aodv_msg, len, ifindex);
 return;
    }
    neighbor_add(aodv_msg, src, ifindex);
    switch (aodv_msg->type) {
    case 1:
 rreq_process((RREQ *) aodv_msg, len, src, dst, ttl, ifindex);
 break;
    case 2:
 alog(7, 0, __FUNCTION__, "Received RREP");
 rrep_process((RREP *) aodv_msg, len, src, dst, ttl, ifindex);
 break;
    case 3:
 alog(7, 0, __FUNCTION__, "Received RERR");
 rerr_process((RERR *) aodv_msg, len, src, dst);
 break;
    case 4:
 alog(7, 0, __FUNCTION__, "Received RREP_ACK");
 rrep_ack_process((RREP_ack *) aodv_msg, len, src, dst);
 break;
    default:
 alog(4, 0, __FUNCTION__,
      "Unknown msg type %u rcvd from %s to %s", aodv_msg->type,
      ip_to_str(src), ip_to_str(dst));
    }
}

canonical_original_code:
void aodv_socket_process_packet(struct AODV_msg *aodv_msg, int len, struct in_addr src, struct in_addr dst, int ttl, unsigned int ifindex)
{
    if ((aodv_msg->type == 2 && ttl == 1 &&
  dst.s_addr == ((unsigned int) 0xFFFFFFFF))) {
 hello_process((struct RREP *) aodv_msg, len, ifindex);
 return;
    }
    neighbor_add(aodv_msg, src, ifindex);
    switch (aodv_msg->type) {
    case 1:
 rreq_process((struct RREQ *) aodv_msg, len, src, dst, ttl, ifindex);
 break;
    case 2:
 alog(7, 0, __FUNCTION__, "Received RREP");
 rrep_process((struct RREP *) aodv_msg, len, src, dst, ttl, ifindex);
 break;
    case 3:
 alog(7, 0, __FUNCTION__, "Received RERR");
 rerr_process((struct RERR *) aodv_msg, len, src, dst);
 break;
    case 4:
 alog(7, 0, __FUNCTION__, "Received RREP_ACK");
 rrep_ack_process((struct RREP_ack *) aodv_msg, len, src, dst);
 break;
    default:
 alog(4, 0, __FUNCTION__,
      "Unknown msg type %u rcvd from %s to %s", aodv_msg->type,
      ip_to_str(src), ip_to_str(dst));
    }
}

variable_types: struct AODV_msg { unsigned int type; } *

variable_types: len int

variable_types:
src
struct in_addr { unsigned int s_addr; }

variable_types:
dst
struct in_addr

variable_types: ttl int

variable_types:
ifindex
unsigned int

user_defined_types: struct RREP { unsigned int type; unsigned int res1; unsigned int a; unsigned int r; unsigned int prefix; unsigned int res2; unsigned int hcnt; unsigned int dest_addr; unsigned int dest_seqno; unsigned int orig_addr; unsigned int lifetime; }

user_defined_types: struct RREQ { unsigned int type; unsigned int res1; unsigned int d; unsigned int g; unsigned int r; unsigned int j; unsigned int res2; unsigned int hcnt; unsigned int rreq_id; unsigned int dest_addr; unsigned int dest_seqno; unsigned int orig_addr; unsigned int orig_seqno; }

user_defined_types: struct RERR { unsigned int type; unsigned int res1; unsigned int n; unsigned int res2; unsigned int dest_count; unsigned int dest_addr; unsigned int dest_seqno; }

user_defined_types: struct RREP_ack { unsigned int type; unsigned int reserved; }


decompiled_code:
__int64 __fastcall aodv_socket_read(int a1)
{
int v1; // eax
_DWORD *v2; // rsi
unsigned int v3; // er12
int v4; // er8
int v5; // eax
__int64 result; // rax
char *v7; // rax
unsigned int v8; // er8
unsigned int v9; // er10
unsigned int v10; // [rsp+Ch] [rbp-BCh]
__int64 v11[2]; // [rsp+10h] [rbp-B8h] BYREF
char v12; // [rsp+20h] [rbp-A8h] BYREF
unsigned int v13; // [rsp+24h] [rbp-A4h]
struct msghdr message; // [rsp+30h] [rbp-98h] BYREF
char v15; // [rsp+70h] [rbp-58h] BYREF

v11[0] = (__int64)recv_buf;
message.msg_name = &v12;
message.msg_iov = (iovec *)v11;
v11[1] = 812LL;
message.msg_namelen = 16;
message.msg_iovlen = 1LL;
message.msg_control = &v15;
message.msg_controllen = 56LL;
v1 = recvmsg(a1, &message, 0);
if ( v1 < 0 )
return alog(4LL, 0LL, "aodv_socket_read", "receive ERROR len=%d!", (unsigned int)v1);
v10 = v13;
if ( message.msg_controllen <= 0xF )
return alog(7LL, 0LL, "aodv_socket_read", "No TTL, packet ignored!");
v2 = message.msg_control;
if ( !message.msg_control )
return alog(7LL, 0LL, "aodv_socket_read", "No TTL, packet ignored!");
v3 = -1;
do
{
if ( !v2[2] )
{
v5 = v2[3];
if ( v5 != 2 && v5 == 8 )
v3 = v2[6];
}
v2 = cmsg_nxthdr_fix((__int64)&message, v2);
}
while ( v2 );
if ( v4 == -1 )
return alog(7LL, 0LL, "aodv_socket_read", "No TTL, packet ignored!");
result = (unsigned int)((_DWORD)&this_host + 80);
while ( !*(_DWORD *)(result - 32) || *(_DWORD *)result != v10 )
{
result += 44LL;
if ( (struct timeval *)result == (struct timeval *)((char *)&this_host + 520) )
{
v7 = devfromsock(a1);
if ( v7 )
result = aodv_socket_process_packet(recv_buf, v9, v10, v3, v8, *((_DWORD *)v7 + 3));
else
result = alog(3LL, 0LL, "aodv_socket_read", "Could not get device info!\n");
return result;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(int a1)
{
int v1; // eax
_DWORD *v2; // rsi
unsigned int v3; // er12
int v4; // er8
int v5; // eax
__int64 result; // rax
char *v7; // rax
unsigned int v8; // er8
unsigned int v9; // er10
unsigned int v10; // [rsp+Ch] [rbp-BCh]
__int64 v11[2]; // [rsp+10h] [rbp-B8h] BYREF
char v12; // [rsp+20h] [rbp-A8h] BYREF
unsigned int v13; // [rsp+24h] [rbp-A4h]
struct msghdr message; // [rsp+30h] [rbp-98h] BYREF
char v15; // [rsp+70h] [rbp-58h] BYREF

v11[0] = (__int64)recv_buf;
message.msg_name = &v12;
message.msg_iov = (iovec *)v11;
v11[1] = 812LL;
message.msg_namelen = 16;
message.msg_iovlen = 1LL;
message.msg_control = &v15;
message.msg_controllen = 56LL;
v1 = recvmsg(a1, &message, 0);
if ( v1 < 0 )
return alog(4LL, 0LL, "aodv_socket_read", "receive ERROR len=%d!", (unsigned int)v1);
v10 = v13;
if ( message.msg_controllen <= 0xF )
return alog(7LL, 0LL, "aodv_socket_read", "No TTL, packet ignored!");
v2 = message.msg_control;
if ( !message.msg_control )
return alog(7LL, 0LL, "aodv_socket_read", "No TTL, packet ignored!");
v3 = -1;
do
{
if ( !v2[2] )
{
v5 = v2[3];
if ( v5 != 2 && v5 == 8 )
v3 = v2[6];
}
v2 = func5((__int64)&message, v2);
}
while ( v2 );
if ( v4 == -1 )
return alog(7LL, 0LL, "aodv_socket_read", "No TTL, packet ignored!");
result = (unsigned int)((_DWORD)&this_host + 80);
while ( !*(_DWORD *)(result - 32) || *(_DWORD *)result != v10 )
{
result += 44LL;
if ( (struct timeval *)result == (struct timeval *)((char *)&this_host + 520) )
{
v7 = func1(a1);
if ( v7 )
result = func7(recv_buf, v9, v10, v3, v8, *((_DWORD *)v7 + 3));
else
result = alog(3LL, 0LL, "aodv_socket_read", "Could not get device info!\n");
return result;
}
}
return result;
}

original_code:
static void aodv_socket_read(int fd)
{
    struct in_addr src, dst;
    int i, len, ttl = -1;
    AODV_msg *aodv_msg;
    struct dev_info *dev;
    struct msghdr msgh;
    struct cmsghdr *cmsg;
    struct iovec iov;
    char ctrlbuf[((((sizeof(int)) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)) + (((sizeof (struct cmsghdr)) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1))) +
   ((((sizeof(struct in_pktinfo)) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)) + (((sizeof (struct cmsghdr)) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)))];
    struct sockaddr_in src_addr;
    dst.s_addr = -1;
    iov.iov_base = recv_buf;
    iov.iov_len = sizeof(RERR) + 100 * sizeof(RERR_udest);
    msgh.msg_name = &src_addr;
    msgh.msg_namelen = sizeof(src_addr);
    msgh.msg_iov = &iov;
    msgh.msg_iovlen = 1;
    msgh.msg_control = ctrlbuf;
    msgh.msg_controllen = sizeof(ctrlbuf);
    len = recvmsg(fd, &msgh, 0);
    if (len < 0) {
 alog(4, 0, __FUNCTION__, "receive ERROR len=%d!", len);
 return;
    }
    src.s_addr = src_addr.sin_addr.s_addr;
    for (cmsg = ((size_t) (&msgh)->msg_controllen >= sizeof (struct cmsghdr) ? (struct cmsghdr *) (&msgh)->msg_control : (struct cmsghdr *) 0); cmsg != ((void *)0);
  cmsg = cmsg_nxthdr_fix((&msgh), (cmsg))) {
 if (cmsg->cmsg_level == 0) {
     switch (cmsg->cmsg_type) {
     case 2:
  ttl = *(((cmsg)->__cmsg_data));
  break;
     case 8:
       {
  struct in_pktinfo *pi = (struct in_pktinfo *)((cmsg)->__cmsg_data);
  dst.s_addr = pi->ipi_addr.s_addr;
       }
     }
 }
    }
    if (ttl < 0) {
 alog(7, 0, __FUNCTION__, "No TTL, packet ignored!");
 return;
    }
    for (i = 0; i < 10; i++)
 if (this_host.devs[i].enabled &&
     memcmp(&src, &this_host.devs[i].ipaddr,
     sizeof(struct in_addr)) == 0)
     return;
    aodv_msg = (AODV_msg *) recv_buf;
    dev = devfromsock(fd);
    if (!dev) {
 alog(3, 0, __FUNCTION__, "Could not get device info!\n");
 return;
    }
    aodv_socket_process_packet(aodv_msg, len, src, dst, ttl, dev->ifindex);
}

canonical_original_code:
static void aodv_socket_read(int fd)
{
    struct in_addr src; struct in_addr dst;
    int i; int len; int ttl = -1;
    struct AODV_msg *aodv_msg;
    struct dev_info *dev;
    struct msghdr msgh;
    struct cmsghdr *cmsg;
    struct iovec iov;
    char ctrlbuf[-1];
    struct sockaddr_in src_addr;
    dst.s_addr = -1;
    iov.iov_base = recv_buf;
    iov.iov_len = sizeof(RERR) + 100 * sizeof(RERR_udest);
    msgh.msg_name = &src_addr;
    msgh.msg_namelen = sizeof(src_addr);
    msgh.msg_iov = &iov;
    msgh.msg_iovlen = 1;
    msgh.msg_control = ctrlbuf;
    msgh.msg_controllen = sizeof(ctrlbuf);
    len = recvmsg(fd, &msgh, 0);
    if (len < 0) {
 alog(4, 0, __FUNCTION__, "receive ERROR len=%d!", len);
 return;
    }
    src.s_addr = src_addr.sin_addr.s_addr;
    for (cmsg = ((unsigned long) (&msgh)->msg_controllen >= sizeof (struct cmsghdr) ? (struct cmsghdr *) (&msgh)->msg_control : (struct cmsghdr *) 0); cmsg != ((void *)0);
  cmsg = cmsg_nxthdr_fix((&msgh), (cmsg))) {
 if (cmsg->cmsg_level == 0) {
     switch (cmsg->cmsg_type) {
     case 2:
  ttl = *(((cmsg)->__cmsg_data));
  break;
     case 8:
       {
  struct in_pktinfo *pi = (struct in_pktinfo *)((cmsg)->__cmsg_data);
  dst.s_addr = pi->ipi_addr.s_addr;
       }
     }
 }
    }
    if (ttl < 0) {
 alog(7, 0, __FUNCTION__, "No TTL, packet ignored!");
 return;
    }
    for (i = 0; i < 10; i++)
 if (this_host.devs[i].enabled &&
     memcmp(&src, &this_host.devs[i].ipaddr,
     sizeof(struct in_addr)) == 0)
     return;
    aodv_msg = (struct AODV_msg *) recv_buf;
    dev = devfromsock(fd);
    if (!dev) {
 alog(3, 0, __FUNCTION__, "Could not get device info!\n");
 return;
    }
    aodv_socket_process_packet(aodv_msg, len, src, dst, ttl, dev->ifindex);
}

variable_types: fd int

variable_types:
dst
struct in_addr { unsigned int s_addr; }

variable_types: struct dev_info { int enabled; int sock; int psock; unsigned int ifindex; char ifname[16]; struct in_addr { unsigned int s_addr; } ipaddr; struct in_addr netmask; struct in_addr broadcast; } *

variable_types: struct msghdr { void *msg_name; unsigned int msg_namelen; struct iovec { void *iov_base; unsigned long iov_len; } *msg_iov; unsigned long msg_iovlen; void *msg_control; unsigned long msg_controllen; int msg_flags; }

variable_types: struct cmsghdr { unsigned long cmsg_len; int cmsg_level; int cmsg_type; unsigned char __cmsg_data[]; } *

variable_types:
ctrlbuf
char [-1]

variable_types: struct in_pktinfo { int ipi_ifindex; struct in_addr { unsigned int s_addr; } ipi_spec_dst; struct in_addr ipi_addr; } *

user_defined_types: struct in_pktinfo { int ipi_ifindex; struct in_addr ipi_spec_dst; struct in_addr ipi_addr; }


decompiled_code:
void __fastcall aodv_socket_send(_BYTE *a1, unsigned int a2, int a3, unsigned __int8 a4, __int64 a5)
{
__int16 v8; // ax
int v9; // edi
int v10; // edx
const void *v11; // rcx
socklen_t v12; // er8
int v13; // eax
__int64 v14; // rbx
const char *v15; // rax
int v16; // eax
int v17; // eax
__m128i v18; // xmm1
int v19; // eax
__m128i v20; // xmm0
__int64 v21; // rbx
int *v22; // rax
__int64 v23; // rbx
int *v24; // rax
__int64 v25; // rax
const char *v26; // rcx
__int64 v27; // r8
__int64 v28; // rax
struct timeval tv; // [rsp+10h] [rbp-48h] BYREF
struct sockaddr addr; // [rsp+20h] [rbp-38h] BYREF

if ( wait_on_reboot && *a1 == 2 )
return;
*(_DWORD *)&addr.sa_data[2] = a2;
addr.sa_family = 2;
*(_QWORD *)&addr.sa_data[6] = 0LL;
v8 = _bswap_16_constprop_0(wait_on_reboot, 0LL, 2LL);
v9 = *(_DWORD *)(a5 + 4);
*(_WORD *)addr.sa_data = v8;
if ( setsockopt(v9, 0, v10, v11, v12) < 0 )
{
alog(4LL, 0LL, "aodv_socket_send", "ERROR setting ttl!");
return;
}
if ( ratelimit )
{
gettimeofday(&tv, 0LL);
if ( *a1 == 1 )
{
v19 = num_rreq;
if ( num_rreq != 9 )
{
v20 = _mm_loadu_si128((const __m128i *)&tv);
++num_rreq;
rreq_ratel[v19] = (__int128)v20;
goto LABEL_5;
}
v25 = timeval_diff(&tv, rreq_ratel);
v26 = "RATELIMIT: Dropping RREQ %ld ms";
v27 = v25;
if ( v25 > 999 )
{
memmove(rreq_ratel, (const void *)(unsigned int)((_DWORD)rreq_ratel + 16), 0x80uLL);
rreq_ratel[8] = (__int128)_mm_loadu_si128((const __m128i *)&tv);
goto LABEL_5;
}
}
else
{
if ( *a1 != 3 )
goto LABEL_5;
v17 = num_rerr;
if ( num_rerr != 9 )
{
v18 = _mm_loadu_si128((const __m128i *)&tv);
++num_rerr;
rerr_ratel[v17] = (__int128)v18;
goto LABEL_5;
}
v28 = timeval_diff(&tv, rerr_ratel);
if ( v28 > 999 )
{
memmove(rerr_ratel, (const void *)(unsigned int)((_DWORD)rerr_ratel + 16), 0x80uLL);
rerr_ratel[8] = (__int128)_mm_loadu_si128((const __m128i *)&tv);
goto LABEL_5;
}
v27 = v28;
v26 = "RATELIMIT: Dropping RERR %ld ms";
}
alog(7LL, 0LL, "aodv_socket_send", v26, v27);
return;
}
LABEL_5:
if ( a2 == -1 )
{
gettimeofday((struct timeval *)(unsigned int)((_DWORD)&this_host + 8), 0LL);
v16 = sendto(*(_DWORD *)(a5 + 4), &send_buf, a3, 0, &addr, 0x10u);
v14 = (unsigned int)v16;
if ( v16 < 0 )
{
v23 = ip_to_str(0xFFFFFFFFLL);
v24 = _errno_location();
alog(4LL, (unsigned int)*v24, "aodv_socket_send", "Failed send to bc %s", v23);
return;
}
if ( *a1 != 2 )
goto LABEL_7;
}
else
{
v13 = sendto(*(_DWORD *)(a5 + 4), &send_buf, a3, 0, &addr, 0x10u);
v14 = (unsigned int)v13;
if ( v13 >= 0 )
{
LABEL_7:
v15 = (const char *)ip_to_str(a2);
alog(6LL, 0LL, "aodv_socket_send", "AODV msg to %s ttl=%d size=%u", v15, a4, v14);
return;
}
v21 = ip_to_str(a2);
v22 = _errno_location();
alog(4LL, (unsigned int)*v22, "aodv_socket_send", "Failed send to %s", v21);
}
}

canonical_decompiled_code:
void __fastcall func9(_BYTE *a1, unsigned int a2, int a3, unsigned __int8 a4, __int64 a5)
{
__int16 v8; // ax
int v9; // edi
int v10; // edx
const void *v11; // rcx
socklen_t v12; // er8
int v13; // eax
__int64 v14; // rbx
const char *v15; // rax
int v16; // eax
int v17; // eax
__m128i v18; // xmm1
int v19; // eax
__m128i v20; // xmm0
__int64 v21; // rbx
int *v22; // rax
__int64 v23; // rbx
int *v24; // rax
__int64 v25; // rax
const char *v26; // rcx
__int64 v27; // r8
__int64 v28; // rax
struct timeval tv; // [rsp+10h] [rbp-48h] BYREF
struct sockaddr addr; // [rsp+20h] [rbp-38h] BYREF

if ( wait_on_reboot && *a1 == 2 )
return;
*(_DWORD *)&addr.sa_data[2] = a2;
addr.sa_family = 2;
*(_QWORD *)&addr.sa_data[6] = 0LL;
v8 = func4(wait_on_reboot, 0LL, 2LL);
v9 = *(_DWORD *)(a5 + 4);
*(_WORD *)addr.sa_data = v8;
if ( setsockopt(v9, 0, v10, v11, v12) < 0 )
{
alog(4LL, 0LL, "aodv_socket_send", "ERROR setting ttl!");
return;
}
if ( ratelimit )
{
gettimeofday(&tv, 0LL);
if ( *a1 == 1 )
{
v19 = num_rreq;
if ( num_rreq != 9 )
{
v20 = _mm_loadu_si128((const __m128i *)&tv);
++num_rreq;
rreq_ratel[v19] = (__int128)v20;
goto LABEL_5;
}
v25 = func0(&tv, rreq_ratel);
v26 = "RATELIMIT: Dropping RREQ %ld ms";
v27 = v25;
if ( v25 > 999 )
{
memmove(rreq_ratel, (const void *)(unsigned int)((_DWORD)rreq_ratel + 16), 0x80uLL);
rreq_ratel[8] = (__int128)_mm_loadu_si128((const __m128i *)&tv);
goto LABEL_5;
}
}
else
{
if ( *a1 != 3 )
goto LABEL_5;
v17 = num_rerr;
if ( num_rerr != 9 )
{
v18 = _mm_loadu_si128((const __m128i *)&tv);
++num_rerr;
rerr_ratel[v17] = (__int128)v18;
goto LABEL_5;
}
v28 = func0(&tv, rerr_ratel);
if ( v28 > 999 )
{
memmove(rerr_ratel, (const void *)(unsigned int)((_DWORD)rerr_ratel + 16), 0x80uLL);
rerr_ratel[8] = (__int128)_mm_loadu_si128((const __m128i *)&tv);
goto LABEL_5;
}
v27 = v28;
v26 = "RATELIMIT: Dropping RERR %ld ms";
}
alog(7LL, 0LL, "aodv_socket_send", v26, v27);
return;
}
LABEL_5:
if ( a2 == -1 )
{
gettimeofday((struct timeval *)(unsigned int)((_DWORD)&this_host + 8), 0LL);
v16 = sendto(*(_DWORD *)(a5 + 4), &send_buf, a3, 0, &addr, 0x10u);
v14 = (unsigned int)v16;
if ( v16 < 0 )
{
v23 = ip_to_str(0xFFFFFFFFLL);
v24 = _errno_location();
alog(4LL, (unsigned int)*v24, "aodv_socket_send", "Failed send to bc %s", v23);
return;
}
if ( *a1 != 2 )
goto LABEL_7;
}
else
{
v13 = sendto(*(_DWORD *)(a5 + 4), &send_buf, a3, 0, &addr, 0x10u);
v14 = (unsigned int)v13;
if ( v13 >= 0 )
{
LABEL_7:
v15 = (const char *)ip_to_str(a2);
alog(6LL, 0LL, "aodv_socket_send", "AODV msg to %s ttl=%d size=%u", v15, a4, v14);
return;
}
v21 = ip_to_str(a2);
v22 = _errno_location();
alog(4LL, (unsigned int)*v22, "aodv_socket_send", "Failed send to %s", v21);
}
}

original_code:
void aodv_socket_send(AODV_msg * aodv_msg, struct in_addr dst,
          int len, u_int8_t ttl, struct dev_info *dev)
{
    int retval = 0;
    struct timeval now;
    struct sockaddr_in dst_addr;
    if (wait_on_reboot && aodv_msg->type == 2)
 return;
    memset(&dst_addr, 0, sizeof(dst_addr));
    dst_addr.sin_family = 2;
    dst_addr.sin_addr = dst;
    dst_addr.sin_port = htons(654);
    if (setsockopt(dev->sock, 0, 2, &ttl, sizeof(ttl)) < 0) {
 alog(4, 0, __FUNCTION__, "ERROR setting ttl!");
 return;
    }
    if (ratelimit) {
 gettimeofday(&now, ((void *)0));
 switch (aodv_msg->type) {
 case 1:
     if (num_rreq == (10 - 1)) {
  if (timeval_diff(&now, &rreq_ratel[0]) < 1000) {
      alog(7, 0, __FUNCTION__, "RATELIMIT: Dropping RREQ %ld ms", timeval_diff(&now, &rreq_ratel[0]));
      return;
  } else {
      memmove(rreq_ratel, &rreq_ratel[1],
       sizeof(struct timeval) * (num_rreq - 1));
      memcpy(&rreq_ratel[num_rreq - 1], &now,
      sizeof(struct timeval));
  }
     } else {
  memcpy(&rreq_ratel[num_rreq], &now, sizeof(struct timeval));
  num_rreq++;
     }
     break;
 case 3:
     if (num_rerr == (10 - 1)) {
  if (timeval_diff(&now, &rerr_ratel[0]) < 1000) {
      alog(7, 0, __FUNCTION__, "RATELIMIT: Dropping RERR %ld ms", timeval_diff(&now, &rerr_ratel[0]));
      return;
  } else {
      memmove(rerr_ratel, &rerr_ratel[1],
       sizeof(struct timeval) * (num_rerr - 1));
      memcpy(&rerr_ratel[num_rerr - 1], &now,
      sizeof(struct timeval));
  }
     } else {
  memcpy(&rerr_ratel[num_rerr], &now, sizeof(struct timeval));
  num_rerr++;
     }
     break;
 }
    }
    if (dst.s_addr == ((in_addr_t) 0xFFFFFFFF)) {
 gettimeofday(&this_host.bcast_time, ((void *)0));
 retval = sendto(dev->sock, send_buf, len, 0,
   (struct sockaddr *) &dst_addr, sizeof(dst_addr));
 if (retval < 0) {
     alog(4, (*__errno_location ()), __FUNCTION__, "Failed send to bc %s",
   ip_to_str(dst));
     return;
 }
    } else {
 retval = sendto(dev->sock, send_buf, len, 0,
   (struct sockaddr *) &dst_addr, sizeof(dst_addr));
 if (retval < 0) {
     alog(4, (*__errno_location ()), __FUNCTION__, "Failed send to %s",
   ip_to_str(dst));
     return;
 }
    }
    if (!(aodv_msg->type == 2 && (dst.s_addr == ((in_addr_t) 0xFFFFFFFF))))
 alog(6, 0, __FUNCTION__, "AODV msg to %s ttl=%d size=%u", ip_to_str(dst), ttl, retval, len);
    return;
}

canonical_original_code:
void aodv_socket_send(struct AODV_msg *aodv_msg, struct in_addr dst, int len, unsigned int ttl, struct dev_info *dev)
{
    int retval = 0;
    struct timeval now;
    struct sockaddr_in dst_addr;
    if (wait_on_reboot && aodv_msg->type == 2)
 return;
    memset(&dst_addr, 0, sizeof(dst_addr));
    dst_addr.sin_family = 2;
    dst_addr.sin_addr = dst;
    dst_addr.sin_port = htons(654);
    if (setsockopt(dev->sock, 0, 2, &ttl, sizeof(ttl)) < 0) {
 alog(4, 0, __FUNCTION__, "ERROR setting ttl!");
 return;
    }
    if (ratelimit) {
 gettimeofday(&now, ((void *)0));
 switch (aodv_msg->type) {
 case 1:
     if (num_rreq == (10 - 1)) {
  if (timeval_diff(&now, &rreq_ratel[0]) < 1000) {
      alog(7, 0, __FUNCTION__, "RATELIMIT: Dropping RREQ %ld ms", timeval_diff(&now, &rreq_ratel[0]));
      return;
  } else {
      memmove(rreq_ratel, &rreq_ratel[1],
       sizeof(struct timeval) * (num_rreq - 1));
      memcpy(&rreq_ratel[num_rreq - 1], &now,
      sizeof(struct timeval));
  }
     } else {
  memcpy(&rreq_ratel[num_rreq], &now, sizeof(struct timeval));
  num_rreq++;
     }
     break;
 case 3:
     if (num_rerr == (10 - 1)) {
  if (timeval_diff(&now, &rerr_ratel[0]) < 1000) {
      alog(7, 0, __FUNCTION__, "RATELIMIT: Dropping RERR %ld ms", timeval_diff(&now, &rerr_ratel[0]));
      return;
  } else {
      memmove(rerr_ratel, &rerr_ratel[1],
       sizeof(struct timeval) * (num_rerr - 1));
      memcpy(&rerr_ratel[num_rerr - 1], &now,
      sizeof(struct timeval));
  }
     } else {
  memcpy(&rerr_ratel[num_rerr], &now, sizeof(struct timeval));
  num_rerr++;
     }
     break;
 }
    }
    if (dst.s_addr == ((unsigned int) 0xFFFFFFFF)) {
 gettimeofday(&this_host.bcast_time, ((void *)0));
 retval = sendto(dev->sock, send_buf, len, 0,
   (struct sockaddr *) &dst_addr, sizeof(dst_addr));
 if (retval < 0) {
     alog(4, (*__errno_location ()), __FUNCTION__, "Failed send to bc %s",
   ip_to_str(dst));
     return;
 }
    } else {
 retval = sendto(dev->sock, send_buf, len, 0,
   (struct sockaddr *) &dst_addr, sizeof(dst_addr));
 if (retval < 0) {
     alog(4, (*__errno_location ()), __FUNCTION__, "Failed send to %s",
   ip_to_str(dst));
     return;
 }
    }
    if (!(aodv_msg->type == 2 && (dst.s_addr == ((unsigned int) 0xFFFFFFFF))))
 alog(6, 0, __FUNCTION__, "AODV msg to %s ttl=%d size=%u", ip_to_str(dst), ttl, retval, len);
    return;
}

variable_types:
ttl
unsigned int

variable_types: struct dev_info { int enabled; int sock; int psock; unsigned int ifindex; char ifname[16]; struct in_addr ipaddr; struct in_addr netmask; struct in_addr broadcast; } *

variable_types: retval int

variable_types: struct timeval { long tv_sec; long tv_usec; }

variable_types: struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr { unsigned int s_addr; } sin_addr; unsigned char sin_zero[-1]; }

user_defined_types: struct sockaddr { unsigned short sa_family; char sa_data[14]; }


decompiled_code:
_DWORD *aodv_socket_new_msg()
{
_DWORD *result; // rax

memset(send_buf, 0, 0x328uLL);
result = send_buf;
send_buf[202] = 0;
return result;
}

canonical_decompiled_code:
_DWORD *func10()
{
_DWORD *result; // rax

memset(send_buf, 0, 0x328uLL);
result = send_buf;
send_buf[202] = 0;
return result;
}

original_code:
AODV_msg * aodv_socket_new_msg(void)
{
    memset(send_buf, '\0', sizeof(RERR) + 100 * sizeof(RERR_udest));
    return (AODV_msg *) (send_buf);
}

canonical_original_code:
struct AODV_msg *aodv_socket_new_msg()
{
    memset(send_buf, '\0', sizeof(RERR) + 100 * sizeof(RERR_udest));
    return (struct AODV_msg *) (send_buf);
}

return_type: struct AODV_msg { unsigned int type; } *


decompiled_code:
int aodv_socket_cleanup()
{
int *v0; // rbx
int result; // eax

v0 = (int *)(unsigned int)((_DWORD)&this_host + 48);
do
{
result = *v0;
if ( *v0 )
result = close(v0[1]);
v0 += 11;
}
while ( v0 != (int *)((char *)&this_host + 488) );
return result;
}

canonical_decompiled_code:
int func11()
{
int *v0; // rbx
int result; // eax

v0 = (int *)(unsigned int)((_DWORD)&this_host + 48);
do
{
result = *v0;
if ( *v0 )
result = close(v0[1]);
v0 += 11;
}
while ( v0 != (int *)((char *)&this_host + 488) );
return result;
}

original_code:
void aodv_socket_cleanup(void)
{
    int i;
    for (i = 0; i < 10; i++) {
 if (!(this_host.devs[i]).enabled)
     continue;
 close((this_host.devs[i]).sock);
    }
}

canonical_original_code:
void aodv_socket_cleanup()
{
    int i;
    for (i = 0; i < 10; i++) {
 if (!(this_host.devs[i]).enabled)
     continue;
 close((this_host.devs[i]).sock);
    }
}

variable_types: i int


canonical_original_code:
static inline long timeval_diff(struct timeval *t1, struct timeval *t2)
{
    long long res;
    if (!t1 || !t2)
 return -1;
    else {
 res = t1->tv_sec;
 res = ((res - t2->tv_sec) * 1000000 + t1->tv_usec - t2->tv_usec) / 1000;
 return (long) res;
    }
}

variable_types: struct timeval { long tv_sec; long tv_usec; } *

variable_types:
res
long long


decompiled_code:
__int64 __fastcall ifindex2devindex(int a1)
{
__int64 v1; // rdx
__int64 result; // rax

v1 = *((int *)&this_host + 11);
if ( (int)v1 <= 0 )
return 10LL;
result = 0LL;
while ( dev_indices[result] != a1 )
{
if ( ++result == v1 )
return 10LL;
}
return (unsigned int)result;
}

canonical_decompiled_code:
__int64 __fastcall func1(int a1)
{
__int64 v1; // rdx
__int64 result; // rax

v1 = *((int *)&this_host + 11);
if ( (int)v1 <= 0 )
return 10LL;
result = 0LL;
while ( dev_indices[result] != a1 )
{
if ( ++result == v1 )
return 10LL;
}
return (unsigned int)result;
}

original_code:
static inline unsigned int ifindex2devindex(unsigned int ifindex)
{
    int i;
    for (i = 0; i < this_host.nif; i++)
 if (dev_indices[i] == ifindex)
     return i;
    return 10;
}

return_type: unsigned int


decompiled_code:
__int64 hello_jitter()
{
__int64 result; // rax

if ( hello_jittering )
result = (unsigned int)(int)(((float)((float)(int)random() * 4.6566129e-10) - 0.5) * 100.0);
else
result = 0LL;
return result;
}

canonical_decompiled_code:
__int64 func3()
{
__int64 result; // rax

if ( hello_jittering )
result = (unsigned int)(int)(((float)((float)(int)random() * 4.6566129e-10) - 0.5) * 100.0);
else
result = 0LL;
return result;
}

original_code:
long hello_jitter()
{
    if (hello_jittering) {
 return (long) (((float) random() / 2147483647 - 0.5) * 100);
    } else
 return 0;
}


decompiled_code:
__int64 hello_stop()
{
alog(7LL, 0LL, "hello_stop", "No active forwarding routes - stopped sending HELLOs!");
return timer_remove(&hello_timer);
}

canonical_decompiled_code:
__int64 func4()
{
alog(7LL, 0LL, "hello_stop", "No active forwarding routes - stopped sending HELLOs!");
return timer_remove(&hello_timer);
}

original_code:
void hello_stop()
{
    alog(7, 0, __FUNCTION__, "No active forwarding routes - stopped sending HELLOs!");
    timer_remove(&hello_timer);
}


decompiled_code:
__int64 hello_send()
{
__int64 v0; // rbx
__int64 v1; // rbp
unsigned __int64 v2; // r14
int v3; // er13
unsigned int v4; // er12
__int64 v5; // rbx
__int64 v6; // rax
__int64 v7; // rdi
__int64 v8; // rdx
unsigned __int8 v9; // cl
__int64 i; // rax
int v11; // esi
__int64 v12; // rsi
__int64 result; // rax
struct timeval v14[3]; // [rsp+0h] [rbp-38h] BYREF

gettimeofday(v14, 0LL);
if ( optimized_hellos && timeval_diff(v14, (_QWORD *)(unsigned int)((_DWORD)&this_host + 24)) > active_route_timeout )
return hello_stop();
v0 = timeval_diff(v14, (_QWORD *)(unsigned int)((_DWORD)&this_host + 8));
v1 = hello_jitter();
if ( v0 <= 999 )
{
v12 = v1 + 1000 - v0;
if ( v12 < 0 )
result = timer_set_timeout(&hello_timer, 1000 - v0 - v1);
else
result = timer_set_timeout(&hello_timer, v12);
}
else
{
v2 = (unsigned int)((_DWORD)&this_host + 48);
v3 = 0;
v4 = 20;
v5 = 0LL;
do
{
if ( *(_DWORD *)v2 )
{
v6 = rrep_create(0LL, 0LL, 0LL, *((unsigned int *)&this_host + 11 * v3 + 20), LODWORD(this_host.tv_sec));
v7 = v6;
if ( unidir_hack )
{
if ( v5 )
v5 += *(unsigned __int8 *)(v5 + 1) + 2LL;
else
v5 = v6 + 20;
v8 = (unsigned int)((_DWORD)&rt_tbl + 8);
v9 = 0;
*(_WORD *)v5 = 3;
do
{
for ( i = *(_QWORD *)(v8 + 8); v8 != i; i = *(_QWORD *)(i + 8) )
{
if ( *(_DWORD *)(i + 168) )
{
v11 = *(_DWORD *)(i + 16);
v9 += 4;
*(_BYTE *)(v5 + 1) = v9;
*(_DWORD *)(v5 + 2) = v11;
}
}
v8 += 16LL;
}
while ( (_UNKNOWN *)v8 != (_UNKNOWN *)((char *)&rt_tbl + 1032) );
if ( v9 )
v4 = v9 + 22;
}
aodv_socket_send(v7, 0xFFFFFFFFLL, v4, 1LL, v2);
}
++v3;
v2 += 44LL;
}
while ( v3 != 10 );
result = timer_set_timeout(&hello_timer, v1 + 1000);
}
return result;
}

canonical_decompiled_code:
__int64 func5()
{
__int64 v0; // rbx
__int64 v1; // rbp
unsigned __int64 v2; // r14
int v3; // er13
unsigned int v4; // er12
__int64 v5; // rbx
__int64 v6; // rax
__int64 v7; // rdi
__int64 v8; // rdx
unsigned __int8 v9; // cl
__int64 i; // rax
int v11; // esi
__int64 v12; // rsi
__int64 result; // rax
struct timeval v14[3]; // [rsp+0h] [rbp-38h] BYREF

gettimeofday(v14, 0LL);
if ( optimized_hellos && func0(v14, (_QWORD *)(unsigned int)((_DWORD)&this_host + 24)) > active_route_timeout )
return func4();
v0 = func0(v14, (_QWORD *)(unsigned int)((_DWORD)&this_host + 8));
v1 = func3();
if ( v0 <= 999 )
{
v12 = v1 + 1000 - v0;
if ( v12 < 0 )
result = timer_set_timeout(&hello_timer, 1000 - v0 - v1);
else
result = timer_set_timeout(&hello_timer, v12);
}
else
{
v2 = (unsigned int)((_DWORD)&this_host + 48);
v3 = 0;
v4 = 20;
v5 = 0LL;
do
{
if ( *(_DWORD *)v2 )
{
v6 = rrep_create(0LL, 0LL, 0LL, *((unsigned int *)&this_host + 11 * v3 + 20), LODWORD(this_host.tv_sec));
v7 = v6;
if ( unidir_hack )
{
if ( v5 )
v5 += *(unsigned __int8 *)(v5 + 1) + 2LL;
else
v5 = v6 + 20;
v8 = (unsigned int)((_DWORD)&rt_tbl + 8);
v9 = 0;
*(_WORD *)v5 = 3;
do
{
for ( i = *(_QWORD *)(v8 + 8); v8 != i; i = *(_QWORD *)(i + 8) )
{
if ( *(_DWORD *)(i + 168) )
{
v11 = *(_DWORD *)(i + 16);
v9 += 4;
*(_BYTE *)(v5 + 1) = v9;
*(_DWORD *)(v5 + 2) = v11;
}
}
v8 += 16LL;
}
while ( (_UNKNOWN *)v8 != (_UNKNOWN *)((char *)&rt_tbl + 1032) );
if ( v9 )
v4 = v9 + 22;
}
aodv_socket_send(v7, 0xFFFFFFFFLL, v4, 1LL, v2);
}
++v3;
v2 += 44LL;
}
while ( v3 != 10 );
result = timer_set_timeout(&hello_timer, v1 + 1000);
}
return result;
}

original_code:
void hello_send(void *arg)
{
    RREP *rrep;
    AODV_ext *ext = ((void *)0);
    u_int8_t flags = 0;
    struct in_addr dest;
    long time_diff, jitter;
    struct timeval now;
    int msg_size = sizeof(RREP);
    int i;
    gettimeofday(&now, ((void *)0));
    if (optimized_hellos &&
 timeval_diff(&now, &this_host.fwd_time) > active_route_timeout) {
 hello_stop();
 return;
    }
    time_diff = timeval_diff(&now, &this_host.bcast_time);
    jitter = hello_jitter();
    if (time_diff >= 1000) {
 for (i = 0; i < 10; i++) {
     if (!(this_host.devs[i]).enabled)
  continue;
     rrep = rrep_create(flags, 0, 0, (this_host.devs[i]).ipaddr,
          this_host.seqno,
          (this_host.devs[i]).ipaddr,
          2 * 1000);
     if (unidir_hack) {
  int i;
  if (ext)
      ext = ((AODV_ext *)((char *)ext + sizeof(AODV_ext) + ext->length));
  else
      ext = (AODV_ext *) ((char *) rrep + sizeof(RREP));
  ext->type = 3;
  ext->length = 0;
  for (i = 0; i < 64; i++) {
      list_t *pos;
      for (pos = (&rt_tbl.tbl[i])->next; pos != (&rt_tbl.tbl[i]); pos = pos->next) {
   rt_table_t *rt = (rt_table_t *) pos;
   if (rt->hello_timer.used) {
       memcpy(((char *)((char *)ext + sizeof(AODV_ext))), &rt->dest_addr,
       sizeof(struct in_addr));
       ext->length += sizeof(struct in_addr);
   }
      }
  }
  if (ext->length)
      msg_size = sizeof(RREP) + (sizeof(AODV_ext) + ext->length);
     }
     dest.s_addr = ((in_addr_t) 0xFFFFFFFF);
     aodv_socket_send((AODV_msg *) rrep, dest, msg_size, 1, &(this_host.devs[i]));
 }
 timer_set_timeout(&hello_timer, 1000 + jitter);
    } else {
 if (1000 - time_diff + jitter < 0)
     timer_set_timeout(&hello_timer,
         1000 - time_diff - jitter);
 else
     timer_set_timeout(&hello_timer,
         1000 - time_diff + jitter);
    }
}

canonical_original_code:
void hello_send(void *arg)
{
    struct RREP *rrep;
    struct AODV_ext *ext = ((void *)0);
    unsigned int flags = 0;
    struct in_addr dest;
    long time_diff; long jitter;
    struct timeval now;
    int msg_size = sizeof(RREP);
    int i;
    gettimeofday(&now, ((void *)0));
    if (optimized_hellos &&
 timeval_diff(&now, &this_host.fwd_time) > active_route_timeout) {
 hello_stop();
 return;
    }
    time_diff = timeval_diff(&now, &this_host.bcast_time);
    jitter = hello_jitter();
    if (time_diff >= 1000) {
 for (i = 0; i < 10; i++) {
     if (!(this_host.devs[i]).enabled)
  continue;
     rrep = rrep_create(flags, 0, 0, (this_host.devs[i]).ipaddr,
          this_host.seqno,
          (this_host.devs[i]).ipaddr,
          2 * 1000);
     if (unidir_hack) {
  int i;
  if (ext)
      ext = ((struct AODV_ext *)((char *)ext + sizeof(AODV_ext) + ext->length));
  else
      ext = (struct AODV_ext *) ((char *) rrep + sizeof(RREP));
  ext->type = 3;
  ext->length = 0;
  for (i = 0; i < 64; i++) {
      struct list_t *pos;
      for (pos = (&rt_tbl.tbl[i])->next; pos != (&rt_tbl.tbl[i]); pos = pos->next) {
   struct rt_table *rt = (rt_table_t *) pos;
   if (rt->hello_timer.used) {
       memcpy(((char *)((char *)ext + sizeof(AODV_ext))), &rt->dest_addr,
       sizeof(struct in_addr));
       ext->length += sizeof(struct in_addr);
   }
      }
  }
  if (ext->length)
      msg_size = sizeof(RREP) + (sizeof(AODV_ext) + ext->length);
     }
     dest.s_addr = ((unsigned int) 0xFFFFFFFF);
     aodv_socket_send((struct AODV_msg *) rrep, dest, msg_size, 1, &(this_host.devs[i]));
 }
 timer_set_timeout(&hello_timer, 1000 + jitter);
    } else {
 if (1000 - time_diff + jitter < 0)
     timer_set_timeout(&hello_timer,
         1000 - time_diff - jitter);
 else
     timer_set_timeout(&hello_timer,
         1000 - time_diff + jitter);
    }
}

variable_types:
arg
void *

variable_types: struct RREP { unsigned int type; unsigned int res1; unsigned int a; unsigned int r; unsigned int prefix; unsigned int res2; unsigned int hcnt; unsigned int dest_addr; unsigned int dest_seqno; unsigned int orig_addr; unsigned int lifetime; } *

variable_types: struct AODV_ext { unsigned int type; unsigned int length; } *

variable_types:
flags
unsigned int

variable_types:
dest
struct in_addr { unsigned int s_addr; }

variable_types: jitter long

variable_types: struct list_t { struct list_t *prev; } *

variable_types: struct rt_table { struct list_t { struct list_t *prev; } l; struct in_addr { unsigned int s_addr; } dest_addr; unsigned int dest_seqno; unsigned int ifindex; struct in_addr next_hop; unsigned int hcnt; unsigned int flags; unsigned int state; struct timer { struct list_t l; int used; struct timeval { long tv_sec; long tv_usec; } timeout; void (*handler)(void *); void *data; } rt_timer; struct timer ack_timer; struct timer hello_timer; struct timeval last_hello_time; unsigned int hello_cnt; unsigned int hash; int nprec; struct list_t precursors; } *

user_defined_types: struct rt_table { struct list_t l; struct in_addr dest_addr; unsigned int dest_seqno; unsigned int ifindex; struct in_addr next_hop; unsigned int hcnt; unsigned int flags; unsigned int state; struct timer rt_timer; struct timer ack_timer; struct timer hello_timer; struct timeval last_hello_time; unsigned int hello_cnt; unsigned int hash; int nprec; struct list_t precursors; }

user_defined_types: struct timer { struct list_t l; int used; struct timeval timeout; void (*handler)(void *); void *data; }


decompiled_code:
__int64 hello_start()
{
__int64 result; // rax

result = (unsigned int)dword_E30;
if ( !dword_E30 )
{
gettimeofday((struct timeval *)(unsigned int)((_DWORD)&this_host + 24), 0LL);
alog(7LL, 0LL, "hello_start", "Starting to send HELLOs!");
timer_init(&hello_timer, hello_send, 0LL);
result = hello_send(0LL);
}
return result;
}

canonical_decompiled_code:
__int64 func6()
{
__int64 result; // rax

result = (unsigned int)dword_E30;
if ( !dword_E30 )
{
gettimeofday((struct timeval *)(unsigned int)((_DWORD)&this_host + 24), 0LL);
alog(7LL, 0LL, "hello_start", "Starting to send HELLOs!");
timer_init(&hello_timer, hello_send, 0LL);
result = func5(0LL);
}
return result;
}

original_code:
void hello_start()
{
    if (hello_timer.used)
 return;
    gettimeofday(&this_host.fwd_time, ((void *)0));
    alog(7, 0, __FUNCTION__, "Starting to send HELLOs!");
    timer_init(&hello_timer, & hello_send, ((void *)0));
    hello_send(((void *)0));
}


decompiled_code:
__int64 __fastcall hello_process(__int64 a1, int a2, int a3)
{
unsigned __int8 v3; // r15
int v4; // er14
unsigned int v6; // ebx
__int64 v7; // rax
__int64 v8; // rbp
unsigned __int8 *v9; // r13
unsigned int v10; // ebx
__int64 v11; // r8
__int64 v12; // r9
int v13; // edi
unsigned int v14; // eax
int v15; // esi
unsigned __int8 *v16; // rax
__int64 v17; // r8
__int64 v18; // rdx
char v19; // r15
__int64 result; // rax
__int64 v21; // r8
char v22; // r9
__int64 v23; // rax
unsigned int v24; // [rsp+8h] [rbp-50h]
unsigned int v25; // [rsp+Ch] [rbp-4Ch]
struct timeval tv; // [rsp+10h] [rbp-48h] BYREF

v3 = 0;
v4 = a2;
gettimeofday(&tv, 0LL);
v6 = *(_DWORD *)(a1 + 4);
v25 = v6;
v24 = _bswap_32(*(_DWORD *)(a1 + 8));
v7 = rt_table_find(v6);
v8 = v7;
if ( v7 )
v3 = *(_BYTE *)(v7 + 34);
if ( unidir_hack )
v3 |= 1u;
v9 = (unsigned __int8 *)(a1 + 20);
if ( a2 > 20 )
{
v10 = 1000;
while ( 1 )
{
v11 = *v9;
v12 = v9[1];
if ( (_BYTE)v11 == 2 )
{
if ( (_BYTE)v12 == 4 )
{
v13 = 4;
v10 = _bswap_32(*(_DWORD *)(v9 + 2));
}
else
{
alog(4LL, 0LL, "hello_process", "Bad hello interval extension!");
v13 = v9[1];
v12 = v9[1];
}
}
else
{
if ( (_BYTE)v11 != 3 )
{
alog(4LL, 0LL, "hello_process", "Bad extension!! type=%d, length=%d", v11, v12);
v17 = 2 * v10 + 100;
goto LABEL_17;
}
v13 = 0;
if ( (_BYTE)v12 )
{
v14 = ifindex2devindex(a3);
v13 = (unsigned __int8)v12;
v15 = *((_DWORD *)&this_host + 11 * v14 + 20);
v16 = v9 + 2;
do
{
if ( *(_DWORD *)v16 == v15 )
v3 &= 0xFEu;
v16 += 4;
}
while ( &v9[4 * (((unsigned int)(unsigned __int8)v12 - 1) >> 2) + 6] != v16 );
}
}
v9 += v12 + 2;
v4 = v4 - 2 - v13;
if ( v4 <= 20 )
{
v17 = 2 * v10 + 100;
goto LABEL_17;
}
}
}
v17 = 2100LL;
v10 = 1000;
LABEL_17:
v18 = v3;
v19 = v3 & 1;
if ( !v8 )
{
v8 = rt_table_insert(v25, v25, 1LL, v24, v17, receive_n_hellos == 0, v18);
v23 = ip_to_str(*(unsigned int *)(v8 + 16));
if ( v19 )
alog(6LL, 0LL, "hello_process", "%s new NEIGHBOR, link UNI-DIR", v23);
else
alog(6LL, 0LL, "hello_process", "%s new NEIGHBOR!", v23);
*(_BYTE *)(v8 + 224) = 1;
return hello_update_timeout(v8, &tv, 2 * v10);
}
if ( v19 && *(_BYTE *)(v8 + 36) == 1 && *(_BYTE *)(v8 + 32) > 1u )
return hello_update_timeout(v8, &tv, 2 * v10);
if ( !receive_n_hellos || *(unsigned __int8 *)(v8 + 224) >= receive_n_hellos - 1 )
{
rt_table_update(v8, v25, 1LL, v24, v17, 1LL, v18);
return hello_update_timeout(v8, &tv, 2 * v10);
}
v21 = timeval_diff(&tv, (_QWORD *)(v8 + 208));
*(__m128i *)(v8 + 208) = _mm_loadu_si128((const __m128i *)&tv);
result = 1LL;
if ( v21 >= v10 + (v10 >> 1) )
v22 = 1;
*(_BYTE *)(v8 + 224) = v22;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, int a2, int a3)
{
unsigned __int8 v3; // r15
int v4; // er14
unsigned int v6; // ebx
__int64 v7; // rax
__int64 v8; // rbp
unsigned __int8 *v9; // r13
unsigned int v10; // ebx
__int64 v11; // r8
__int64 v12; // r9
int v13; // edi
unsigned int v14; // eax
int v15; // esi
unsigned __int8 *v16; // rax
__int64 v17; // r8
__int64 v18; // rdx
char v19; // r15
__int64 result; // rax
__int64 v21; // r8
char v22; // r9
__int64 v23; // rax
unsigned int v24; // [rsp+8h] [rbp-50h]
unsigned int v25; // [rsp+Ch] [rbp-4Ch]
struct timeval tv; // [rsp+10h] [rbp-48h] BYREF

v3 = 0;
v4 = a2;
gettimeofday(&tv, 0LL);
v6 = *(_DWORD *)(a1 + 4);
v25 = v6;
v24 = func2(*(_DWORD *)(a1 + 8));
v7 = rt_table_find(v6);
v8 = v7;
if ( v7 )
v3 = *(_BYTE *)(v7 + 34);
if ( unidir_hack )
v3 |= 1u;
v9 = (unsigned __int8 *)(a1 + 20);
if ( a2 > 20 )
{
v10 = 1000;
while ( 1 )
{
v11 = *v9;
v12 = v9[1];
if ( (_BYTE)v11 == 2 )
{
if ( (_BYTE)v12 == 4 )
{
v13 = 4;
v10 = func2(*(_DWORD *)(v9 + 2));
}
else
{
alog(4LL, 0LL, "hello_process", "Bad hello interval extension!");
v13 = v9[1];
v12 = v9[1];
}
}
else
{
if ( (_BYTE)v11 != 3 )
{
alog(4LL, 0LL, "hello_process", "Bad extension!! type=%d, length=%d", v11, v12);
v17 = 2 * v10 + 100;
goto LABEL_17;
}
v13 = 0;
if ( (_BYTE)v12 )
{
v14 = func1(a3);
v13 = (unsigned __int8)v12;
v15 = *((_DWORD *)&this_host + 11 * v14 + 20);
v16 = v9 + 2;
do
{
if ( *(_DWORD *)v16 == v15 )
v3 &= 0xFEu;
v16 += 4;
}
while ( &v9[4 * (((unsigned int)(unsigned __int8)v12 - 1) >> 2) + 6] != v16 );
}
}
v9 += v12 + 2;
v4 = v4 - 2 - v13;
if ( v4 <= 20 )
{
v17 = 2 * v10 + 100;
goto LABEL_17;
}
}
}
v17 = 2100LL;
v10 = 1000;
LABEL_17:
v18 = v3;
v19 = v3 & 1;
if ( !v8 )
{
v8 = rt_table_insert(v25, v25, 1LL, v24, v17, receive_n_hellos == 0, v18);
v23 = ip_to_str(*(unsigned int *)(v8 + 16));
if ( v19 )
alog(6LL, 0LL, "hello_process", "%s new NEIGHBOR, link UNI-DIR", v23);
else
alog(6LL, 0LL, "hello_process", "%s new NEIGHBOR!", v23);
*(_BYTE *)(v8 + 224) = 1;
return hello_update_timeout(v8, &tv, 2 * v10);
}
if ( v19 && *(_BYTE *)(v8 + 36) == 1 && *(_BYTE *)(v8 + 32) > 1u )
return hello_update_timeout(v8, &tv, 2 * v10);
if ( !receive_n_hellos || *(unsigned __int8 *)(v8 + 224) >= receive_n_hellos - 1 )
{
rt_table_update(v8, v25, 1LL, v24, v17, 1LL, v18);
return hello_update_timeout(v8, &tv, 2 * v10);
}
v21 = func0(&tv, (_QWORD *)(v8 + 208));
*(__m128i *)(v8 + 208) = _mm_loadu_si128((const __m128i *)&tv);
result = 1LL;
if ( v21 >= v10 + (v10 >> 1) )
v22 = 1;
*(_BYTE *)(v8 + 224) = v22;
return result;
}

original_code:
void hello_process(RREP * hello, int rreplen, unsigned int ifindex)
{
    u_int32_t hello_seqno, timeout, hello_interval = 1000;
    u_int8_t state, flags = 0;
    struct in_addr ext_neighbor, hello_dest;
    rt_table_t *rt;
    AODV_ext *ext = ((void *)0);
    int i;
    struct timeval now;
    gettimeofday(&now, ((void *)0));
    hello_dest.s_addr = hello->dest_addr;
    hello_seqno = ntohl(hello->dest_seqno);
    rt = rt_table_find(hello_dest);
    if (rt)
 flags = rt->flags;
    if (unidir_hack)
 flags |= 0x1;
    ext = (AODV_ext *) ((char *) hello + sizeof(RREP));
    while (rreplen > (int) sizeof(RREP)) {
 switch (ext->type) {
 case 2:
     if (ext->length == 4) {
  memcpy(&hello_interval, ((char *)((char *)ext + sizeof(AODV_ext))), 4);
  hello_interval = ntohl(hello_interval);
     } else
  alog(4, 0,
       __FUNCTION__, "Bad hello interval extension!");
     break;
 case 3:
     for (i = 0; i < ext->length; i = i + 4) {
  ext_neighbor.s_addr =
      *(in_addr_t *) ((char *) ((char *)((char *)ext + sizeof(AODV_ext))) + i);
  if (ext_neighbor.s_addr == (this_host.devs[ifindex2devindex(ifindex)]).ipaddr.s_addr)
      flags &= ~0x1;
     }
     break;
 default:
     alog(4, 0, __FUNCTION__,
   "Bad extension!! type=%d, length=%d", ext->type, ext->length);
     ext = ((void *)0);
     break;
 }
 if (ext == ((void *)0))
     break;
 rreplen -= (sizeof(AODV_ext) + ext->length);
 ext = ((AODV_ext *)((char *)ext + sizeof(AODV_ext) + ext->length));
    }
    if (receive_n_hellos)
 state = 0;
    else
 state = 1;
    timeout = 2 * hello_interval + 100;
    if (!rt) {
 rt = rt_table_insert(hello_dest, hello_dest, 1,
        hello_seqno, timeout, state, flags, ifindex);
 if (flags & 0x1) {
     alog(6, 0, __FUNCTION__, "%s new NEIGHBOR, link UNI-DIR", ip_to_str(rt->dest_addr));
 } else {
     alog(6, 0, __FUNCTION__, "%s new NEIGHBOR!", ip_to_str(rt->dest_addr));
 }
 rt->hello_cnt = 1;
    } else {
 if ((flags & 0x1) && rt->state == 1 && rt->hcnt > 1) {
     goto hello_update;
 }
 if (receive_n_hellos && rt->hello_cnt < (receive_n_hellos - 1)) {
     if (timeval_diff(&now, &rt->last_hello_time) <
  (long) (hello_interval + hello_interval / 2))
  rt->hello_cnt++;
     else
  rt->hello_cnt = 1;
     memcpy(&rt->last_hello_time, &now, sizeof(struct timeval));
     return;
 }
 rt_table_update(rt, hello_dest, 1, hello_seqno, timeout, 1, flags);
    }
  hello_update:
    hello_update_timeout(rt, &now, 2 * hello_interval);
    return;
}

canonical_original_code:
void hello_process(struct RREP *hello, int rreplen, unsigned int ifindex)
{
    unsigned int hello_seqno; unsigned int timeout; unsigned int hello_interval = 1000;
    unsigned int state; unsigned int flags = 0;
    struct in_addr ext_neighbor; struct in_addr hello_dest;
    struct rt_table *rt;
    struct AODV_ext *ext = ((void *)0);
    int i;
    struct timeval now;
    gettimeofday(&now, ((void *)0));
    hello_dest.s_addr = hello->dest_addr;
    hello_seqno = ntohl(hello->dest_seqno);
    rt = rt_table_find(hello_dest);
    if (rt)
 flags = rt->flags;
    if (unidir_hack)
 flags |= 0x1;
    ext = (struct AODV_ext *) ((char *) hello + sizeof(RREP));
    while (rreplen > (int) sizeof(RREP)) {
 switch (ext->type) {
 case 2:
     if (ext->length == 4) {
  memcpy(&hello_interval, ((char *)((char *)ext + sizeof(AODV_ext))), 4);
  hello_interval = ntohl(hello_interval);
     } else
  alog(4, 0,
       __FUNCTION__, "Bad hello interval extension!");
     break;
 case 3:
     for (i = 0; i < ext->length; i = i + 4) {
  ext_neighbor.s_addr =
      *(unsigned int *) ((char *) ((char *)((char *)ext + sizeof(AODV_ext))) + i);
  if (ext_neighbor.s_addr == (this_host.devs[ifindex2devindex(ifindex)]).ipaddr.s_addr)
      flags &= ~0x1;
     }
     break;
 default:
     alog(4, 0, __FUNCTION__,
   "Bad extension!! type=%d, length=%d", ext->type, ext->length);
     ext = ((void *)0);
     break;
 }
 if (ext == ((void *)0))
     break;
 rreplen -= (sizeof(AODV_ext) + ext->length);
 ext = ((struct AODV_ext *)((char *)ext + sizeof(AODV_ext) + ext->length));
    }
    if (receive_n_hellos)
 state = 0;
    else
 state = 1;
    timeout = 2 * hello_interval + 100;
    if (!rt) {
 rt = rt_table_insert(hello_dest, hello_dest, 1,
        hello_seqno, timeout, state, flags, ifindex);
 if (flags & 0x1) {
     alog(6, 0, __FUNCTION__, "%s new NEIGHBOR, link UNI-DIR", ip_to_str(rt->dest_addr));
 } else {
     alog(6, 0, __FUNCTION__, "%s new NEIGHBOR!", ip_to_str(rt->dest_addr));
 }
 rt->hello_cnt = 1;
    } else {
 if ((flags & 0x1) && rt->state == 1 && rt->hcnt > 1) {
     goto hello_update;
 }
 if (receive_n_hellos && rt->hello_cnt < (receive_n_hellos - 1)) {
     if (timeval_diff(&now, &rt->last_hello_time) <
  (long) (hello_interval + hello_interval / 2))
  rt->hello_cnt++;
     else
  rt->hello_cnt = 1;
     memcpy(&rt->last_hello_time, &now, sizeof(struct timeval));
     return;
 }
 rt_table_update(rt, hello_dest, 1, hello_seqno, timeout, 1, flags);
    }
  hello_update:
    hello_update_timeout(rt, &now, 2 * hello_interval);
    return;
}

variable_types: rreplen int

variable_types:
ifindex
unsigned int

variable_types:
timeout
unsigned int

variable_types:
state
unsigned int

user_defined_types: struct timeval { long tv_sec; long tv_usec; }


decompiled_code:
__int64 __fastcall timeval_diff(_QWORD *a1, _QWORD *a2)
{
__int64 result; // rax

if ( a2 )
result = (a1[1] + 1000000LL * (*a1 - *a2) - a2[1]) / 1000;
else
result = -1LL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(_QWORD *a1, _QWORD *a2)
{
__int64 result; // rax

if ( a2 )
result = (a1[1] + 1000000LL * (*a1 - *a2) - a2[1]) / 1000;
else
result = -1LL;
return result;
}


original_code:
int timer_init(struct timer *t, timeout_func_t f, void *data)
{
    if (!t)
 return -1;
    do { (&t->l)->next = ((void *)0); (&t->l)->prev = ((void *)0); } while (0);
    t->handler = f;
    t->data = data;
    t->timeout.tv_sec = 0;
    t->timeout.tv_usec = 0;
    t->used = 0;
    return 0;
}

canonical_original_code:
int timer_init(struct timer *t, void (*f)(void *), void *data)
{
    if (!t)
 return -1;
    do { (&t->l)->next = ((void *)0); (&t->l)->prev = ((void *)0); } while (0);
    t->handler = f;
    t->data = data;
    t->timeout.tv_sec = 0;
    t->timeout.tv_usec = 0;
    t->used = 0;
    return 0;
}

variable_types: struct timer { struct list_t { struct list_t *prev; } l; int used; struct timeval { long tv_sec; long tv_usec; } timeout; void (*handler)(void *); void *data; } *

variable_types:
f
void (*)(void *)

variable_types:
data
void *


decompiled_code:
__int64 __fastcall timer_remove(__int64 a1)
{
__int64 result; // rax

if ( !a1 )
return 0xFFFFFFFFLL;
if ( *(_QWORD *)(a1 + 8) || (result = 0LL, *(_QWORD *)a1) )
{
list_detach(a1);
*(_DWORD *)(a1 + 16) = 0;
result = 1LL;
}
else
{
*(_DWORD *)(a1 + 16) = 0;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
__int64 result; // rax

if ( !a1 )
return 0xFFFFFFFFLL;
if ( *(_QWORD *)(a1 + 8) || (result = 0LL, *(_QWORD *)a1) )
{
list_detach(a1);
*(_DWORD *)(a1 + 16) = 0;
result = 1LL;
}
else
{
*(_DWORD *)(a1 + 16) = 0;
}
return result;
}

original_code:
int timer_remove(struct timer *t)
{
    int res = 1;
    if (!t)
 return -1;
    if (((&t->l)->next == ((void *)0) && (&t->l)->prev == ((void *)0)))
 res = 0;
    else
 list_detach(&t->l);
    t->used = 0;
    return res;
}

variable_types: res int


decompiled_code:
__int64 __fastcall timer_add(__int64 a1)
{
void **v2; // r8
_QWORD *v3; // rdi

if ( !a1 )
{
perror("NULL timer!!!\n");
exit(-1);
}
if ( !*(_QWORD *)(a1 + 40) )
{
perror("NULL handler!!!\n");
exit(-1);
}
if ( *(_DWORD *)(a1 + 16) )
timer_remove(a1);
v2 = off_418;
*(_DWORD *)(a1 + 16) = 1;
v3 = (_QWORD *)(a1 + 24);
if ( v2 == &TQ )
return list_add(&TQ, a1);
do
{
if ( timeval_diff(v3, v2 + 3) < 0 )
break;
v2 = (void **)v2[1];
}
while ( v2 != &TQ );
return list_add(*v2, a1);
}

original_code:
static void timer_add(struct timer *t)
{
    list_t *pos;
    if (!t) {
 perror("NULL timer!!!\n");
 exit(-1);
    }
    if (!t->handler) {
 perror("NULL handler!!!\n");
 exit(-1);
    }
    if (t->used)
 timer_remove(t);
    t->used = 1;
    if (((&TQ) == (&TQ)->next)) {
 list_add(&TQ, &t->l);
    } else {
 for (pos = (&TQ)->next; pos != (&TQ); pos = pos->next) {
     struct timer *curr = (struct timer *) pos;
     if (timeval_diff(&t->timeout, &curr->timeout) < 0) {
  break;
     }
 }
 list_add(pos->prev, &t->l);
    }
    return;
}

canonical_original_code:
static void timer_add(struct timer *t)
{
    struct list_t *pos;
    if (!t) {
 perror("NULL timer!!!\n");
 exit(-1);
    }
    if (!t->handler) {
 perror("NULL handler!!!\n");
 exit(-1);
    }
    if (t->used)
 timer_remove(t);
    t->used = 1;
    if (((&TQ) == (&TQ)->next)) {
 list_add(&TQ, &t->l);
    } else {
 for (pos = (&TQ)->next; pos != (&TQ); pos = pos->next) {
     struct timer *curr = (struct timer *) pos;
     if (timeval_diff(&t->timeout, &curr->timeout) < 0) {
  break;
     }
 }
 list_add(pos->prev, &t->l);
    }
    return;
}


decompiled_code:
__int64 __fastcall timer_timeout_now(__int64 a1)
{
int v1; // er8
__int64 result; // rax

v1 = timer_remove(a1);
result = 0xFFFFFFFFLL;
if ( v1 )
{
(*(void (__fastcall **)(_QWORD))(a1 + 40))(*(_QWORD *)(a1 + 48));
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
int v1; // er8
__int64 result; // rax

v1 = func3(a1);
result = 0xFFFFFFFFLL;
if ( v1 )
{
(*(void (__fastcall **)(_QWORD))(a1 + 40))(*(_QWORD *)(a1 + 48));
result = 1LL;
}
return result;
}

original_code:
int timer_timeout_now(struct timer *t)
{
    if (timer_remove(t)) {
 t->handler(t->data);
 return 1;
    }
    return -1;
}


decompiled_code:
__int64 __fastcall timer_set_timeout(__int64 a1, __int64 a2)
{
__int64 v2; // rsi

if ( *(_DWORD *)(a1 + 16) )
{
timer_remove(a1);
gettimeofday((struct timeval *)(a1 + 24), 0LL);
if ( a2 >= 0 )
goto LABEL_3;
LABEL_5:
alog(4LL, 0LL, "timer_set_timeout", "Negative timeout!!!");
goto LABEL_3;
}
gettimeofday((struct timeval *)(a1 + 24), 0LL);
if ( a2 < 0 )
goto LABEL_5;
LABEL_3:
v2 = *(_QWORD *)(a1 + 32) + 1000 * a2;
*(_QWORD *)(a1 + 24) += v2 / 1000000;
*(_QWORD *)(a1 + 32) = v2 % 1000000;
return timer_add(a1);
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2)
{
__int64 v2; // rsi

if ( *(_DWORD *)(a1 + 16) )
{
func3(a1);
gettimeofday((struct timeval *)(a1 + 24), 0LL);
if ( a2 >= 0 )
goto LABEL_3;
LABEL_5:
alog(4LL, 0LL, "timer_set_timeout", "Negative timeout!!!");
goto LABEL_3;
}
gettimeofday((struct timeval *)(a1 + 24), 0LL);
if ( a2 < 0 )
goto LABEL_5;
LABEL_3:
v2 = *(_QWORD *)(a1 + 32) + 1000 * a2;
*(_QWORD *)(a1 + 24) += v2 / 1000000;
*(_QWORD *)(a1 + 32) = v2 % 1000000;
return func4(a1);
}

original_code:
void timer_set_timeout(struct timer *t, long msec)
{
    if (t->used) {
 timer_remove(t);
    }
    gettimeofday(&t->timeout, ((void *)0));
    if (msec < 0)
 alog(4, 0, __FUNCTION__, "Negative timeout!!!");
    t->timeout.tv_usec += msec * 1000;
    t->timeout.tv_sec += t->timeout.tv_usec / 1000000;
    t->timeout.tv_usec = t->timeout.tv_usec % 1000000;
    timer_add(t);
}

variable_types: msec long


decompiled_code:
__int64 __fastcall timer_left(__int64 a1)
{
struct timeval v2; // [rsp-18h] [rbp-18h] BYREF

if ( !a1 )
return -1LL;
gettimeofday(&v2, 0LL);
return timeval_diff(&v2, (_QWORD *)(a1 + 24));
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1)
{
struct timeval v2; // [rsp-18h] [rbp-18h] BYREF

if ( !a1 )
return -1LL;
gettimeofday(&v2, 0LL);
return func0(&v2, (_QWORD *)(a1 + 24));
}

original_code:
long timer_left(struct timer *t)
{
    struct timeval now;
    if (!t)
 return -1;
    gettimeofday(&now, ((void *)0));
    return timeval_diff(&now, &t->timeout);
}

variable_types: struct timeval { long tv_sec; long tv_usec; }


decompiled_code:
__int64 *timer_age_queue()
{
char *v0; // rax
char *v1; // rdx
__int64 *result; // rax
struct timeval v3; // [rsp+0h] [rbp-18h] BYREF

gettimeofday(&v3, 0LL);
fflush(stdout);
if ( off_418 == &TQ )
return 0LL;
timer_timeout(&v3);
if ( off_418 == &TQ )
return 0LL;
v0 = (char *)off_418[4] - v3.tv_usec;
v1 = (char *)off_418[3] - v3.tv_sec;
qword_688 = (__int64)v0;
remaining_0 = (__int64)v1;
if ( (__int64)v0 >= 0 )
return &remaining_0;
qword_688 = (__int64)(v0 + 1000000);
result = &remaining_0;
remaining_0 = (__int64)(v1 - 1);
return result;
}

canonical_decompiled_code:
__int64 *func8()
{
char *v0; // rax
char *v1; // rdx
__int64 *result; // rax
struct timeval v3; // [rsp+0h] [rbp-18h] BYREF

gettimeofday(&v3, 0LL);
fflush(stdout);
if ( off_418 == &TQ )
return 0LL;
func2(&v3);
if ( off_418 == &TQ )
return 0LL;
v0 = (char *)off_418[4] - v3.tv_usec;
v1 = (char *)off_418[3] - v3.tv_sec;
qword_688 = (__int64)v0;
remaining_0 = (__int64)v1;
if ( (__int64)v0 >= 0 )
return &remaining_0;
qword_688 = (__int64)(v0 + 1000000);
result = &remaining_0;
remaining_0 = (__int64)(v1 - 1);
return result;
}

original_code:
struct timeval * timer_age_queue()
{
    struct timeval now;
    struct timer *t;
    static struct timeval remaining;
    gettimeofday(&now, ((void *)0));
    fflush(stdout);
    if (((&TQ) == (&TQ)->next))
 return ((void *)0);
    timer_timeout(&now);
    if (((&TQ) == (&TQ)->next))
 return ((void *)0);
    t = (struct timer *) TQ.next;
    remaining.tv_usec = (t->timeout.tv_usec - now.tv_usec);
    remaining.tv_sec = (t->timeout.tv_sec - now.tv_sec);
    if (remaining.tv_usec < 0) {
 remaining.tv_usec += 1000000;
 remaining.tv_sec -= 1;
    }
    return (&remaining);
}

canonical_original_code:
struct timeval *timer_age_queue()
{
    struct timeval now;
    struct timer *t;
    static struct timeval remaining;
    gettimeofday(&now, ((void *)0));
    fflush(stdout);
    if (((&TQ) == (&TQ)->next))
 return ((void *)0);
    timer_timeout(&now);
    if (((&TQ) == (&TQ)->next))
 return ((void *)0);
    t = (struct timer *) TQ.next;
    remaining.tv_usec = (t->timeout.tv_usec - now.tv_usec);
    remaining.tv_sec = (t->timeout.tv_sec - now.tv_sec);
    if (remaining.tv_usec < 0) {
 remaining.tv_usec += 1000000;
 remaining.tv_sec -= 1;
    }
    return (&remaining);
}

return_type: struct timeval { long tv_sec; long tv_usec; } *


decompiled_code:
__int64 __fastcall ifindex2devindex(int a1)
{
__int64 v1; // rdx
__int64 result; // rax

v1 = this_host[11];
if ( (int)v1 <= 0 )
return 10LL;
result = 0LL;
while ( dev_indices[result] != a1 )
{
if ( ++result == v1 )
return 10LL;
}
return (unsigned int)result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1)
{
__int64 v1; // rdx
__int64 result; // rax

v1 = this_host[11];
if ( (int)v1 <= 0 )
return 10LL;
result = 0LL;
while ( dev_indices[result] != a1 )
{
if ( ++result == v1 )
return 10LL;
}
return (unsigned int)result;
}

canonical_original_code:
static inline unsigned int ifindex2devindex(unsigned int ifindex)
{
    int i;
    for (i = 0; i < this_host.nif; i++)
 if (dev_indices[i] == ifindex)
     return i;
    return 10;
}

variable_types: i int


decompiled_code:
int *__fastcall rerr_create(char a1, unsigned int a2, unsigned int a3)
{
const char *v4; // rax
int v5; // eax
int *v6; // r8

v4 = (const char *)ip_to_str(a2);
alog(7LL, 0LL, "rerr_create", "Assembling RERR about %s seqno=%d", v4, a3);
*(_DWORD *)(aodv_socket_new_msg() + 4) = a2;
v5 = _bswap_32(a3);
*v6 = ((a1 & 1) << 15) | 0x1000003;
v6[2] = v5;
return v6;
}

canonical_decompiled_code:
int *__fastcall func2(char a1, unsigned int a2, unsigned int a3)
{
const char *v4; // rax
int v5; // eax
int *v6; // r8

v4 = (const char *)ip_to_str(a2);
alog(7LL, 0LL, "rerr_create", "Assembling RERR about %s seqno=%d", v4, a3);
*(_DWORD *)(aodv_socket_new_msg() + 4) = a2;
v5 = func1(a3);
*v6 = ((a1 & 1) << 15) | 0x1000003;
v6[2] = v5;
return v6;
}

original_code:
RERR * rerr_create(u_int8_t flags, struct in_addr dest_addr,
      u_int32_t dest_seqno)
{
    RERR *rerr;
    alog(7, 0, __FUNCTION__, "Assembling RERR about %s seqno=%d", ip_to_str(dest_addr), dest_seqno);
    rerr = (RERR *) aodv_socket_new_msg();
    rerr->type = 3;
    rerr->n = (flags & 0x1 ? 1 : 0);
    rerr->res1 = 0;
    rerr->res2 = 0;
    rerr->dest_addr = dest_addr.s_addr;
    rerr->dest_seqno = htonl(dest_seqno);
    rerr->dest_count = 1;
    return rerr;
}

canonical_original_code:
struct RERR *rerr_create(unsigned int flags, struct in_addr dest_addr, unsigned int dest_seqno)
{
    struct RERR *rerr;
    alog(7, 0, __FUNCTION__, "Assembling RERR about %s seqno=%d", ip_to_str(dest_addr), dest_seqno);
    rerr = (struct RERR *) aodv_socket_new_msg();
    rerr->type = 3;
    rerr->n = (flags & 0x1 ? 1 : 0);
    rerr->res1 = 0;
    rerr->res2 = 0;
    rerr->dest_addr = dest_addr.s_addr;
    rerr->dest_seqno = htonl(dest_seqno);
    rerr->dest_count = 1;
    return rerr;
}

variable_types: struct RERR { unsigned int type; unsigned int res1; unsigned int n; unsigned int res2; unsigned int dest_count; unsigned int dest_addr; unsigned int dest_seqno; } *


decompiled_code:
__int64 __fastcall rerr_add_udest(__int64 a1, int a2, unsigned int a3)
{
_DWORD *v4; // rsi
__int64 result; // rax
char v6; // dl
__int64 v7; // rcx

v4 = (_DWORD *)(a1 + 8LL * (*(unsigned __int8 *)(a1 + 3) - 1) + 12);
*v4 = a2;
result = _bswap_32(a3);
v4[1] = result;
*(_BYTE *)(v7 + 3) = v6;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, int a2, unsigned int a3)
{
_DWORD *v4; // rsi
__int64 result; // rax
char v6; // dl
__int64 v7; // rcx

v4 = (_DWORD *)(a1 + 8LL * (*(unsigned __int8 *)(a1 + 3) - 1) + 12);
*v4 = a2;
result = func1(a3);
v4[1] = result;
*(_BYTE *)(v7 + 3) = v6;
return result;
}

original_code:
void rerr_add_udest(RERR * rerr, struct in_addr udest,
        u_int32_t udest_seqno)
{
    RERR_udest *ud;
    ud = (RERR_udest *) ((char *) rerr + (sizeof(RERR) + (rerr->dest_count-1)*sizeof(RERR_udest)));
    ud->dest_addr = udest.s_addr;
    ud->dest_seqno = htonl(udest_seqno);
    rerr->dest_count++;
}

canonical_original_code:
void rerr_add_udest(struct RERR *rerr, struct in_addr udest, unsigned int udest_seqno)
{
    struct RERR_udest *ud;
    ud = (struct RERR_udest *) ((char *) rerr + (sizeof(RERR) + (rerr->dest_count-1)*sizeof(RERR_udest)));
    ud->dest_addr = udest.s_addr;
    ud->dest_seqno = htonl(udest_seqno);
    rerr->dest_count++;
}

variable_types:
udest
struct in_addr { unsigned int s_addr; }

variable_types: struct RERR_udest { unsigned int dest_addr; unsigned int dest_seqno; } *