

#include<stdio.h>
#include<netinet/in.h>
#include<string.h>
#include<stdlib.h>
#include<pthread.h>
#include<ctype.h>

#include"sitar.h"
#include"sitar_scan.h"
#include<almemsys/almemsys.h>
#include"jpreturn.h"




/* ------ SCAN PORT --------- */
int scan_snmp(struct scan_buf *pd)
{
int ret, hi, inret, chk, plai, stats, in1, in2;
ret = 0;
hi = 0;
inret = 0;
chk = 0;
plai = 0;
stats = 0;
in1 = 0;
in2 = 0;

char ch[1024];
char ho[1024];
char bk[1024];

char * chhi = ch;
char * chho = ho;
char * backdata = bk;

memset(chhi, 0x00, 1024);
memset(chho, 0x00, 1024);
memset(backdata, 0x00, 1024);

pd->swap = null_free(pd->swap);
pd->swap_2 = null_free(pd->swap_2);

if(0 == ch_int2(pd->ch_plai)){
   plai = strtol(pd->ch_plai, (char **)NULL, 10);
   }
else{
   plai = 3;
   }

// 閾値がNOTの場合、戻り値は編集しないでそのまま返す
if(0 == memcmp(pd->ch_prot, "NOT", 3) || 0 == memcmp(pd->ch_port, "NON", 3)){
   pd->ch_info = cal_oid(pd->ch_com, pd->ch_info, &ret, &inret, pd->ch_port, pd->ch_host, &chk, pd->timeout);

   self_memcpy(backdata, pd->ch_info, 1024);
   pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"(%s) %s\n", backdata, SNMP_23);

   #ifdef SNMP_DEBUG
   printf("SNMP_DEBUG: scan_snmp(): ch_info = <%s>: inret = <%d>: stat = <%d>\n", pd->ch_info, inret, ret);
   #endif
   ret = -1;
   if(0 == (int)strlen(pd->ch_info)){
      ret = -1;
      pd->ch_info=safe_memcpy(pd->ch_info,"SNMP Information is a no bur error.\n",BUF_MAX);
      }
   }

// 閾値がLOGの場合、戻りを数字に戻さずそのまま返す
else if(0 == memcmp(pd->ch_prot, "LOG", 3) || 0 == memcmp(pd->ch_port, "log", 3)){

   pd->ch_info = snmp_test(pd->ch_info, pd->ch_port, pd->ch_host, pd->ch_com, &ret, 0, &chk, pd->timeout);

   #ifdef SNMP_DEBUG
   printf("SNMP_DEBUG: scan_snmp(): ch_info = <%s>: inret = <%d>: stat = <%d>\n", pd->ch_info, inret, ret);
   #endif
   ret = -1;
   if(0 == (int)strlen(pd->ch_info)){
      ret = -1;
      pd->ch_info=safe_memcpy(pd->ch_info,"SNMP Information is a no bur error.\n",BUF_MAX);
      }
   }



