undefined4 dhcp6_get_options(uint *param_1,uint *param_2,int param_3)

{
  undefined4 uVar1;
  int iVar2;
  void *pvVar3;
  int iVar4;
  char *__s;
  uint uVar5;
  uint uVar6;
  uint uVar7;
  uint uVar8;
  uint in_t5;
  uint *__src;
  char *__s_00;
  uint uVar9;
  uint uVar10;
  uint *puVar11;
  char *__s_01;
  byte *pbVar12;
  undefined2 local_108;
  ushort local_106;
  ushort local_104;
  uint local_100;
  uint local_fc;
  uint local_f8;
  undefined4 local_f4;
  undefined4 *local_f0;
  uint local_ec;
  uint *local_e8;
  uint local_e4;
  uint local_e0;
  uint local_dc;
  char local_d8 [16];
  char local_c8 [16];
  char local_b8 [16];
  uint local_a8;
  uint local_a4;
  uint local_a0;
  uint local_9c;
  char local_98 [24];
  uint *local_80;
  int local_7c;
  int local_78;
  int local_74;
  int local_70;
  int local_6c;
  int local_68;
  int local_64;
  int local_60;
  int local_5c;
  int local_58;
  int local_54;
  int local_50;
  int local_4c;
  int local_48;
  int local_44;
  uint *local_40;
  undefined4 *local_3c;
  undefined4 *local_38;
  int local_34;
  int local_30;
  int local_2c;
  
  local_34 = param_3 + 0x38;
  local_4c = param_3 + 0x70;
  local_2c = param_3 + 8;
  local_64 = param_3 + 0x68;
  local_30 = param_3 + 0x40;
  local_44 = param_3 + 0x50;
  local_7c = param_3 + 0x30;
  local_38 = (undefined4 *)(param_3 + 0xd8);
  local_40 = (uint *)(param_3 + 0xe8);
  local_3c = (undefined4 *)(param_3 + 0xe0);
  local_48 = param_3 + 0x60;
  local_5c = param_3 + 0x48;
  local_50 = param_3 + 0x90;
  local_54 = param_3 + 0xa0;
  local_58 = param_3 + 0xb0;
  local_60 = param_3 + 0x58;
  __src = param_1 + 1;
  local_74 = param_3 + 0x78;
  local_68 = param_3 + 0x88;
  local_6c = param_3 + 0x98;
  local_70 = param_3 + 0xa8;
  local_78 = param_3 + 0x28;
  local_80 = param_1;
  do {
    if (param_2 < __src) {
      return 0;
    }
    local_100 = *param_1;
    uVar10 = (local_100 & 0xff) << 8 | (local_100 & 0xffff) >> 8;
    uVar7 = local_100 >> 0x18;
    uVar9 = (local_100 >> 0x10 & 0xff) << 8 | uVar7;
    uVar1 = dhcp6optstr(uVar10);
    uVar5 = uVar9;
    dprintf(7,"dhcp6_get_options","get DHCP option %s, len %d",uVar1,uVar9);
    puVar11 = (uint *)((int)__src + uVar9);
    if (param_2 < puVar11) {
      dprintf(6,"dhcp6_get_options","malformed DHCP options");
      goto LAB_0040caa8;
    }
    switch(uVar10) {
    default:
      uVar1 = dhcp6optstr(uVar10);
      dprintf(6,"dhcp6_get_options","unknown or unexpected DHCP6 option %s, len %d",uVar1,uVar9);
      break;
    case 1:
      if (uVar9 == 0) {
LAB_0040d6c0:
        dprintf(6,"dhcp6_get_options","malformed DHCP option: type %d, len %d",uVar10,uVar9);
        goto LAB_0040caa8;
      }
      local_ec = uVar9;
      local_e8 = __src;
      uVar1 = duidstr(&local_ec);
      dprintf(7,"","  DUID: %s",uVar1,uVar5);
      iVar2 = duidcpy(param_3,&local_ec);
      goto joined_r0x0040d370;
    case 2:
      if (uVar9 == 0) goto LAB_0040d6c0;
      local_ec = uVar9;
      local_e8 = __src;
      uVar1 = duidstr(&local_ec);
      dprintf(7,"","  DUID: %s",uVar1,uVar5);
      iVar2 = duidcpy(local_2c,&local_ec);
joined_r0x0040d370:
      if (iVar2 != 0) {
        dprintf(3,"dhcp6_get_options","failed to copy DUID");
        goto LAB_0040caa8;
      }
      break;
    case 3:
      if (uVar9 + 4 < 0x10) goto LAB_0040d6c0;
      local_a4 = param_1[1];
      local_9c = param_1[3];
      local_a0 = param_1[2];
      uVar5 = (int)param_1 + 3U & 3;
      uVar7 = (uint)param_1 & 3;
      in_t5 = (*(int *)((byte *)((int)param_1 + 3U) + -uVar5) << (3 - uVar5) * 8 |
              in_t5 & 0xffffffffU >> (uVar5 + 1) * 8) & -1 << (4 - uVar7) * 8 |
              *(uint *)((int)param_1 - uVar7) >> uVar7 * 8;
      local_e4 = local_a4 << 0x18 | local_a4 >> 0x18 | (local_a4 & 0xff0000) >> 8 |
                 (local_a4 & 0xff00) << 8;
      uVar7 = local_a0 << 0x18 | local_a0 >> 0x18 | (local_a0 & 0xff0000) >> 8 |
              (local_a0 & 0xff00) << 8;
      uVar5 = local_9c << 0x18 | local_9c >> 0x18 | (local_9c & 0xff0000) >> 8 |
              (local_9c & 0xff00) << 8;
      local_e0 = uVar7;
      local_dc = uVar5;
      local_a8 = in_t5;
      dprintf(7,"","  IA_NA: ID=%lu, T1=%lu, T2=%lu",local_e4,uVar7,uVar5);
      iVar2 = dhcp6_find_listval(local_7c,6,&local_e4,0);
      if (iVar2 == 0) {
        local_f0 = &local_f4;
        local_f4 = 0;
        iVar2 = FUN_0040c1a8(3,param_1 + 4,puVar11,local_f0);
        if (iVar2 != 0) goto LAB_0040caa8;
        uVar1 = 6;
        iVar2 = local_7c;
LAB_0040d714:
        iVar2 = dhcp6_add_listval(iVar2,uVar1,&local_e4,&local_f4);
        if (iVar2 == 0) {
          dhcp6_clear_list(&local_f4);
          goto LAB_0040caa8;
        }
        dhcp6_clear_list(&local_f4);
      }
      else {
        dprintf(6,"dhcp6_get_options","duplicated IA_NA %lu",local_e4,uVar7,uVar5);
      }
      break;
    case 6:
      if (((uVar7 & 1) != 0) || (uVar9 == 0)) goto LAB_0040d6c0;
      if (uVar9 / 2 != 0) {
        iVar2 = 0;
        do {
          local_104 = (ushort)*__src;
          local_fc = (local_104 & 0xff) << 8 | (uint)(local_104 >> 8);
          uVar1 = dhcp6optstr(local_fc);
          dprintf(7,"","  requested option: %s",uVar1,uVar5);
          iVar4 = dhcp6_find_listval(local_34,1,&local_fc,0);
          if (iVar4 == 0) {
            iVar4 = dhcp6_add_listval(local_34,1,&local_fc,0);
            if (iVar4 == 0) {
              dprintf(3,"dhcp6_get_options","failed to copy requested option");
              goto LAB_0040caa8;
            }
          }
          else {
            uVar1 = dhcp6optstr(local_104,1);
            dprintf(6,"dhcp6_get_options","duplicated option type (%s)",uVar1);
          }
          iVar2 = iVar2 + 1;
          __src = (uint *)((int)__src + 2);
        } while (iVar2 < (int)(uVar9 / 2));
      }
      break;
    case 7:
      if (uVar9 != 1) goto LAB_0040d6c0;
      dprintf(7,"","  preference: %d",(uint)(byte)*__src,uVar5);
      if (*(int *)(param_3 + 0x14) == -1) {
        *(uint *)(param_3 + 0x14) = (uint)(byte)*__src;
      }
      else {
        dprintf(6,"dhcp6_get_options","duplicated preference option",0x430000,uVar5);
      }
      break;
    case 8:
      if (uVar9 != 2) goto LAB_0040d6c0;
      uVar7 = ((ushort)*__src & 0xff) << 8 | (uint)(ushort)((ushort)*__src >> 8);
      local_106 = (ushort)uVar7;
      dprintf(7,"","  elapsed time: %lu",uVar7,uVar5);
      if (*(int *)(param_3 + 0x1c) == -1) {
        *(uint *)(param_3 + 0x1c) = (uint)local_106;
      }
      else {
        dprintf(6,"dhcp6_get_options","duplicated elapsed time option");
      }
      break;
    case 9:
      pvVar3 = malloc(uVar9)   //possible issue identified - semgrep
      *(void **)(param_3 + 0xbc) = pvVar3;
      if (pvVar3 == (void *)0x0) goto LAB_0040caa8;
      memcpy(pvVar3,__src,uVar9)   //possible issue identified - semgrep
      *(uint *)(param_3 + 0xb8) = uVar9;
      break;
    case 0xb:
      if (uVar9 < 0xb) goto LAB_0040d6c0;
      if (*(int *)(param_3 + 0xcc) != -1) {
        dprintf(6,"dhcp6_get_options","found more than one authentication option");
        goto LAB_0040caa8;
      }
      *(int *)(param_3 + 0xcc) = (int)(char)(byte)*__src;
      *(int *)(param_3 + 0xd0) = (int)(char)*(byte *)((int)__src + 1);
      *(int *)(param_3 + 0xd4) = (int)(char)*(byte *)((int)__src + 2);
      uVar1 = *(undefined4 *)((int)__src + 7);
      *local_38 = *(undefined4 *)((int)__src + 3);
      local_38[1] = uVar1;
      builtin_strncpy(local_b8,"unknown(255)",0xd)   //possible issue identified - semgrep
      builtin_strncpy(local_d8,"unknown(255)",0xd)   //possible issue identified - semgrep
      builtin_strncpy(local_c8,"unknown(255)",0xd)   //possible issue identified - semgrep
      builtin_strncpy(local_98,"ffff",4)   //possible issue identified - semgrep
      uVar5 = *(uint *)(param_3 + 0xcc);
      builtin_strncpy(local_98 + 4," ffff ffff ffff",0x10)   //possible issue identified - semgrep
      pbVar12 = (byte *)((int)__src + 0xb);
      if (uVar5 == 2) {
        __s_00 = "delayed";
      }
      else if (uVar5 == 3) {
        __s_00 = "reconfig";
      }
      else {
        __s_00 = local_d8;
        snprintf(__s_00,0xd,"unknown(%d)",uVar5 & 0xff)   //possible issue identified - semgrep
      }
      if (*(uint *)(param_3 + 0xd0) == 1) {
        __s_01 = "HMAC-MD5";
      }
      else {
        __s_01 = local_c8;
        snprintf(__s_01,0xd,"unknown(%d)",*(uint *)(param_3 + 0xd0) & 0xff)   //possible issue identified - semgrep
      }
      if (*(int *)(param_3 + 0xd4) == 0) {
        __s = "mono counter";
      }
      else {
        __s = local_b8;
        snprintf(__s,0xd,"unknown(%d)")   //possible issue identified - semgrep
      }
      snprintf(&DAT_0043ec34,0x400,"proto: %s, alg: %s, RDM: %s, RD: %s",__s_00,__s_01,__s,local_98)   //possible issue identified - semgrep
      ;
      dprintf(7,"",&DAT_0042843c,&DAT_0043ec34);
      if (*(int *)(param_3 + 0xcc) == 2) {
        if (uVar9 == 0xb) {
LAB_0040d638:
          *(uint *)(param_3 + 200) = *(uint *)(param_3 + 200) | 1;
        }
        else {
          if (uVar9 - 0xb < 0x14) goto LAB_0040d6c0;
          *(uint *)(param_3 + 0xe4) = uVar9 - 0x1f;
          pvVar3 = malloc(uVar9 - 0x1f)   //possible issue identified - semgrep
          *(void **)(param_3 + 0xe8) = pvVar3;
          if (pvVar3 == (void *)0x0) {
            dprintf(4,"dhcp6_get_options","failed allocate memory for auth realm");
            goto LAB_0040caa8;
          }
          memcpy(pvVar3,pbVar12,*(size_t *)(param_3 + 0xe4))   //possible issue identified - semgrep
          pbVar12 = pbVar12 + *(int *)(param_3 + 0xe4);
          *local_3c = *(undefined4 *)pbVar12;
          uVar5 = *(uint *)(param_3 + 0xe0);
          uVar5 = uVar5 << 0x18 | uVar5 >> 0x18 | uVar5 >> 8 & 0xff00 | (uVar5 & 0xff00) << 8;
          *(uint *)(param_3 + 0xe0) = uVar5;
          *(byte **)(param_3 + 0xec) = pbVar12 + (4 - (int)local_80);
          dprintf(7,"","  auth key ID: %x, offset=%d, realmlen=%d",uVar5,
                  pbVar12 + (4 - (int)local_80),*(undefined4 *)(param_3 + 0xe4));
        }
      }
      else {
        if (*(int *)(param_3 + 0xcc) != 3) {
          dprintf(6,"dhcp6_get_options","unsupported authentication protocol: %d",
                  (int)(char)*pbVar12);
          goto LAB_0040caa8;
        }
        if (uVar9 == 0xb) goto LAB_0040d638;
        uVar10 = (int)(__src + 3) - (int)local_80;
        *(int *)(param_3 + 0xe0) = (int)(char)*(byte *)((int)__src + 0xb);
        *(uint *)(param_3 + 0xe4) = uVar10;
        uVar5 = (int)__src + 0x13U & 3;
        iVar2 = *(int *)((byte *)((int)__src + 0x13U) + -uVar5);
        uVar8 = __src[6];
        uVar7 = (uint)(__src + 4) & 3;
        uVar9 = *(uint *)((int)(__src + 4) - uVar7);
        uVar6 = __src[5];
        *local_40 = __src[3];
        local_40[1] = (iVar2 << (3 - uVar5) * 8 | uVar10 & 0xffffffffU >> (uVar5 + 1) * 8) &
                      -1 << (4 - uVar7) * 8 | uVar9 >> uVar7 * 8;
        local_40[2] = uVar6;
        local_40[3] = uVar8;
        if (*(int *)(param_3 + 0xe0) == 1) {
          g_prevrd = *(undefined4 *)(param_3 + 0xd8);
          DAT_0043ea04 = *(undefined4 *)(param_3 + 0xdc);
          reconfig_key = *local_40;
          DAT_00441264 = local_40[1];
          DAT_00441268 = local_40[2];
          DAT_0044126c = local_40[3];
        }
      }
      break;
    case 0xd:
      if (uVar9 < 2) goto LAB_0040d6c0;
      local_106 = (ushort)*__src;
      uVar7 = (local_106 & 0xff) << 8 | (uint)(local_106 >> 8);
      local_108 = (undefined2)uVar7;
      uVar1 = dhcp6_stcodestr(uVar7);
      dprintf(7,"","  status code: %s",uVar1,uVar5);
      iVar2 = dhcp6_add_listval(local_30,2,&local_108,0);
      if (iVar2 == 0) {
        dprintf(3,"dhcp6_get_options","failed to copy status code");
        goto LAB_0040caa8;
      }
      break;
    case 0xe:
      if (uVar9 != 0) goto LAB_0040d6c0;
      *(undefined4 *)(param_3 + 0x10) = 1;
      break;
    case 0x12:
      pvVar3 = malloc(uVar9)   //possible issue identified - semgrep
      *(void **)(param_3 + 0xc4) = pvVar3;
      if (pvVar3 == (void *)0x0) goto LAB_0040caa8;
      memcpy(pvVar3,__src,uVar9)   //possible issue identified - semgrep
      *(uint *)(param_3 + 0xc0) = uVar9;
      break;
    case 0x13:
      if (uVar9 != 1) goto LAB_0040d6c0;
      dprintf(7,"","  reconfigure type: %d",(uint)(byte)*__src,uVar5);
      *(int *)(param_3 + 0x18) = (int)(char)(byte)*__src;
      break;
    case 0x15:
      uVar1 = 0x15;
      iVar2 = local_44;
      goto LAB_0040caf8;
    case 0x16:
      uVar1 = 0x16;
      iVar2 = local_5c;
      goto LAB_0040ca90;
    case 0x17:
      uVar1 = 0x17;
      iVar2 = local_64;
      goto LAB_0040ca90;
    case 0x18:
      uVar1 = 0x18;
      iVar2 = local_4c;
      goto LAB_0040caf8;
    case 0x19:
      if (uVar9 + 4 < 0x10) goto LAB_0040d6c0;
      local_a4 = param_1[1];
      local_9c = param_1[3];
      local_a0 = param_1[2];
      uVar5 = (int)param_1 + 3U & 3;
      uVar7 = (uint)param_1 & 3;
      in_t5 = (*(int *)((byte *)((int)param_1 + 3U) + -uVar5) << (3 - uVar5) * 8 |
              in_t5 & 0xffffffffU >> (uVar5 + 1) * 8) & -1 << (4 - uVar7) * 8 |
              *(uint *)((int)param_1 - uVar7) >> uVar7 * 8;
      local_e4 = local_a4 << 0x18 | local_a4 >> 0x18 | (local_a4 & 0xff0000) >> 8 |
                 (local_a4 & 0xff00) << 8;
      uVar7 = local_a0 << 0x18 | local_a0 >> 0x18 | (local_a0 & 0xff0000) >> 8 |
              (local_a0 & 0xff00) << 8;
      uVar5 = local_9c << 0x18 | local_9c >> 0x18 | (local_9c & 0xff0000) >> 8 |
              (local_9c & 0xff00) << 8;
      local_e0 = uVar7;
      local_dc = uVar5;
      local_a8 = in_t5;
      dprintf(7,"","  IA_PD: ID=%lu, T1=%lu, T2=%lu",local_e4,uVar7,uVar5);
      iVar2 = dhcp6_find_listval(local_78,4,&local_e4,0);
      if (iVar2 == 0) {
        local_f0 = &local_f4;
        local_f4 = 0;
        iVar2 = FUN_0040c1a8(0x19,param_1 + 4,puVar11,local_f0);
        if (iVar2 != 0) goto LAB_0040caa8;
        uVar1 = 4;
        iVar2 = local_78;
        goto LAB_0040d714;
      }
      dprintf(6,"dhcp6_get_options","duplicated IA_PD %lu",local_e4,uVar7,uVar5);
      break;
    case 0x1b:
      uVar1 = 0x1b;
      iVar2 = local_68;
      goto LAB_0040ca90;
    case 0x1c:
      uVar1 = 0x1c;
      iVar2 = local_6c;
      goto LAB_0040ca90;
    case 0x1d:
      uVar1 = 0x1d;
      iVar2 = local_50;
      goto LAB_0040caf8;
    case 0x1e:
      uVar1 = 0x1e;
      iVar2 = local_54;
      goto LAB_0040caf8;
    case 0x1f:
      uVar1 = 0x1f;
      iVar2 = local_74;
      goto LAB_0040ca90;
    case 0x20:
      if (uVar9 != 4) goto LAB_0040d6c0;
      uVar7 = *__src;
      local_f8 = uVar7 << 0x18 | uVar7 >> 0x18 | uVar7 >> 8 & 0xff00 | (uVar7 & 0xff00) << 8;
      dprintf(7,"","   information refresh time: %lu",local_f8,uVar5);
      if (local_f8 < 600) {
        dprintf(6,"dhcp6_get_options","refresh time is too small (%d), adjusted",local_f8,uVar5);
        iVar2 = *(int *)(param_3 + 0x20);
        local_f8 = 600;
      }
      else {
        iVar2 = *(int *)(param_3 + 0x20);
      }
      if ((iVar2 == -1) && (*(int *)(param_3 + 0x24) == -1)) {
        *(undefined4 *)(param_3 + 0x24) = 0;
        *(uint *)(param_3 + 0x20) = local_f8;
      }
      else {
        dprintf(6,"dhcp6_get_options","duplicated refresh time option");
      }
      break;
    case 0x21:
      uVar1 = 0x21;
      iVar2 = local_58;
      goto LAB_0040caf8;
    case 0x22:
      uVar1 = 0x22;
      iVar2 = local_70;
      goto LAB_0040ca90;
    case 0x40:
      uVar1 = 0x40;
      iVar2 = local_48;
LAB_0040caf8:
      iVar2 = FUN_0040b1a0(uVar9,__src,uVar1,iVar2);
      goto joined_r0x0040caa0;
    case 0x62:
      uVar1 = 0x62;
      iVar2 = local_60;
LAB_0040ca90:
      iVar2 = FUN_0040c004(uVar9,__src,uVar1,iVar2);
joined_r0x0040caa0:
      if (iVar2 == -1) {
LAB_0040caa8:
        dhcp6_clear_options(param_3);
        return 0xffffffff;
      }
    }
    __src = puVar11 + 1;
    param_1 = puVar11;
  } while( true );
}