// 閾値の先頭が|で最後か|であり敷居が|である、克つ全体が5文字以上な場合
else if(pd->ch_prot[0] == '|' && 4 < (int)strlen(pd->ch_prot) &&
   pd->ch_prot[((int)strlen(pd->ch_prot)) - 1] == '|' && 3 == char_count(pd->ch_prot, '|')){
   if(pd->ch_prot[1] != '|' && 0 != isdigit(pd->ch_prot[1]) && 0 != isdigit(pd->ch_prot[((int)strlen(pd->ch_prot)) - 2])){

      pd->swap = delim_get(pd->ch_prot, pd->swap, '|', &stats, 1);
      pd->swap_2 = safe_memcpy(pd->swap_2, (pd->swap + 1), BUF_LEN);
      pd->swap = delim_get(pd->ch_prot, pd->swap, '|', &stats, 2);

      if(0 == ch_int2(pd->swap_2) && 0 == ch_int2(pd->swap)){

         in1 = strtol(pd->swap_2, (char **)NULL, 10);
         in2 = strtol(pd->swap, (char **)NULL, 10);

         #ifdef SNMP_DEBUG
         printf("BUG BUG swap2 %d , %d\n", in1, in2);
         #endif
         if(in2 >= in1){
            pd->ch_info = cal_oid(pd->ch_com, pd->ch_info, &ret, &inret, pd->ch_port, pd->ch_host, &chk, pd->timeout);
            if(4 == chk){
               #ifdef SNMP_DEBUG
               printf("SNMP_DEBUG: scan_snmp(||): %s %s in1=%d in2=%d inret=%d\n", pd->ch_info, pd->ch_free1, in1, in2, inret);
               #endif
               ret = -1;

               self_memcpy(backdata, pd->ch_info, 1024);
               pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"(%s) %s\n", backdata, SNMP_30);

               }
            else if(0 > ret){
               if(0 == (int)strlen(pd->ch_info)){
                  ret = -1;
                  pd->ch_info=safe_sprintf(pd->ch_info, BUF_MAX,"%s\n",SNMP_10);
                  }
               }
            else{
               if(inret >= in1 && inret <= in2){
                  // ok
                  ret = 0;
                  pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d < return %d > %d %s\n", in1, inret, in2, SNMP_32);
                  }
               else{
                  // ng
                  ret = -1;
                  pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d < !return %d > %d %s\n", in1, inret, in2, SNMP_33);
                  }
               }
            }
         else{
            ret = -1;
            pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%s %s\n",pd->ch_prot, SNMP_34);
            }
         }
      else{
         ret = -1;
         pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"2 %s %s\n",pd->ch_prot, SNMP_13);
         }
      }
   else{
      ret = -1;
      pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"3 %s %s\n",pd->ch_prot, SNMP_13);
      }
   }





// 閾値の先頭が&で最後か&であり敷居が&である、克つ全体が5文字以上な場合
else if(pd->ch_prot[0] == '&' && 4 < (int)strlen(pd->ch_prot) &&
   pd->ch_prot[((int)strlen(pd->ch_prot)) - 1] == '&' && 3 == char_count(pd->ch_prot, '&')){
   if(pd->ch_prot[1] != '&' && 0 != isdigit(pd->ch_prot[1]) && 0 != isdigit(pd->ch_prot[((int)strlen(pd->ch_prot)) - 2])){

      pd->swap = delim_get(pd->ch_prot, pd->swap, '&', &stats, 1);
      pd->swap_2 = safe_memcpy(pd->swap_2, (pd->swap + 1), BUF_LEN);
      pd->swap = delim_get(pd->ch_prot, pd->swap, '&', &stats, 2);

      if(0 == ch_int2(pd->swap_2) && 0 == ch_int2(pd->swap)){

         in1 = strtol(pd->swap_2, (char **)NULL, 10);
         in2 = strtol(pd->swap, (char **)NULL, 10);

         #ifdef SNMP_DEBUG
         printf("BUG BUG swap2 %d , %d\n", in1, in2);
         #endif
         if(in2 >= in1){
            pd->ch_info = cal_oid(pd->ch_com, pd->ch_info, &ret, &inret, pd->ch_port, pd->ch_host, &chk, pd->timeout);
            if(4 == chk){
               #ifdef SNMP_DEBUG
               printf("SNMP_DEBUG: scan_snmp(||): %s %s in1=%d in2=%d inret=%d\n", pd->ch_info, pd->ch_free1, in1, in2, inret);
               #endif
               ret = -1;

               self_memcpy(backdata, pd->ch_info, 1024);
               pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"(%s) %s\n", backdata, SNMP_30);

               }
            else if(0 > ret){
               if(0 == (int)strlen(pd->ch_info)){
                  ret = -1;
                  pd->ch_info=safe_sprintf(pd->ch_info, BUF_MAX,"%s\n",SNMP_10);
                  }
               }
            else{
               if(inret <= in1 || in2 <= inret){
                  // ok
                  ret = 0;
                  pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d < return %d > %d %s\n", in1, inret, in2, SNMP_32);
                  }
               else{
                  // ng
                  ret = -1;
                  pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d < !return %d > %d %s\n", in1, inret, in2, SNMP_33);
                  }
               }
            }
         else{
            ret = -1;
            pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%s %s\n",pd->ch_prot, SNMP_34);
            }
         }
      else{
         ret = -1;
         pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"2 %s %s\n",pd->ch_prot, SNMP_13);
         }
      }
   else{
      ret = -1;
      pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"3 %s %s\n",pd->ch_prot, SNMP_13);
      }
   }







// 閾値の先頭がマイナスの場合
else if(pd->ch_prot[0] == '-' && 1 < (int)strlen(pd->ch_prot)){

// chhi = safe_memcpy(chhi, pd->ch_prot + 1, BUF_MAX);
   self_memcpy(chhi, pd->ch_prot + 1, 1024);
   if(-1 != ch_int(chhi)){
      if((hi = strtol(chhi, (char **)NULL, 10)) >= 0){
         pd->ch_info = cal_oid(pd->ch_com, pd->ch_info, &ret, &inret, pd->ch_port, pd->ch_host, &chk, pd->timeout);
         #ifdef SNMP_DEBUG
         printf("SNMP_DEBUG: scan_snmp(): %s\n%s", pd->ch_info, pd->ch_free1);
         #endif
         if(4 == chk){
            ret = -1;
 
            self_memcpy(backdata, pd->ch_info, 1024);
            pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"(%s) %s\n", backdata, SNMP_30);

            }
         else if(0 > ret){
            if(0 == (int)strlen(pd->ch_info)){
               ret = -1;
               pd->ch_info=safe_sprintf(pd->ch_info, BUF_MAX,"%s\n",SNMP_10);
               }
            }
         else{
            if(hi > inret){
               ret = -1;
               if(0 < plai && 5 > plai){
                  pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d > %d %s\n", hi, inret, SNMP_11);
                  }
               else{
                  pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d\n", inret);
                  }
               }
            else{
               ret = 0;
               if(0 < plai && 5 > plai){
                  pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d < %d %s\n", hi, inret, SNMP_12);
                  }
               else{
                  pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d\n", inret);
                  }
               }
            }
         }
      else{
         ret = -1;
         pd->ch_info=safe_sprintf(pd->ch_info, BUF_MAX,"%s %s %d\n", SNMP_13, pd->ch_prot, hi);
         } 
      }
   else{
      ret = -1;
      pd->ch_info=safe_sprintf(pd->ch_info, BUF_MAX,"%s\n",SNMP_14);
      } 
   }




// 閾値の先頭が＋の場合
else if(pd->ch_prot[0] == '+' && 1 < (int)strlen(pd->ch_prot)){
// chhi = safe_memcpy(chhi, pd->ch_prot + 1, BUF_MAX);
   self_memcpy(chhi, pd->ch_prot + 1, 1024);
   if(-1 != ch_int(chhi)){
      if((hi = strtol(chhi, (char **)NULL, 10)) >= 0){
         pd->ch_info = cal_oid(pd->ch_com, pd->ch_info, &ret, &inret, pd->ch_port, pd->ch_host, &chk, pd->timeout);
         #ifdef SNMP_DEBUG
         printf("SNMP_DEBUG: scan_snmp(): %s\n%s", pd->ch_info, pd->ch_free1);
         #endif
         if(4 == chk){
            ret = -1;

            self_memcpy(backdata, pd->ch_info, 1024);
            pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"(%s) %s\n", backdata, SNMP_30);

            }
         else if(0 > ret){
            if(0 == (int)strlen(pd->ch_info)){
               ret = -1;
               pd->ch_info=safe_sprintf(pd->ch_info, BUF_MAX,"%s\n",SNMP_10);
               }
            }
         else{
            if(hi < inret){
               ret = -1;
               if(0 < plai && 5 > plai){
                  pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d < %d %s\n", hi, inret, SNMP_11);
                  }
               else{
                  pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d\n", inret);
                  }
               }
            else{
               ret = 0;
               if(0 < plai && 5 > plai){
                  pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d > %d %s\n", hi, inret, SNMP_12);
                  }
               else{
                  pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d\n", inret);
                  }
               }
            }
         }
      else{
         ret = -1;
         pd->ch_info=safe_sprintf(pd->ch_info, BUF_MAX,"%s %s %d\n", SNMP_13, pd->ch_prot, hi);
         } 
      }
   else{
      ret = -1;
      pd->ch_info=safe_sprintf(pd->ch_info, BUF_MAX,"%s\n",SNMP_14);
      } 
   }

// 閾値の先頭が！の場合
else if(pd->ch_prot[0] == '!' && 1 < (int)strlen(pd->ch_prot)){
// chhi = safe_memcpy(chhi, pd->ch_prot + 1, BUF_MAX);
   self_memcpy(chhi, pd->ch_prot + 1, 1024);

   if(0 == memcmp(pd->ch_com, "cal", 3)){
      pd->ch_info = cal_oid(pd->ch_com, pd->ch_info, &ret, &inret, pd->ch_port, pd->ch_host, &chk, pd->timeout);
      if(ret > -1){
         pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d", inret);
         }
      }
   else{
      pd->ch_info = snmp_test(pd->ch_info, pd->ch_port, pd->ch_host, pd->ch_com, &ret, 1, &chk, pd->timeout);
      }

   #ifdef SNMP_DEBUG
   printf("SNMP_DEBUG: scan_snmp(!): %s %s %s ret= %d\n", pd->ch_info, pd->ch_free1, chhi, ret);
   #endif
   if(0 > ret){
      if(0 == (int)strlen(pd->ch_info)){
         ret = -1;
         pd->ch_info=safe_sprintf(pd->ch_info, BUF_MAX,"%s\n",SNMP_10);
         }
      }
   else{
//    chho = safe_memcpy(chho, pd->ch_info, BUF_MAX);
      self_memcpy(chho, pd->ch_info, 1024);
      // 同じ返事を返していない（！なので異常）
      if(0 != self_memcmp(chhi, chho)){
         ret = -1;
         if(0 < plai && 5 > plai){
            pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,
               "%s\n                   1(%s)\n                   2(%s)\n", SNMP_19, chhi, chho);
            }
         else{
            pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX, "%s\n", chho);
            }
         }
      // 同じ返事を返している（！なので正常）
      else{
         ret = 0;
         if(0 < plai && 5 > plai){
            pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,
               "%s\n                   1(%s)\n                   2(%s)\n", SNMP_20, chhi, chho);
            }
         else{
            pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX, "%s\n", chho);
            }
         }
      }
   }


// 閾値の先頭が＝の場合
else if(pd->ch_prot[0] == '=' && 1 < (int)strlen(pd->ch_prot)){
// chhi = safe_memcpy(chhi, pd->ch_prot + 1, BUF_MAX);
   self_memcpy(chhi, pd->ch_prot + 1, 1024);

   if(0 == memcmp(pd->ch_com, "cal", 3)){
      pd->ch_info = cal_oid(pd->ch_com, pd->ch_info, &ret, &inret, pd->ch_port, pd->ch_host, &chk, pd->timeout);
      if(ret >= 0){
         pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"%d", inret);
         }
      }
   else{
      pd->ch_info = snmp_test(pd->ch_info, pd->ch_port, pd->ch_host, pd->ch_com, &ret, 1, &chk, pd->timeout);
      }

   #ifdef SNMP_DEBUG
   printf("SNMP_DEBUG: scan_snmp(=): %s %s %s ret = %d\n", pd->ch_info, pd->ch_free1, chhi, ret);
   #endif
   if(0 > ret){
      if(0 == (int)strlen(pd->ch_info)){
         ret = -1;
         pd->ch_info=safe_sprintf(pd->ch_info, BUF_MAX,"%s\n",SNMP_10);
         }
      }
   else{
//    chho = safe_memcpy(chho, pd->ch_info, BUF_MAX);
      self_memcpy(chho, pd->ch_info, 1024);
      // 同じ返事を返していない（＝なので正常）
      if(0 != self_memcmp(chhi, chho)){
         ret = 0;

         if(0 < plai && 5 > plai){
            pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,
               "%s\n                   1(%s)\n                   2(%s)\n", SNMP_19, chhi, chho);
            }
         else{
            pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX, "%s\n", chho);
            }
         }
      // 同じ返事を返している（＝なので異常）
      else{
         ret = -1;
         if(0 < plai && 5 > plai){
            pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,
               "%s\n                   1(%s)\n                   2(%s)\n", SNMP_20, chhi, chho);
            }
         else{
            pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX, "%s\n", chho);
            }
         }
      }
   }


// それ以外の場合もNOTと同じ処理、但し間違いを正す。
else {
   pd->ch_info = cal_oid(pd->ch_com, pd->ch_info, &ret, &inret, pd->ch_port, pd->ch_host, &chk, pd->timeout);

   self_memcpy(backdata, pd->ch_info, 1024);
   pd->ch_info = safe_sprintf(pd->ch_info, BUF_MAX,"(%s) %s\n", backdata, SNMP_13);

   #ifdef SNMP_DEBUG
   printf("SNMP_DEBUG: scan_snmp(): %s\n%s", pd->ch_info, pd->ch_free1);
   printf("SNMP_DEBUG: scan_snmp(): backdata = <%s>: inret = <%d>: stat = <%d>\n", backdata, inret, ret);
   #endif
   ret = -1;
   if(0 == (int)strlen(pd->ch_info)){
      ret = -1;
      pd->ch_info=safe_memcpy(pd->ch_info,"SNMP Information is a no bur error.\n",BUF_MAX);
      }
   }


// TEXTとLOGモードの処理
if(0 == self_memcmp(pd->ch_plai, "4")){
   #ifdef SNMP_DEBUG
   printf("SNMP_DEBUG: scan_snmp(): snmp chack plai=%s check_stat=%d\n", pd->ch_plai, pd->check_stat);
   #endif
   ret = -1;
   }
else if(0 == self_memcmp(pd->ch_plai, "11")){
   #ifdef SNMP_DEBUG
   printf("SNMP_DEBUG: scan_snmp(): snmp chack plai=%s check_stat=%d\n", pd->ch_plai, pd->check_stat);
   #endif
   if(ret == -1){
      pd->ch_plai = safe_memcpy(pd->ch_plai, "1", BUF_MAX);
      }
   ret = -1;
   }
else if(0 == self_memcmp(pd->ch_plai, "12")){
   #ifdef SNMP_DEBUG
   printf("SNMP_DEBUG: scan_snmp(): snmp chack plai=%s check_stat=%d\n", pd->ch_plai, pd->check_stat);
   #endif
   if(ret == -1){
      pd->ch_plai = safe_memcpy(pd->ch_plai, "2", BUF_MAX);
      }
   ret = -1;
   }
else if(0 == self_memcmp(pd->ch_plai, "13")){
   #ifdef SNMP_DEBUG
   printf("SNMP_DEBUG: scan_snmp(): snmp chack plai=%s check_stat=%d\n", pd->ch_plai, pd->check_stat);
   #endif
   if(ret == -1){
      pd->ch_plai = safe_memcpy(pd->ch_plai, "3", BUF_MAX);
      }
   ret = -1;
   }



// CHECK STAT設定　正か逆かで反転する。監視の正逆の判断 check_stat == 1はエラー、0は正常です。
if(ret < 0){
   if(pd->ch_stat[0] == '0'){
      pd->check_stat = 1;
      }
   if(pd->ch_stat[0] == '1'){
      pd->check_stat = 0;
      }
   }

if(ret >= 0){
   if(pd->ch_stat[0] == '0'){
      pd->check_stat = 0;
      }

   if(pd->ch_stat[0] == '1'){
      pd->check_stat = 1;
      }
   }


#ifdef SNMP_DEBUG
printf("SNMP_DEBUG: scan_snmp(last): ch_info = <%s>: inret = <%d>: stat = <%d>\n", pd->ch_info, inret, ret);
#endif

return(ret);
}




