traceRouteCtlTable.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:215k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1.         if (var_val_type != ASN_INTEGER) {
  2.             snmp_log(LOG_ERR,
  3.                      "write to traceRouteCtlIfIndex not ASN_INTEGERn");
  4.             return SNMP_ERR_WRONGTYPE;
  5.         }
  6.         break;
  7.     case RESERVE2:
  8.         /*
  9.          * memory reseveration, final preparation... 
  10.          */
  11.         break;
  12.     case FREE:
  13.         /*
  14.          * Release any resources that have been allocated 
  15.          */
  16.         break;
  17.     case ACTION:
  18.         /*
  19.          * The variable has been stored in objid for
  20.          * you to use, and you have just been asked to do something with
  21.          * it.  Note that anything done here must be reversable in the UNDO case 
  22.          */
  23.         tmpvar = StorageTmp->traceRouteCtlAdminStatus;
  24.         StorageTmp->traceRouteCtlAdminStatus = *((long *) var_val);
  25.         break;
  26.     case UNDO:
  27.         /*
  28.          * Back out any changes made in the ACTION case 
  29.          */
  30.         StorageTmp->traceRouteCtlAdminStatus = tmpvar;
  31.         break;
  32.     case COMMIT:
  33.         /*
  34.          * Things are working well, so it's now safe to make the change
  35.          * permanently.  Make sure that anything done here can't fail! 
  36.          */
  37.         snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) StorageTmp->traceRouteCtlOwnerIndex, StorageTmp->traceRouteCtlOwnerIndexLen); /*  traceRouteCtlOwnerIndex  */
  38.         snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) StorageTmp->traceRouteCtlTestName, StorageTmp->traceRouteCtlTestNameLen);     /*  traceRouteCtlTestName  */
  39.         StorageNew =
  40.             header_complex_get(traceRouteResultsTableStorage, vars);
  41.         if (StorageTmp->traceRouteCtlAdminStatus == 1
  42.             && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
  43.             if (StorageNew == NULL)
  44.                 init_trResultsTable(StorageTmp);
  45.             else {
  46.                 StorageTmp->traceRouteResults->
  47.                     traceRouteResultsOperStatus = 1;
  48.                 modify_trResultsOper(StorageTmp, 1);
  49.             }
  50.             if (StorageTmp->traceRouteCtlFrequency != 0)
  51.                 StorageTmp->timer_id =
  52.                     snmp_alarm_register(StorageTmp->traceRouteCtlFrequency,
  53.                                         SA_REPEAT, run_traceRoute,
  54.                                         StorageTmp);
  55.             else
  56.                 StorageTmp->timer_id = snmp_alarm_register(1, (int) NULL,
  57.                                                            run_traceRoute,
  58.                                                            StorageTmp);
  59.         } else if (StorageTmp->traceRouteCtlAdminStatus == 2
  60.                    && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
  61.             snmp_alarm_unregister(StorageTmp->timer_id);
  62.             if (StorageNew == NULL)
  63.                 init_trResultsTable(StorageTmp);
  64.             else {
  65.                 StorageTmp->traceRouteResults->
  66.                     traceRouteResultsOperStatus = 2;
  67.                 modify_trResultsOper(StorageTmp, 2);
  68.             }
  69.         }
  70.         break;
  71.     }
  72.     return SNMP_ERR_NOERROR;
  73. }
  74. int
  75. write_traceRouteCtlDescr(int action,
  76.                          u_char * var_val,
  77.                          u_char var_val_type,
  78.                          size_t var_val_len,
  79.                          u_char * statP, oid * name, size_t name_len)
  80. {
  81.     static char    *tmpvar;
  82.     static size_t   tmplen;
  83.     struct traceRouteCtlTable_data *StorageTmp = NULL;
  84.     size_t          newlen =
  85.         name_len -
  86.         (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1);
  87.     if ((StorageTmp =
  88.          header_complex(traceRouteCtlTableStorage, NULL,
  89.                         &name[sizeof(traceRouteCtlTable_variables_oid) /
  90.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  91.                         NULL)) == NULL)
  92.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  93.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  94.         return SNMP_ERR_NOTWRITABLE;
  95.     }
  96.     if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
  97.         return SNMP_ERR_NOTWRITABLE;
  98.     }
  99.     switch (action) {
  100.     case RESERVE1:
  101.         if (var_val_type != ASN_OCTET_STR) {
  102.             snmp_log(LOG_ERR,
  103.                      "write to traceRouteCtlTargetAddress not ASN_OCTET_STRn");
  104.             return SNMP_ERR_WRONGTYPE;
  105.         }
  106.         break;
  107.     case RESERVE2:
  108.         /*
  109.          * memory reseveration, final preparation... 
  110.          */
  111.         break;
  112.     case FREE:
  113.         /*
  114.          * Release any resources that have been allocated 
  115.          */
  116.         break;
  117.     case ACTION:
  118.         /*
  119.          * The variable has been stored in long_ret for
  120.          * you to use, and you have just been asked to do something with
  121.          * it.  Note that anything done here must be reversable in the UNDO case 
  122.          */
  123.         tmpvar = StorageTmp->traceRouteCtlDescr;
  124.         tmplen = StorageTmp->traceRouteCtlDescrLen;
  125.         StorageTmp->traceRouteCtlDescr = (char *) malloc(var_val_len + 1);
  126.         if (StorageTmp->traceRouteCtlDescr == NULL) {
  127.             exit(1);
  128.         }
  129.         memcpy(StorageTmp->traceRouteCtlDescr, var_val, var_val_len + 1);
  130.         StorageTmp->traceRouteCtlDescr[var_val_len] = '';
  131.         StorageTmp->traceRouteCtlDescrLen = var_val_len;
  132.         break;
  133.     case UNDO:
  134.         /*
  135.          * Back out any changes made in the ACTION case 
  136.          */
  137.         SNMP_FREE(StorageTmp->traceRouteCtlDescr);
  138.         StorageTmp->traceRouteCtlDescr = NULL;
  139.         StorageTmp->traceRouteCtlDescr = tmpvar;
  140.         StorageTmp->traceRouteCtlDescrLen = tmplen;
  141.         break;
  142.     case COMMIT:
  143.         /*
  144.          * Things are working well, so it's now safe to make the change
  145.          * permanently.  Make sure that anything done here can't fail! 
  146.          */
  147.         SNMP_FREE(tmpvar);
  148.         tmpvar = NULL;
  149.         break;
  150.     }
  151.     return SNMP_ERR_NOERROR;
  152. }
  153. int
  154. write_traceRouteCtlMaxRows(int action,
  155.                            u_char * var_val,
  156.                            u_char var_val_type,
  157.                            size_t var_val_len,
  158.                            u_char * statP, oid * name, size_t name_len)
  159. {
  160.     static size_t   tmpvar;
  161.     struct traceRouteCtlTable_data *StorageTmp = NULL;
  162.     static size_t   tmplen;
  163.     size_t          newlen =
  164.         name_len -
  165.         (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1);
  166.     if ((StorageTmp =
  167.          header_complex(traceRouteCtlTableStorage, NULL,
  168.                         &name[sizeof(traceRouteCtlTable_variables_oid) /
  169.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  170.                         NULL)) == NULL)
  171.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  172.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  173.         return SNMP_ERR_NOTWRITABLE;
  174.     }
  175.     if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
  176.         return SNMP_ERR_NOTWRITABLE;
  177.     }
  178.     switch (action) {
  179.     case RESERVE1:
  180.         if (var_val_type != ASN_UNSIGNED) {
  181.             snmp_log(LOG_ERR,
  182.                      "write to traceRouteCtlDSField not ASN_UNSIGNEDn");
  183.             return SNMP_ERR_WRONGTYPE;
  184.         }
  185.         break;
  186.     case RESERVE2:
  187.         /*
  188.          * memory reseveration, final preparation... 
  189.          */
  190.         break;
  191.     case FREE:
  192.         /*
  193.          * Release any resources that have been allocated 
  194.          */
  195.         break;
  196.     case ACTION:
  197.         /*
  198.          * The variable has been stored in objid for
  199.          * you to use, and you have just been asked to do something with
  200.          * it.  Note that anything done here must be reversable in the UNDO case 
  201.          */
  202.         tmpvar = StorageTmp->traceRouteCtlMaxRows;
  203.         StorageTmp->traceRouteCtlMaxRows = *((long *) var_val);
  204.         break;
  205.     case UNDO:
  206.         /*
  207.          * Back out any changes made in the ACTION case 
  208.          */
  209.         StorageTmp->traceRouteCtlMaxRows = tmpvar;
  210.         break;
  211.     case COMMIT:
  212.         /*
  213.          * Things are working well, so it's now safe to make the change
  214.          * permanently.  Make sure that anything done here can't fail! 
  215.          */
  216.         break;
  217.     }
  218.     return SNMP_ERR_NOERROR;
  219. }
  220. int
  221. write_traceRouteCtlTrapGeneration(int action,
  222.                                   u_char * var_val,
  223.                                   u_char var_val_type,
  224.                                   size_t var_val_len,
  225.                                   u_char * statP, oid * name,
  226.                                   size_t name_len)
  227. {
  228.     static char    *tmpvar;
  229.     static size_t   tmplen;
  230.     struct traceRouteCtlTable_data *StorageTmp = NULL;
  231.     size_t          newlen =
  232.         name_len -
  233.         (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1);
  234.     if ((StorageTmp =
  235.          header_complex(traceRouteCtlTableStorage, NULL,
  236.                         &name[sizeof(traceRouteCtlTable_variables_oid) /
  237.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  238.                         NULL)) == NULL)
  239.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  240.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  241.         return SNMP_ERR_NOTWRITABLE;
  242.     }
  243.     if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
  244.         return SNMP_ERR_NOTWRITABLE;
  245.     }
  246.     switch (action) {
  247.     case RESERVE1:
  248.         if (var_val_type != ASN_OCTET_STR) {
  249.             snmp_log(LOG_ERR,
  250.                      "write to traceRouteCtlTargetAddress not ASN_OCTET_STRn");
  251.             return SNMP_ERR_WRONGTYPE;
  252.         }
  253.         break;
  254.     case RESERVE2:
  255.         /*
  256.          * memory reseveration, final preparation... 
  257.          */
  258.         break;
  259.     case FREE:
  260.         /*
  261.          * Release any resources that have been allocated 
  262.          */
  263.         break;
  264.     case ACTION:
  265.         /*
  266.          * The variable has been stored in long_ret for
  267.          * you to use, and you have just been asked to do something with
  268.          * it.  Note that anything done here must be reversable in the UNDO case 
  269.          */
  270.         tmpvar = StorageTmp->traceRouteCtlTrapGeneration;
  271.         tmplen = StorageTmp->traceRouteCtlTrapGenerationLen;
  272.         StorageTmp->traceRouteCtlTrapGeneration =
  273.             (char *) malloc(var_val_len + 1);
  274.         if (StorageTmp->traceRouteCtlTrapGeneration == NULL) {
  275.             exit(1);
  276.         }
  277.         memcpy(StorageTmp->traceRouteCtlTrapGeneration, var_val,
  278.                var_val_len + 1);
  279.         StorageTmp->traceRouteCtlTrapGeneration[var_val_len] = '';
  280.         StorageTmp->traceRouteCtlTrapGenerationLen = var_val_len;
  281.         break;
  282.     case UNDO:
  283.         /*
  284.          * Back out any changes made in the ACTION case 
  285.          */
  286.         SNMP_FREE(StorageTmp->traceRouteCtlTrapGeneration);
  287.         StorageTmp->traceRouteCtlTrapGeneration = NULL;
  288.         StorageTmp->traceRouteCtlTrapGeneration = tmpvar;
  289.         StorageTmp->traceRouteCtlTrapGenerationLen = tmplen;
  290.         break;
  291.     case COMMIT:
  292.         /*
  293.          * Things are working well, so it's now safe to make the change
  294.          * permanently.  Make sure that anything done here can't fail! 
  295.          */
  296.         SNMP_FREE(tmpvar);
  297.         tmpvar = NULL;
  298.         break;
  299.     }
  300.     return SNMP_ERR_NOERROR;
  301. }
  302. int
  303. write_traceRouteCtlCreateHopsEntries(int action,
  304.                                      u_char * var_val,
  305.                                      u_char var_val_type,
  306.                                      size_t var_val_len,
  307.                                      u_char * statP, oid * name,
  308.                                      size_t name_len)
  309. {
  310.     static size_t   tmpvar;
  311.     struct traceRouteCtlTable_data *StorageTmp = NULL;
  312.     static size_t   tmplen;
  313.     size_t          newlen =
  314.         name_len -
  315.         (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1);
  316.     if ((StorageTmp =
  317.          header_complex(traceRouteCtlTableStorage, NULL,
  318.                         &name[sizeof(traceRouteCtlTable_variables_oid) /
  319.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  320.                         NULL)) == NULL)
  321.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  322.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  323.         return SNMP_ERR_NOTWRITABLE;
  324.     }
  325.     if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
  326.         return SNMP_ERR_NOTWRITABLE;
  327.     }
  328.     switch (action) {
  329.     case RESERVE1:
  330.         if (var_val_type != ASN_INTEGER) {
  331.             snmp_log(LOG_ERR,
  332.                      "write to traceRouteCtlDSField not ASN_INTEGERn");
  333.             return SNMP_ERR_WRONGTYPE;
  334.         }
  335.         break;
  336.     case RESERVE2:
  337.         /*
  338.          * memory reseveration, final preparation... 
  339.          */
  340.         break;
  341.     case FREE:
  342.         /*
  343.          * Release any resources that have been allocated 
  344.          */
  345.         break;
  346.     case ACTION:
  347.         /*
  348.          * The variable has been stored in objid for
  349.          * you to use, and you have just been asked to do something with
  350.          * it.  Note that anything done here must be reversable in the UNDO case 
  351.          */
  352.         tmpvar = StorageTmp->traceRouteCtlCreateHopsEntries;
  353.         StorageTmp->traceRouteCtlCreateHopsEntries = *((long *) var_val);
  354.         break;
  355.     case UNDO:
  356.         /*
  357.          * Back out any changes made in the ACTION case 
  358.          */
  359.         StorageTmp->traceRouteCtlCreateHopsEntries = tmpvar;
  360.         break;
  361.     case COMMIT:
  362.         /*
  363.          * Things are working well, so it's now safe to make the change
  364.          * permanently.  Make sure that anything done here can't fail! 
  365.          */
  366.         break;
  367.     }
  368.     return SNMP_ERR_NOERROR;
  369. }
  370. int
  371. write_traceRouteCtlType(int action,
  372.                         u_char * var_val,
  373.                         u_char var_val_type,
  374.                         size_t var_val_len,
  375.                         u_char * statP, oid * name, size_t name_len)
  376. {
  377.     static oid     *tmpvar;
  378.     static size_t   tmplen;
  379.     struct traceRouteCtlTable_data *StorageTmp = NULL;
  380.     size_t          newlen =
  381.         name_len -
  382.         (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1);
  383.     if ((StorageTmp =
  384.          header_complex(traceRouteCtlTableStorage, NULL,
  385.                         &name[sizeof(traceRouteCtlTable_variables_oid) /
  386.                               sizeof(oid) + 3 - 1], &newlen, 1, NULL,
  387.                         NULL)) == NULL)
  388.         return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */
  389.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  390.         return SNMP_ERR_NOTWRITABLE;
  391.     }
  392.     if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
  393.         return SNMP_ERR_NOTWRITABLE;
  394.     }
  395.     switch (action) {
  396.     case RESERVE1:
  397.         if (var_val_type != ASN_OBJECT_ID) {
  398.             snmp_log(LOG_ERR,
  399.                      "write to traceRouteCtlType not ASN_OBJECT_IDn");
  400.             return SNMP_ERR_WRONGTYPE;
  401.         }
  402.         break;
  403.     case RESERVE2:
  404.         /*
  405.          * memory reseveration, final preparation... 
  406.          */
  407.         break;
  408.     case FREE:
  409.         /*
  410.          * Release any resources that have been allocated 
  411.          */
  412.         break;
  413.     case ACTION:
  414.         /*
  415.          * The variable has been stored in long_ret for
  416.          * you to use, and you have just been asked to do something with
  417.          * it.  Note that anything done here must be reversable in the UNDO case 
  418.          */
  419.         tmpvar = StorageTmp->traceRouteCtlType;
  420.         tmplen = StorageTmp->traceRouteCtlTypeLen;
  421.         StorageTmp->traceRouteCtlType = (oid *) malloc(var_val_len);
  422.         if (StorageTmp->traceRouteCtlType == NULL) {
  423.             exit(1);
  424.         }
  425.         memcpy(StorageTmp->traceRouteCtlType, var_val, var_val_len);
  426.         StorageTmp->traceRouteCtlTypeLen = var_val_len / sizeof(oid);
  427.         break;
  428.     case UNDO:
  429.         /*
  430.          * Back out any changes made in the ACTION case 
  431.          */
  432.         SNMP_FREE(StorageTmp->traceRouteCtlType);
  433.         StorageTmp->traceRouteCtlType = NULL;
  434.         StorageTmp->traceRouteCtlType = tmpvar;
  435.         StorageTmp->traceRouteCtlTypeLen = tmplen;
  436.         break;
  437.     case COMMIT:
  438.         /*
  439.          * Things are working well, so it's now safe to make the change
  440.          * permanently.  Make sure that anything done here can't fail! 
  441.          */
  442.         SNMP_FREE(tmpvar);
  443.         tmpvar = NULL;
  444.         break;
  445.     }
  446.     return SNMP_ERR_NOERROR;
  447. }
  448. int
  449. write_traceRouteCtlRowStatus(int action,
  450.                              u_char * var_val,
  451.                              u_char var_val_type,
  452.                              size_t var_val_len,
  453.                              u_char * statP, oid * name, size_t name_len)
  454. {
  455.     struct traceRouteCtlTable_data *StorageTmp = NULL;
  456.     static struct traceRouteCtlTable_data *StorageNew = NULL;
  457.     static struct traceRouteCtlTable_data *StorageDel = NULL;
  458.     size_t          newlen =
  459.         name_len -
  460.         (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1);
  461.     static int      old_value;
  462.     int             set_value;
  463.     static netsnmp_variable_list *vars = NULL, *vp = NULL;
  464.     struct header_complex_index *hciptr = NULL;
  465.     StorageTmp =
  466.         header_complex(traceRouteCtlTableStorage, NULL,
  467.                        &name[sizeof(traceRouteCtlTable_variables_oid) /
  468.                              sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL);
  469.     if (var_val_type != ASN_INTEGER || var_val == NULL) {
  470.         snmp_log(LOG_ERR,
  471.                  "write to traceRouteCtlRowStatus not ASN_INTEGERn");
  472.         return SNMP_ERR_WRONGTYPE;
  473.     }
  474.     if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
  475.         return SNMP_ERR_NOTWRITABLE;
  476.     }
  477.     set_value = *((long *) var_val);
  478.     /*
  479.      * check legal range, and notReady is reserved for us, not a user 
  480.      */
  481.     if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY)
  482.         return SNMP_ERR_INCONSISTENTVALUE;
  483.     switch (action) {
  484.     case RESERVE1:
  485.         /*
  486.          * stage one: test validity 
  487.          */
  488.         if (StorageTmp == NULL) {
  489.             /*
  490.              * create the row now? 
  491.              */
  492.             /*
  493.              * ditch illegal values now 
  494.              */
  495.             if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
  496.                 return SNMP_ERR_INCONSISTENTVALUE;
  497.             }
  498.             /*
  499.              * destroying a non-existent row is actually legal 
  500.              */
  501.             if (set_value == RS_DESTROY) {
  502.                 return SNMP_ERR_NOERROR;
  503.             }
  504.             /*
  505.              * illegal creation values 
  506.              */
  507.             if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
  508.                 return SNMP_ERR_INCONSISTENTVALUE;
  509.             }
  510.         } else {
  511.             /*
  512.              * row exists.  Check for a valid state change 
  513.              */
  514.             if (set_value == RS_CREATEANDGO
  515.                 || set_value == RS_CREATEANDWAIT) {
  516.                 /*
  517.                  * can't create a row that exists 
  518.                  */
  519.                 return SNMP_ERR_INCONSISTENTVALUE;
  520.             }
  521.             /*
  522.              * XXX: interaction with row storage type needed 
  523.              */
  524.             if (StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE &&
  525.                 set_value != RS_DESTROY) {
  526.                 /*
  527.                  * "Once made active an entry may not be modified except to 
  528.                  * delete it."  XXX: doesn't this in fact apply to ALL
  529.                  * columns of the table and not just this one?  
  530.                  */
  531.                 return SNMP_ERR_INCONSISTENTVALUE;
  532.             }
  533.             if (StorageTmp->storageType != ST_NONVOLATILE) {
  534.                 return SNMP_ERR_NOTWRITABLE;
  535.             }
  536.         }
  537.         break;
  538.     case RESERVE2:
  539.         /*
  540.          * memory reseveration, final preparation... 
  541.          */
  542.         if (StorageTmp == NULL) {
  543.             if (set_value == RS_DESTROY) {
  544.                 return SNMP_ERR_NOERROR;
  545.             }
  546.             /*
  547.              * creation 
  548.              */
  549.             snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* traceRouteCtlOwnerIndex */
  550.             snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* traceRouteCtlTestName */
  551.             if (header_complex_parse_oid
  552.                 (&
  553.                  (name
  554.                   [sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) +
  555.                    2]), newlen, vars) != SNMPERR_SUCCESS) {
  556.                 /*
  557.                  * XXX: free, zero vars 
  558.                  */
  559.                 return SNMP_ERR_INCONSISTENTNAME;
  560.             }
  561.             StorageNew = create_traceRouteCtlTable_data();
  562.             if (vars->val_len <= 32) {
  563.                 StorageNew->traceRouteCtlOwnerIndex =
  564.                     malloc(vars->val_len + 1);
  565.                 memcpy(StorageNew->traceRouteCtlOwnerIndex,
  566.                        vars->val.string, vars->val_len);
  567.                 StorageNew->traceRouteCtlOwnerIndex[vars->val_len] = '';
  568.                 StorageNew->traceRouteCtlOwnerIndexLen = vars->val_len;
  569.             } else {
  570.                 StorageNew->traceRouteCtlOwnerIndex = malloc(33);
  571.                 memcpy(StorageNew->traceRouteCtlOwnerIndex,
  572.                        vars->val.string, 32);
  573.                 StorageNew->traceRouteCtlOwnerIndex[32] = '';
  574.                 StorageNew->traceRouteCtlOwnerIndexLen = 32;
  575.             }
  576.             vars = vars->next_variable;
  577.             if (vars->val_len <= 32) {
  578.                 StorageNew->traceRouteCtlTestName =
  579.                     malloc(vars->val_len + 1);
  580.                 memcpy(StorageNew->traceRouteCtlTestName, vars->val.string,
  581.                        vars->val_len);
  582.                 StorageNew->traceRouteCtlTestName[vars->val_len] = '';
  583.                 StorageNew->traceRouteCtlTestNameLen = vars->val_len;
  584.             } else {
  585.                 StorageNew->traceRouteCtlTestName = malloc(33);
  586.                 memcpy(StorageNew->traceRouteCtlTestName, vars->val.string,
  587.                        32);
  588.                 StorageNew->traceRouteCtlTestName[32] = '';
  589.                 StorageNew->traceRouteCtlTestNameLen = 32;
  590.             }
  591.             vars = vars->next_variable;
  592.             /*
  593.              * XXX: fill in default row values here into StorageNew 
  594.              */
  595.             StorageNew->traceRouteCtlRowStatus = set_value;
  596.             /*
  597.              * XXX: free, zero vars, no longer needed? 
  598.              */
  599.         }
  600.         snmp_free_varbind(vars);
  601.         vars = NULL;
  602.         break;
  603.     case FREE:
  604.         /*
  605.          * XXX: free, zero vars 
  606.          */
  607.         snmp_free_varbind(vars);
  608.         vars = NULL;
  609.         /*
  610.          * Release any resources that have been allocated 
  611.          */
  612.         break;
  613.     case ACTION:
  614.         /*
  615.          * The variable has been stored in set_value for you to
  616.          * use, and you have just been asked to do something with
  617.          * it.  Note that anything done here must be reversable in
  618.          * the UNDO case 
  619.          */
  620.         if (StorageTmp == NULL) {
  621.             if (set_value == RS_DESTROY) {
  622.                 return SNMP_ERR_NOERROR;
  623.             }
  624.             /*
  625.              * row creation, so add it 
  626.              */
  627.             if (StorageNew != NULL) {
  628. #if 1
  629.                 DEBUGMSGTL(("traceRouteCtlTable",
  630.                             "write_traceRouteCtlRowStatus entering new=%d...  n",
  631.                             action));
  632. #endif
  633.                 traceRouteCtlTable_add(StorageNew);
  634.             }
  635.             /*
  636.              * XXX: ack, and if it is NULL? 
  637.              */
  638.         } else if (set_value != RS_DESTROY) {
  639.             /*
  640.              * set the flag? 
  641.              */
  642.             old_value = StorageTmp->traceRouteCtlRowStatus;
  643.             StorageTmp->traceRouteCtlRowStatus = *((long *) var_val);
  644.         } else {
  645.             /*
  646.              * destroy...  extract it for now 
  647.              */
  648.             hciptr =
  649.                 header_complex_find_entry(traceRouteCtlTableStorage,
  650.                                           StorageTmp);
  651.             StorageDel =
  652.                 header_complex_extract_entry(&traceRouteCtlTableStorage,
  653.                                              hciptr);
  654.             snmp_alarm_unregister(StorageDel->timer_id);
  655.             traceRouteResultsTable_del(StorageTmp);
  656.             traceRouteProbeHistoryTable_del(StorageTmp);
  657.             traceRouteHopsTable_del(StorageTmp);
  658.         }
  659.         break;
  660.     case UNDO:
  661.         /*
  662.          * Back out any changes made in the ACTION case 
  663.          */
  664.         if (StorageTmp == NULL) {
  665.             if (set_value == RS_DESTROY) {
  666.                 return SNMP_ERR_NOERROR;
  667.             }
  668.             /*
  669.              * row creation, so remove it again 
  670.              */
  671.             hciptr =
  672.                 header_complex_find_entry(traceRouteCtlTableStorage,
  673.                                           StorageTmp);
  674.             StorageDel =
  675.                 header_complex_extract_entry(&traceRouteCtlTableStorage,
  676.                                              hciptr);
  677.             /*
  678.              * XXX: free it 
  679.              */
  680.         } else if (StorageDel != NULL) {
  681.             /*
  682.              * row deletion, so add it again 
  683.              */
  684.             traceRouteCtlTable_add(StorageDel);
  685.             traceRouteResultsTable_add(StorageDel);
  686.             traceRouteProbeHistoryTable_addall(StorageDel);
  687.             traceRouteHopsTable_addall(StorageDel);
  688.         } else {
  689.             StorageTmp->traceRouteCtlRowStatus = old_value;
  690.         }
  691.         break;
  692.     case COMMIT:
  693.         /*
  694.          * Things are working well, so it's now safe to make the change
  695.          * permanently.  Make sure that anything done here can't fail! 
  696.          */
  697.         if (StorageTmp == NULL) {
  698.             if (set_value == RS_DESTROY) {
  699.                 return SNMP_ERR_NOERROR;
  700.             }
  701.         }
  702.         if (StorageDel != NULL) {
  703.             free(StorageDel->traceRouteCtlOwnerIndex);
  704.             StorageDel->traceRouteCtlOwnerIndex = NULL;
  705.             free(StorageDel->traceRouteCtlTestName);
  706.             StorageDel->traceRouteCtlTestName = NULL;
  707.             free(StorageDel->traceRouteCtlTargetAddress);
  708.             StorageDel->traceRouteCtlTargetAddress = NULL;
  709.             free(StorageDel->traceRouteCtlSourceAddress);
  710.             StorageDel->traceRouteCtlSourceAddress = NULL;
  711.             free(StorageDel->traceRouteCtlMiscOptions);
  712.             StorageDel->traceRouteCtlMiscOptions = NULL;
  713.             free(StorageDel->traceRouteCtlDescr);
  714.             StorageDel->traceRouteCtlDescr = NULL;
  715.             free(StorageDel->traceRouteCtlTrapGeneration);
  716.             StorageDel->traceRouteCtlTrapGeneration = NULL;
  717.             free(StorageDel->traceRouteCtlType);
  718.             StorageDel->traceRouteCtlType = NULL;
  719.             free(StorageDel);
  720.             StorageDel = NULL;
  721.             /*
  722.              * XXX: free it, its dead 
  723.              */
  724.         } else {
  725.             if (StorageTmp
  726.                 && StorageTmp->traceRouteCtlRowStatus == RS_CREATEANDGO) {
  727.                 StorageTmp->traceRouteCtlRowStatus = RS_ACTIVE;
  728.             } else if (StorageTmp &&
  729.                        StorageTmp->traceRouteCtlRowStatus ==
  730.                        RS_CREATEANDWAIT) {
  731.                 StorageTmp->traceRouteCtlRowStatus = RS_NOTINSERVICE;
  732.             }
  733.         }
  734.         if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
  735. #if 1
  736.             DEBUGMSGTL(("traceRouteCtlTable",
  737.                         "write_traceRouteCtlRowStatus entering runbefore=%ld...  n",
  738.                         StorageTmp->traceRouteCtlTargetAddressType));
  739. #endif
  740.             if (StorageTmp->traceRouteCtlAdminStatus == 1) {
  741.                 init_trResultsTable(StorageTmp);
  742.                 if (StorageTmp->traceRouteCtlFrequency != 0)
  743.                     StorageTmp->timer_id =
  744.                         snmp_alarm_register(StorageTmp->
  745.                                             traceRouteCtlFrequency,
  746.                                             SA_REPEAT, run_traceRoute,
  747.                                             StorageTmp);
  748.                 else
  749.                     StorageTmp->timer_id =
  750.                         snmp_alarm_register(1, (int) NULL, run_traceRoute,
  751.                                             StorageTmp);
  752.             }
  753.         }
  754.         break;
  755.     }
  756.     return SNMP_ERR_NOERROR;
  757. }
  758. unsigned long
  759. round(double number)
  760. {
  761.     unsigned long   ret_num = 0;
  762.     if (number - (unsigned long) number < 0.5)
  763.         ret_num = (unsigned long) number;
  764.     else
  765.         ret_num = (unsigned long) number + 1;
  766.     return ret_num;
  767. }
  768. void
  769. run_traceRoute(unsigned int clientreg, void *clientarg)
  770. {
  771.     struct traceRouteCtlTable_data *item = clientarg;
  772.     u_short         port = item->traceRouteCtlPort;     /* start udp dest port # for probe packets 相当于ctlport */
  773.     int             waittime = item->traceRouteCtlTimeOut;      /* time to wait for response (in seconds) 相等于ctltimeout */
  774.     prog = "traceroute";
  775.     int             nprobes = item->traceRouteCtlProbesPerHop;
  776.     if (item->traceRouteCtlInitialTtl > item->traceRouteCtlMaxTtl) {
  777.         DEBUGMSGTL(("traceRouteCtlTable",
  778.                     "first ttl (%d) may not be greater than max ttl (%d)n",
  779.                     item->traceRouteCtlInitialTtl,
  780.                     item->traceRouteCtlMaxTtl));
  781.         return;
  782.     }
  783.     char           *old_HopsAddress[255];
  784.     int             count = 0;
  785.     int             flag = 0;
  786.     if (item->traceRouteCtlTargetAddressType == 1
  787.         || item->traceRouteCtlTargetAddressType == 16) {
  788.         register int    op, code, n;
  789.         register char  *cp;
  790.         register const char *err;
  791.         register u_char *outp;
  792.         register u_int32_t *ap;
  793.         struct sockaddr whereto;        /* Who to try to reach */
  794.         struct sockaddr wherefrom;      /* Who we are */
  795.         register struct sockaddr_in *from =
  796.             (struct sockaddr_in *) &wherefrom;
  797.         register struct sockaddr_in *to = (struct sockaddr_in *) &whereto;
  798.         register struct hostinfo *hi;
  799.         int             on = 1;
  800.         register struct protoent *pe;
  801.         register int    ttl, probe, i;
  802.         register int    seq = 0;
  803.         int             tos = 0, settos = 0;
  804.         register int    lsrr = 0;
  805.         register u_short off = 0;
  806.         struct ifaddrlist *al;
  807.         char            errbuf[132];
  808.         int             minpacket = 0;  /* min ip packet size */
  809.         struct ip      *outip;  /* last output (udp) packet */
  810.         struct udphdr  *outudp; /* last output (udp) packet */
  811.         int             packlen = 0;    /* total length of packet */
  812.         int             optlen = 0;     /* length of ip options */
  813.         int             options = 0;    /* socket options */
  814.         int             s;      /* receive (icmp) socket file descriptor */
  815.         int             sndsock;        /* send (udp/icmp) socket file descriptor */
  816.         u_short         ident;
  817.         /*
  818.          * loose source route gateway list (including room for final destination) 
  819.          */
  820.         u_int32_t       gwlist[NGATEWAYS + 1];
  821.         static const char devnull[] = "/dev/null";
  822.         char           *device = NULL;
  823.         char           *source = NULL;
  824.         char           *hostname;
  825.         u_int           pausemsecs = 0;
  826.         u_char          packet[512];    /* last inbound (icmp) packet */
  827.         int             pmtu = 0;       /* Path MTU Discovery (RFC1191) */
  828.         struct outdata *outdata;        /* last output (udp) packet */
  829.         minpacket = sizeof(*outip) + sizeof(*outdata) + optlen;
  830.         minpacket += sizeof(*outudp);
  831.         packlen = minpacket;    /* minimum sized packet */
  832.         hostname =
  833.             (char *) malloc(item->traceRouteCtlTargetAddressLen + 1);
  834.         if (hostname == NULL)
  835.             return;
  836.         memcpy(hostname, item->traceRouteCtlTargetAddress,
  837.                item->traceRouteCtlTargetAddressLen + 1);
  838.         hostname[item->traceRouteCtlTargetAddressLen] = '';
  839.         hi = gethostinfo(hostname);
  840.         setsin(to, hi->addrs[0]);
  841.         if (hi->n > 1)
  842.             DEBUGMSGTL(("traceRouteCtlTable",
  843.                         "Warning: %s has multiple addresses; using %sn",
  844.                         hostname, inet_ntoa(to->sin_addr)));
  845.         hostname = hi->name;
  846.         hi->name = NULL;
  847.         freehostinfo(hi);
  848. #ifdef HAVE_SETLINEBUF
  849.         setlinebuf(stdout);
  850. #else
  851.         setvbuf(stdout, NULL, _IOLBF, 0);
  852. #endif
  853.         outip = (struct ip *) malloc(packlen);
  854.         if (outip == NULL) {
  855.             DEBUGMSGTL(("traceRouteCtlTable",
  856.                         "malloc: %sn", strerror(errno)));
  857.             exit(1);
  858.         }
  859.         memset((char *) outip, 0, packlen);
  860.         outip->ip_v = IPVERSION;
  861.         if (settos)
  862.             outip->ip_tos = tos;
  863. #ifdef BYTESWAP_IP_HDR
  864.         outip->ip_len = htons(packlen);
  865.         outip->ip_off = htons(off);
  866. #else
  867.         outip->ip_len = packlen;
  868.         outip->ip_off = off;
  869. #endif
  870.         outp = (u_char *) (outip + 1);
  871. #ifdef HAVE_RAW_OPTIONS
  872.         if (lsrr > 0) {
  873.             register u_char *optlist;
  874.             optlist = outp;
  875.             outp += optlen;
  876.             /*
  877.              * final hop 
  878.              */
  879.             gwlist[lsrr] = to->sin_addr.s_addr;
  880.             outip->ip_dst.s_addr = gwlist[0];
  881.             /*
  882.              * force 4 byte alignment 
  883.              */
  884.             optlist[0] = IPOPT_NOP;
  885.             /*
  886.              * loose source route option 
  887.              */
  888.             optlist[1] = IPOPT_LSRR;
  889.             i = lsrr * sizeof(gwlist[0]);
  890.             optlist[2] = i + 3;
  891.             /*
  892.              * Pointer to LSRR addresses 
  893.              */
  894.             optlist[3] = IPOPT_MINOFF;
  895.             memcpy(optlist + 4, gwlist + 1, i);
  896.         } else
  897. #endif
  898.             outip->ip_dst = to->sin_addr;
  899.         outip->ip_hl = (outp - (u_char *) outip) >> 2;
  900.         ident = (getpid() & 0xffff) | 0x8000;
  901.         outip->ip_p = IPPROTO_UDP;
  902.         outudp = (struct udphdr *) outp;
  903.         outudp->source = htons(ident);
  904.         outudp->len =
  905.             htons((u_short) (packlen - (sizeof(*outip) + optlen)));
  906.         outdata = (struct outdata *) (outudp + 1);
  907.         cp = "icmp";
  908.         if ((pe = getprotobyname(cp)) == NULL) {
  909.             DEBUGMSGTL(("traceRouteCtlTable",
  910.                         "unknown protocol %sn", cp));
  911.             exit(1);
  912.         }
  913.         /*
  914.          * Insure the socket fds won't be 0, 1 or 2 
  915.          */
  916.         if (open(devnull, O_RDONLY) < 0 ||
  917.             open(devnull, O_RDONLY) < 0 || open(devnull, O_RDONLY) < 0) {
  918.             DEBUGMSGTL(("traceRouteCtlTable",
  919.                         "open "%s": %sn", devnull, strerror(errno)));
  920.             exit(1);
  921.         }
  922.         if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0) {
  923.             DEBUGMSGTL(("traceRouteCtlTable",
  924.                         "icmp socket: %sn", strerror(errno)));
  925.             exit(1);
  926.         }
  927.         if (options & SO_DEBUG)
  928.             (void) setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *) &on,
  929.                               sizeof(on));
  930.         if (options & SO_DONTROUTE)
  931.             (void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *) &on,
  932.                               sizeof(on));
  933. #ifndef __hpux
  934.         printf("rawn");
  935.         sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
  936. #else
  937.         printf("udpn");
  938.         sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
  939. #endif
  940.         if (sndsock < 0) {
  941.             DEBUGMSGTL(("traceRouteCtlTable",
  942.                         "raw socket: %sn", strerror(errno)));
  943.             exit(1);
  944.         }
  945. #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
  946.         if (lsrr > 0) {
  947.             u_char          optlist[MAX_IPOPTLEN];
  948.             cp = "ip";
  949.             if ((pe = getprotobyname(cp)) == NULL) {
  950.                 DEBUGMSGTL(("traceRouteCtlTable",
  951.                             "unknown protocol %sn", cp));
  952.                 exit(1);
  953.             }
  954.             /*
  955.              * final hop 
  956.              */
  957.             gwlist[lsrr] = to->sin_addr.s_addr;
  958.             ++lsrr;
  959.             /*
  960.              * force 4 byte alignment 
  961.              */
  962.             optlist[0] = IPOPT_NOP;
  963.             /*
  964.              * loose source route option 
  965.              */
  966.             optlist[1] = IPOPT_LSRR;
  967.             i = lsrr * sizeof(gwlist[0]);
  968.             optlist[2] = i + 3;
  969.             /*
  970.              * Pointer to LSRR addresses 
  971.              */
  972.             optlist[3] = IPOPT_MINOFF;
  973.             memcpy(optlist + 4, gwlist, i);
  974.             if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS,
  975.                             (char *) optlist,
  976.                             i + sizeof(gwlist[0]))) < 0) {
  977.                 DEBUGMSGTL(("traceRouteCtlTable", "IP_OPTIONS: %sn",
  978.                             strerror(errno)));
  979.                 exit(1);
  980.             }
  981.         }
  982. #endif
  983. #ifdef SO_SNDBUF
  984.         if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *) &packlen,
  985.                        sizeof(packlen)) < 0) {
  986.             DEBUGMSGTL(("traceRouteCtlTable",
  987.                         "SO_SNDBUF: %sn", strerror(errno)));
  988.             exit(1);
  989.         }
  990. #endif
  991. #ifdef IP_HDRINCL
  992.         if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *) &on,
  993.                        sizeof(on)) < 0) {
  994.             DEBUGMSGTL(("traceRouteCtlTable",
  995.                         "IP_HDRINCL: %sn", strerror(errno)));
  996.             exit(1);
  997.         }
  998. #else
  999. #ifdef IP_TOS
  1000.         if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS,
  1001.                                  (char *) &tos, sizeof(tos)) < 0) {
  1002.             DEBUGMSGTL(("traceRouteCtlTable",
  1003.                         "setsockopt tos %d: %sn", strerror(errno)));
  1004.             exit(1);
  1005.         }
  1006. #endif
  1007. #endif
  1008.         if (options & SO_DEBUG)
  1009.             (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *) &on,
  1010.                               sizeof(on));
  1011.         if (options & SO_DONTROUTE)
  1012.             (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
  1013.                               (char *) &on, sizeof(on));
  1014.         /*
  1015.          * Get the interface address list 
  1016.          */
  1017.         n = ifaddrlist(&al, errbuf);
  1018.         if (n < 0) {
  1019.             DEBUGMSGTL(("traceRouteCtlTable",
  1020.                         " ifaddrlist: %sn", errbuf));
  1021.             exit(1);
  1022.         }
  1023.         if (n == 0) {
  1024.             DEBUGMSGTL(("traceRouteCtlTable",
  1025.                         " Can't find any network interfacesn"));
  1026.             exit(1);
  1027.         }
  1028.         /*
  1029.          * Look for a specific device 
  1030.          */
  1031.         if (device != NULL) {
  1032.             for (i = n; i > 0; --i, ++al)
  1033.                 if (strcmp(device, al->device) == 0)
  1034.                     break;
  1035.             if (i <= 0) {
  1036.                 DEBUGMSGTL(("traceRouteCtlTable",
  1037.                             " Can't find interface %.32sn", device));
  1038.                 exit(1);
  1039.             }
  1040.         }
  1041.         /*
  1042.          * Determine our source address 
  1043.          */
  1044.         if (source == NULL) {
  1045.             /*
  1046.              * If a device was specified, use the interface address.
  1047.              * Otherwise, try to determine our source address.
  1048.              */
  1049.             if (device != NULL)
  1050.                 setsin(from, al->addr);
  1051.             else if ((err = findsaddr(to, from)) != NULL) {
  1052.                 DEBUGMSGTL(("traceRouteCtlTable",
  1053.                             " findsaddr: %sn", err));
  1054.                 exit(1);
  1055.             }
  1056.         } else {
  1057.             hi = gethostinfo(source);
  1058.             source = hi->name;
  1059.             hi->name = NULL;
  1060.             /*
  1061.              * If the device was specified make sure it
  1062.              * corresponds to the source address specified.
  1063.              * Otherwise, use the first address (and warn if
  1064.              * there are more than one).
  1065.              */
  1066.             if (device != NULL) {
  1067.                 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
  1068.                     if (*ap == al->addr)
  1069.                         break;
  1070.                 if (i <= 0) {
  1071.                     DEBUGMSGTL(("traceRouteCtlTable",
  1072.                                 " %s is not on interface %.32sn",
  1073.                                 source, device));
  1074.                     exit(1);
  1075.                 }
  1076.                 setsin(from, *ap);
  1077.             } else {
  1078.                 setsin(from, hi->addrs[0]);
  1079.                 if (hi->n > 1)
  1080.                     DEBUGMSGTL(("traceRouteCtlTable",
  1081.                                 " Warning: %s has multiple addresses; using %sn",
  1082.                                 source, inet_ntoa(from->sin_addr)));
  1083.             }
  1084.             freehostinfo(hi);
  1085.         }
  1086.         /*
  1087.          * Revert to non-privileged user after opening sockets 
  1088.          */
  1089.         setgid(getgid());
  1090.         setuid(getuid());
  1091.         outip->ip_src = from->sin_addr;
  1092. #ifndef IP_HDRINCL
  1093.         if (bind(sndsock, (struct sockaddr *) from, sizeof(*from)) < 0) {
  1094.             DEBUGMSGTL(("traceRouteCtlTable",
  1095.                         " bind: %sn", strerror(errno)));
  1096.             exit(1);
  1097.         }
  1098. #endif
  1099.         DEBUGMSGTL(("traceRouteCtlTable",
  1100.                     " to %s (%s)", hostname, inet_ntoa(to->sin_addr)));
  1101.         if (source)
  1102.             DEBUGMSGTL(("traceRouteCtlTable", " from %s", source));
  1103.         DEBUGMSGTL(("traceRouteCtlTable",
  1104.                     ", %d hops max, %d byte packetsn",
  1105.                     item->traceRouteCtlMaxTtl, packlen));
  1106.         (void) fflush(stderr);
  1107.         struct traceRouteResultsTable_data *StorageResults = NULL;
  1108.         netsnmp_variable_list *vars_results = NULL;
  1109.         struct traceRouteHopsTable_data *StorageHops = NULL;
  1110.         struct traceRouteHopsTable_data *temp = NULL;
  1111.         struct traceRouteHopsTable_data *current_temp = NULL;
  1112.         struct traceRouteHopsTable_data *current = NULL;
  1113.         unsigned long   index = 0;
  1114.         struct traceRouteProbeHistoryTable_data *StorageProbe = NULL;
  1115.         struct traceRouteProbeHistoryTable_data *temp_his = NULL;
  1116.         struct traceRouteProbeHistoryTable_data *current_temp_his = NULL;
  1117.         netsnmp_variable_list *vars_probe = NULL;
  1118.         snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen);     /*  traceRouteCtlOwnerIndex  */
  1119.         snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /*  traceRouteCtlTestName  */
  1120.         if ((StorageResults =
  1121.              header_complex_get(traceRouteResultsTableStorage,
  1122.                                 vars_results)) == NULL)
  1123.             return;
  1124.         snmp_free_varbind(vars_results);
  1125.         vars_results = NULL;
  1126.         for (ttl = item->traceRouteCtlInitialTtl;
  1127.              ttl <= item->traceRouteCtlMaxTtl; ++ttl) {
  1128.             u_int32_t       lastaddr = 0;
  1129.             int             gotlastaddr = 0;
  1130.             int             got_there = 0;
  1131.             int             unreachable = 0;
  1132.             int             sentfirst = 0;
  1133.             time_t          timep = 0;
  1134.             StorageResults->traceRouteResultsCurHopCount = ttl;
  1135.             if (item->traceRouteCtlCreateHopsEntries == 1) {
  1136.                 if (ttl == item->traceRouteCtlInitialTtl) {
  1137.                     int             k = 0;
  1138.                     count = traceRouteHopsTable_count(item);
  1139.                     struct traceRouteHopsTable_data *StorageTmp = NULL;
  1140.                     struct header_complex_index *hciptr2 = NULL;
  1141.                     netsnmp_variable_list *vars = NULL;
  1142.                     oid             newoid[MAX_OID_LEN];
  1143.                     size_t          newoid_len;
  1144.                     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */
  1145.                     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen);     /* traceRouteCtlTestName */
  1146.                     header_complex_generate_oid(newoid, &newoid_len, NULL,
  1147.                                                 0, vars);
  1148.                     for (hciptr2 = traceRouteHopsTableStorage;
  1149.                          hciptr2 != NULL; hciptr2 = hciptr2->next) {
  1150.                         if (snmp_oid_compare
  1151.                             (newoid, newoid_len, hciptr2->name,
  1152.                              newoid_len) == 0) {
  1153.                             StorageTmp =
  1154.                                 header_complex_extract_entry
  1155.                                 (&traceRouteHopsTableStorage, hciptr2);
  1156.                             old_HopsAddress[k] =
  1157.                                 (char *) malloc(StorageTmp->
  1158.                                                 traceRouteHopsIpTgtAddressLen
  1159.                                                 + 1);
  1160.                             if (old_HopsAddress[k] == NULL) {
  1161.                                 exit(1);
  1162.                             }
  1163.                             memdup((u_char **) & old_HopsAddress[k],
  1164.                                    StorageTmp->traceRouteHopsIpTgtAddress,
  1165.                                    StorageTmp->
  1166.                                    traceRouteHopsIpTgtAddressLen + 1);
  1167.                             old_HopsAddress[k][StorageTmp->
  1168.                                                traceRouteHopsIpTgtAddressLen]
  1169.                                 = '';
  1170.                             k++;
  1171.                             StorageTmp = NULL;
  1172.                         }
  1173.                     }
  1174.                     traceRouteHopsTable_del(item);
  1175.                     index = 0;
  1176.                 }
  1177.                 temp = SNMP_MALLOC_STRUCT(traceRouteHopsTable_data);
  1178.                 temp->traceRouteCtlOwnerIndex =
  1179.                     (char *) malloc(item->traceRouteCtlOwnerIndexLen + 1);
  1180.                 memcpy(temp->traceRouteCtlOwnerIndex,
  1181.                        item->traceRouteCtlOwnerIndex,
  1182.                        item->traceRouteCtlOwnerIndexLen + 1);
  1183.                 temp->traceRouteCtlOwnerIndex[item->
  1184.                                               traceRouteCtlOwnerIndexLen] =
  1185.                     '';
  1186.                 temp->traceRouteCtlOwnerIndexLen =
  1187.                     item->traceRouteCtlOwnerIndexLen;
  1188.                 temp->traceRouteCtlTestName =
  1189.                     (char *) malloc(item->traceRouteCtlTestNameLen + 1);
  1190.                 memcpy(temp->traceRouteCtlTestName,
  1191.                        item->traceRouteCtlTestName,
  1192.                        item->traceRouteCtlTestNameLen + 1);
  1193.                 temp->traceRouteCtlTestName[item->
  1194.                                             traceRouteCtlTestNameLen] =
  1195.                     '';
  1196.                 temp->traceRouteCtlTestNameLen =
  1197.                     item->traceRouteCtlTestNameLen;
  1198.                 /* add lock to protect */
  1199.                 pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
  1200.                 pthread_mutex_lock(&counter_mutex);
  1201.                 temp->traceRouteHopsHopIndex = ++index;
  1202.                 pthread_mutex_unlock(&counter_mutex);
  1203.                 /* endsadsadsad */
  1204.                 temp->traceRouteHopsIpTgtAddressType = 0;
  1205.                 temp->traceRouteHopsIpTgtAddress = strdup("");
  1206.                 temp->traceRouteHopsIpTgtAddressLen = 0;
  1207.                 temp->traceRouteHopsMinRtt = 0;
  1208.                 temp->traceRouteHopsMaxRtt = 0;
  1209.                 temp->traceRouteHopsAverageRtt = 0;
  1210.                 temp->traceRouteHopsRttSumOfSquares = 0;
  1211.                 temp->traceRouteHopsSentProbes = 0;
  1212.                 temp->traceRouteHopsProbeResponses = 0;
  1213.                 temp->traceRouteHopsLastGoodProbe = strdup("");
  1214.                 temp->traceRouteHopsLastGoodProbeLen = 0;
  1215.                 if (index == 1)
  1216.                     item->traceRouteHops = temp;
  1217.                 else {
  1218.                     (current_temp)->next = temp;
  1219.                 }
  1220.                 current_temp = temp;
  1221.                 if (index + 1 >= item->traceRouteCtlMaxTtl) {
  1222.                     current_temp->next = NULL;
  1223.                 }
  1224.                 if (item->traceRouteHops != NULL)
  1225.                     if (traceRouteHopsTable_add(current_temp) !=
  1226.                         SNMPERR_SUCCESS)
  1227.                         DEBUGMSGTL(("traceRouteHopsTable",
  1228.                                     "registered an entry errorn"));
  1229.             }
  1230.             register unsigned long maxRtt = 0;
  1231.             register unsigned long minRtt = 0;
  1232.             register unsigned long averageRtt = 0;
  1233.             register unsigned long sumRtt = 0;
  1234.             register unsigned long responseProbe = 0;
  1235.             register unsigned long sumOfSquare = 0;
  1236.             for (probe = 0; probe < nprobes; ++probe) {
  1237.                 register int    cc;
  1238.                 struct timeval  t1, t2;
  1239.                 struct timezone tz;
  1240.                 register struct ip *ip = NULL;
  1241.                 register unsigned long Rtt = 0;
  1242.                 if (sentfirst && pausemsecs > 0)
  1243.                     usleep(pausemsecs * 1000);
  1244.                 (void) gettimeofday(&t1, &tz);
  1245.                 send_probe(to, ++seq, ttl, &t1, outip, outudp, packlen,
  1246.                            optlen, hostname, ident, sndsock, port,
  1247.                            outdata);
  1248.                 ++sentfirst;
  1249.                 while ((cc =
  1250.                         wait_for_reply(s, from, &t1, packet,
  1251.                                        waittime)) != 0) {
  1252.                     (void) gettimeofday(&t2, &tz);
  1253.                     timep = 0;
  1254.                     time(&timep);
  1255.                     i = packet_ok(packet, cc, from, seq, ident, pmtu,
  1256.                                   port);
  1257.                     /*
  1258.                      * Skip short packet 
  1259.                      */
  1260.                     if (i == 0)
  1261.                         continue;
  1262.                     if (!gotlastaddr || from->sin_addr.s_addr != lastaddr) {
  1263.                         register struct ip *ip;
  1264.                         register int    hlen;
  1265.                         ip = (struct ip *) packet;
  1266.                         hlen = ip->ip_hl << 2;
  1267.                         cc -= hlen;
  1268.                         DEBUGMSGTL(("traceRouteCtlTable",
  1269.                                     " %s", inet_ntoa(from->sin_addr)));
  1270.                         lastaddr = from->sin_addr.s_addr;
  1271.                         ++gotlastaddr;
  1272.                     }
  1273.                     Rtt = deltaT(&t1, &t2);
  1274.                     responseProbe = responseProbe + 1;
  1275.                     if (probe == 0) {
  1276.                         minRtt = Rtt;
  1277.                         maxRtt = Rtt;
  1278.                         averageRtt = Rtt;
  1279.                         sumRtt = Rtt;
  1280.                         sumOfSquare = Rtt * Rtt;
  1281.                     } else {
  1282.                         if (Rtt < minRtt)
  1283.                             minRtt = Rtt;
  1284.                         if (Rtt > maxRtt)
  1285.                             maxRtt = Rtt;
  1286.                         sumRtt = (sumRtt) + Rtt;
  1287.                         averageRtt =
  1288.                             round((double) (sumRtt) /
  1289.                                   (double) responseProbe);
  1290.                         sumOfSquare = sumOfSquare + Rtt * Rtt;
  1291.                     }
  1292.                     StorageResults->traceRouteResultsCurProbeCount =
  1293.                         probe + 1;
  1294.                     if (i == -2) {
  1295. #ifndef ARCHAIC
  1296.                         ip = (struct ip *) packet;
  1297.                         if (ip->ip_ttl <= 1)
  1298.                             Printf(" !");
  1299. #endif
  1300.                         ++got_there;
  1301.                         break;
  1302.                     }
  1303.                     /*
  1304.                      * time exceeded in transit 
  1305.                      */
  1306.                     if (i == -1)
  1307.                         break;
  1308.                     code = i - 1;
  1309.                     switch (code) {
  1310.                     case ICMP_UNREACH_PORT:
  1311. #ifndef ARCHAIC
  1312.                         ip = (struct ip *) packet;
  1313.                         if (ip->ip_ttl <= 1)
  1314.                             Printf(" !");
  1315. #endif
  1316.                         ++got_there;
  1317.                         break;
  1318.                     case ICMP_UNREACH_NET:
  1319.                         ++unreachable;
  1320.                         Printf(" !N");
  1321.                         break;
  1322.                     case ICMP_UNREACH_HOST:
  1323.                         ++unreachable;
  1324.                         Printf(" !H");
  1325.                         break;
  1326.                     case ICMP_UNREACH_PROTOCOL:
  1327.                         ++got_there;
  1328.                         Printf(" !P");
  1329.                         break;
  1330.                     case ICMP_UNREACH_NEEDFRAG:
  1331.                         ++unreachable;
  1332.                         Printf(" !F-%d", pmtu);
  1333.                         break;
  1334.                     case ICMP_UNREACH_SRCFAIL:
  1335.                         ++unreachable;
  1336.                         Printf(" !S");
  1337.                         break;
  1338.                     case ICMP_UNREACH_FILTER_PROHIB:
  1339.                         ++unreachable;
  1340.                         Printf(" !X");
  1341.                         break;
  1342.                     case ICMP_UNREACH_HOST_PRECEDENCE:
  1343.                         ++unreachable;
  1344.                         Printf(" !V");
  1345.                         break;
  1346.                     case ICMP_UNREACH_PRECEDENCE_CUTOFF:
  1347.                         ++unreachable;
  1348.                         Printf(" !C");
  1349.                         break;
  1350.                     default:
  1351.                         ++unreachable;
  1352.                         Printf(" !<%d>", code);
  1353.                         break;
  1354.                     }
  1355.                     break;
  1356.                 }
  1357.                 if (cc == 0) {
  1358.                     timep = 0;
  1359.                     time(&timep);
  1360.                     Printf(" *");
  1361.                     Rtt = (item->traceRouteCtlTimeOut) * 1000;
  1362.                 }
  1363.                 if (item->traceRouteCtlMaxRows != 0) {
  1364.                     temp_his =
  1365.                         SNMP_MALLOC_STRUCT
  1366.                         (traceRouteProbeHistoryTable_data);
  1367.                     temp_his->traceRouteCtlOwnerIndex =
  1368.                         (char *) malloc(item->traceRouteCtlOwnerIndexLen +
  1369.                                         1);
  1370.                     memcpy(temp_his->traceRouteCtlOwnerIndex,
  1371.                            item->traceRouteCtlOwnerIndex,
  1372.                            item->traceRouteCtlOwnerIndexLen + 1);
  1373.                     temp_his->traceRouteCtlOwnerIndex[item->
  1374.                                                       traceRouteCtlOwnerIndexLen]
  1375.                         = '';
  1376.                     temp_his->traceRouteCtlOwnerIndexLen =
  1377.                         item->traceRouteCtlOwnerIndexLen;
  1378.                     temp_his->traceRouteCtlTestName =
  1379.                         (char *) malloc(item->traceRouteCtlTestNameLen +
  1380.                                         1);
  1381.                     memcpy(temp_his->traceRouteCtlTestName,
  1382.                            item->traceRouteCtlTestName,
  1383.                            item->traceRouteCtlTestNameLen + 1);
  1384.                     temp_his->traceRouteCtlTestName[item->
  1385.                                                     traceRouteCtlTestNameLen]
  1386.                         = '';
  1387.                     temp_his->traceRouteCtlTestNameLen =
  1388.                         item->traceRouteCtlTestNameLen;
  1389.                     /* add lock to protect */
  1390.                     pthread_mutex_t counter_mutex =
  1391.                         PTHREAD_MUTEX_INITIALIZER;
  1392.                     pthread_mutex_lock(&counter_mutex);
  1393.                     if (item->traceRouteProbeHistoryMaxIndex >=
  1394.                         (unsigned long) (2147483647))
  1395.                         item->traceRouteProbeHistoryMaxIndex = 0;
  1396.                     temp_his->traceRouteProbeHistoryIndex =
  1397.                         ++(item->traceRouteProbeHistoryMaxIndex);
  1398.                     pthread_mutex_unlock(&counter_mutex);
  1399.                     /* endsadsadsad */
  1400.                     temp_his->traceRouteProbeHistoryHopIndex = ttl;
  1401.                     temp_his->traceRouteProbeHistoryProbeIndex = probe + 1;
  1402.                     temp_his->traceRouteProbeHistoryHAddrType = 1;
  1403.                     temp_his->traceRouteProbeHistoryHAddr =
  1404.                         (char *) malloc(strlen(inet_ntoa(from->sin_addr)) +
  1405.                                         1);
  1406.                     strcpy(temp_his->traceRouteProbeHistoryHAddr,
  1407.                            (inet_ntoa(from->sin_addr)));
  1408.                     temp_his->
  1409.                         traceRouteProbeHistoryHAddr[strlen
  1410.                                                     (inet_ntoa
  1411.                                                      (from->sin_addr))] =
  1412.                         '';
  1413.                     temp_his->traceRouteProbeHistoryHAddrLen =
  1414.                         strlen(inet_ntoa(from->sin_addr));
  1415.                     temp_his->traceRouteProbeHistoryResponse = Rtt;
  1416.                     temp_his->traceRouteProbeHistoryStatus = 1;
  1417.                     temp_his->traceRouteProbeHistoryLastRC = 0;
  1418.                     temp_his->traceRouteProbeHistoryTime =
  1419.                         (char *) malloc(strlen(asctime(gmtime(&timep))));
  1420.                     temp_his->traceRouteProbeHistoryTime =
  1421.                         strdup(asctime(gmtime(&timep)));
  1422.                     temp_his->
  1423.                         traceRouteProbeHistoryTime[strlen
  1424.                                                    (asctime
  1425.                                                     (gmtime(&timep))) -
  1426.                                                    1] = '';
  1427.                     temp_his->traceRouteProbeHistoryTimeLen =
  1428.                         strlen(asctime(gmtime(&timep))) - 1;
  1429.                     if (probe == 0)
  1430.                         item->traceRouteProbeHis = temp_his;
  1431.                     else {
  1432.                         (current_temp_his)->next = temp_his;
  1433.                     }
  1434.                     current_temp_his = temp_his;
  1435.                     if (probe + 1 >= nprobes) {
  1436.                         current_temp_his->next = NULL;
  1437.                     }
  1438.                     if (item->traceRouteProbeHis != NULL)
  1439.                         if (traceRouteProbeHistoryTable_count(item) <
  1440.                             item->traceRouteCtlMaxRows) {
  1441.                             if (traceRouteProbeHistoryTable_add
  1442.                                 (current_temp_his) != SNMPERR_SUCCESS)
  1443.                                 DEBUGMSGTL(("traceRouteProbeHistoryTable",
  1444.                                             "registered an entry errorn"));
  1445.                         } else {
  1446.                             traceRouteProbeHistoryTable_delLast(item);
  1447.                             if (traceRouteProbeHistoryTable_add
  1448.                                 (current_temp_his) != SNMPERR_SUCCESS)
  1449.                                 DEBUGMSGTL(("traceRouteProbeHistoryTable",
  1450.                                             "registered an entry errorn"));
  1451.                         }
  1452.                 }
  1453.                 if (item->traceRouteCtlCreateHopsEntries == 1) {
  1454.                     netsnmp_variable_list *vars_hops = NULL;
  1455.                     snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen);    /*  traceRouteCtlOwnerIndex  */
  1456.                     snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen);        /*  traceRouteCtlTestName  */
  1457.                     snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_UNSIGNED, (char *) &index, sizeof(index));       /*  traceRouteHopsIndex  */
  1458.                     if ((current =
  1459.                          header_complex_get(traceRouteHopsTableStorage,
  1460.                                             vars_hops)) == NULL)
  1461.                         return;
  1462.                     snmp_free_varbind(vars_hops);
  1463.                     vars_hops = NULL;
  1464.                     current->traceRouteHopsIpTgtAddressType = 1;
  1465.                     current->traceRouteHopsIpTgtAddress =
  1466.                         (char *) malloc(strlen(inet_ntoa(from->sin_addr)) +
  1467.                                         1);
  1468.                     current->traceRouteHopsIpTgtAddress =
  1469.                         strdup(inet_ntoa(from->sin_addr));
  1470.                     current->
  1471.                         traceRouteHopsIpTgtAddress[strlen
  1472.                                                    (inet_ntoa
  1473.                                                     (from->sin_addr))] =
  1474.                         '';
  1475.                     current->traceRouteHopsIpTgtAddressLen =
  1476.                         strlen(inet_ntoa(from->sin_addr));
  1477.                     if (count != 0) {
  1478.                         if (strcmp
  1479.                             (old_HopsAddress[index - 1],
  1480.                              current->traceRouteHopsIpTgtAddress) != 0)
  1481.                             flag = 1;
  1482.                     }
  1483.                     current->traceRouteHopsIpTgtAddressLen =
  1484.                         strlen(inet_ntoa(from->sin_addr));
  1485.                     current->traceRouteHopsMinRtt = minRtt;
  1486.                     current->traceRouteHopsMaxRtt = maxRtt;
  1487.                     current->traceRouteHopsAverageRtt = averageRtt;
  1488.                     current->traceRouteHopsRttSumOfSquares = sumOfSquare;
  1489.                     current->traceRouteHopsSentProbes = probe + 1;
  1490.                     current->traceRouteHopsProbeResponses = responseProbe;
  1491.                     current->traceRouteHopsLastGoodProbe =
  1492.                         (char *) malloc(strlen(asctime(gmtime(&timep))));
  1493.                     current->traceRouteHopsLastGoodProbe =
  1494.                         strdup(asctime(gmtime(&timep)));
  1495.                     current->
  1496.                         traceRouteHopsLastGoodProbe[strlen
  1497.                                                     (asctime
  1498.                                                      (gmtime(&timep))) -
  1499.                                                     1] = '';
  1500.                     current->traceRouteHopsLastGoodProbeLen =
  1501.                         strlen(asctime(gmtime(&timep))) - 1;
  1502.                 }
  1503.                 (void) fflush(stdout);
  1504.             }
  1505.             putchar('n');
  1506.             if (got_there
  1507.                 || (unreachable > 0 && unreachable >= nprobes - 1)) {
  1508.                 if (got_there != 0) {
  1509.                     StorageResults->traceRouteResultsTestAttempts =
  1510.                         StorageResults->traceRouteResultsTestAttempts + 1;
  1511.                     StorageResults->traceRouteResultsTestSuccesses =
  1512.                         StorageResults->traceRouteResultsTestSuccesses + 1;
  1513.                     StorageResults->traceRouteResultsLastGoodPath =
  1514.                         (char *) malloc(strlen(asctime(gmtime(&timep))) -
  1515.                                         1);
  1516.                     StorageResults->traceRouteResultsLastGoodPath =
  1517.                         strdup(asctime(gmtime(&timep)));
  1518.                     StorageResults->
  1519.                         traceRouteResultsLastGoodPath[strlen
  1520.                                                       (asctime
  1521.                                                        (gmtime(&timep))) -
  1522.                                                       1] = '';
  1523.                     StorageResults->traceRouteResultsLastGoodPathLen =
  1524.                         strlen(asctime(gmtime(&timep))) - 1;
  1525.                     if ((item->
  1526.                          traceRouteCtlTrapGeneration[0] &
  1527.                          TRACEROUTETRAPGENERATION_TESTCOMPLETED) != 0) {
  1528.                         DEBUGMSGTL(("traceRouteProbeHistoryTable",
  1529.                                     "TEST completed!n"));
  1530.                         send_traceRoute_trap(item, traceRouteTestCompleted,
  1531.                                              sizeof
  1532.                                              (traceRouteTestCompleted) /
  1533.                                              sizeof(oid));
  1534.                     }
  1535.                 }
  1536.                 else {
  1537.                     StorageResults->traceRouteResultsTestAttempts =
  1538.                         StorageResults->traceRouteResultsTestAttempts + 1;
  1539.                     if ((item->
  1540.                          traceRouteCtlTrapGeneration[0] &
  1541.                          TRACEROUTETRAPGENERATION_TESTFAILED) != 0) {
  1542.                         DEBUGMSGTL(("traceRouteProbeHistoryTable",
  1543.                                     "test Failed!n"));
  1544.                         send_ping_trap(item, traceRouteTestFailed,
  1545.                                        sizeof(traceRouteTestFailed) /
  1546.                                        sizeof(oid));
  1547.                     }
  1548.                 }
  1549.                 break;
  1550.             } else if (ttl == item->traceRouteCtlMaxTtl
  1551.                        && (probe + 1) == nprobes) {
  1552.                 StorageResults->traceRouteResultsTestAttempts =
  1553.                     StorageResults->traceRouteResultsTestAttempts + 1;
  1554.                 if ((item->
  1555.                      traceRouteCtlTrapGeneration[0] &
  1556.                      TRACEROUTETRAPGENERATION_TESTFAILED) != 0) {
  1557.                     DEBUGMSGTL(("traceRouteProbeHistoryTable",
  1558.                                 "test Failed!n"));
  1559.                     send_ping_trap(item, traceRouteTestFailed,
  1560.                                    sizeof(traceRouteTestFailed) /
  1561.                                    sizeof(oid));
  1562.                 }
  1563.             }
  1564.         }
  1565.         if (flag == 1) {
  1566.             DEBUGMSGTL(("traceRouteProbeHistoryTable", "path changed!n"));
  1567.             send_traceRoute_trap(item, traceRoutePathChange,
  1568.                                  sizeof(traceRoutePathChange) /
  1569.                                  sizeof(oid));
  1570.         }
  1571.         int             k = 0;
  1572.         for (k = 0; k < count; k++) {
  1573.             free(old_HopsAddress[k]);
  1574.             old_HopsAddress[k] = NULL;
  1575.         }
  1576.     }
  1577.     if (item->traceRouteCtlTargetAddressType == 2) {
  1578.         static char     SNAPSHOT[] = "020124";
  1579.         int             icmp_sock = 0;  /* receive (icmp) socket file descriptor */
  1580.         int             sndsock = 0;    /* send (udp) socket file descriptor */
  1581.         struct timezone tz;     /* leftover */
  1582.         struct sockaddr_in6 whereto;    /* Who to try to reach */
  1583.         struct sockaddr_in6 saddr;
  1584.         struct sockaddr_in6 firsthop;
  1585.         char           *source = NULL;
  1586.         char           *device = NULL;
  1587.         char           *hostname = NULL;
  1588.         pid_t           ident = 0;
  1589.         u_short         port = 32768 + 666;     /* start udp dest port # for probe packets */
  1590.         int             options = 0;    /* socket options */
  1591.         int             verbose = 0;
  1592.         int             waittime = 5;   /* time to wait for response (in seconds) */
  1593.         int             nflag = 0;      /* print addresses numerically */
  1594.         char           *sendbuff = NULL;
  1595.         int             datalen = sizeof(struct pkt_format);
  1596.         u_char          packet[512];    /* last inbound (icmp) packet */
  1597.         char            pa[64];
  1598.         struct hostent *hp = NULL;
  1599.         struct sockaddr_in6 from, *to = NULL;
  1600.         int             ch = 0, i = 0, on = 0, probe = 0, seq = 0, tos =
  1601.             0, ttl = 0;
  1602.         int             socket_errno = 0;
  1603.         icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
  1604.         socket_errno = errno;
  1605.         setuid(getuid());
  1606.         on = 1;
  1607.         seq = tos = 0;
  1608.         to = (struct sockaddr_in6 *) &whereto;
  1609.         hostname =
  1610.             (char *) malloc(item->traceRouteCtlTargetAddressLen + 1);
  1611.         memcpy(hostname, item->traceRouteCtlTargetAddress,
  1612.                item->traceRouteCtlTargetAddressLen + 1);
  1613.         hostname[item->traceRouteCtlTargetAddressLen] = '';
  1614.         setlinebuf(stdout);
  1615.         (void) bzero((char *) &whereto, sizeof(struct sockaddr_in6));
  1616.         to->sin6_family = AF_INET6;
  1617.         to->sin6_port = htons(port);
  1618.         if (inet_pton(AF_INET6, hostname, &to->sin6_addr) > 0) {
  1619.             NULL;
  1620.         } else {
  1621.             hp = gethostbyname2(hostname, AF_INET6);
  1622.             if (hp != NULL) {
  1623.                 memmove((caddr_t) & to->sin6_addr, hp->h_addr, 16);
  1624.                 hostname = (char *) hp->h_name;
  1625.             } else {
  1626.                 (void) fprintf(stderr,
  1627.                                "traceroute: unknown host %sn", hostname);
  1628.                 return;
  1629.             }
  1630.         }
  1631.         firsthop = *to;
  1632.         datalen = item->traceRouteCtlDataSize;
  1633.         if (datalen < (int) sizeof(struct pkt_format)
  1634.             || datalen >= MAXPACKET) {
  1635.             Fprintf(stderr,
  1636.                     "traceroute: packet size must be %d <= s < %d.n",
  1637.                     (int) sizeof(struct pkt_format), MAXPACKET);
  1638.             datalen = 16;
  1639.         }
  1640.         ident = getpid();
  1641.         sendbuff = malloc(datalen);
  1642.         if (sendbuff == NULL) {
  1643.             fprintf(stderr, "malloc failedn");
  1644.             return;
  1645.         }
  1646.         if (icmp_sock < 0) {
  1647.             errno = socket_errno;
  1648.             perror("traceroute6: icmp socket");
  1649.             return;
  1650.         }
  1651.         if (options & SO_DEBUG)
  1652.             setsockopt(icmp_sock, SOL_SOCKET, SO_DEBUG,
  1653.                        (char *) &on, sizeof(on));
  1654.         if (options & SO_DONTROUTE)
  1655.             setsockopt(icmp_sock, SOL_SOCKET, SO_DONTROUTE,
  1656.                        (char *) &on, sizeof(on));
  1657.         if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
  1658.             perror("traceroute: UDP socket");
  1659.             return;
  1660.         }
  1661. #ifdef SO_SNDBUF
  1662.         if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *) &datalen,
  1663.                        sizeof(datalen)) < 0) {
  1664.             perror("traceroute: SO_SNDBUF");
  1665.             return;
  1666.         }
  1667. #endif                          /* SO_SNDBUF */
  1668.         if (options & SO_DEBUG)
  1669.             (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
  1670.                               (char *) &on, sizeof(on));
  1671.         if (options & SO_DONTROUTE)
  1672.             (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
  1673.                               (char *) &on, sizeof(on));
  1674.         if (source == NULL) {
  1675.             int             alen;
  1676.             int             probe_fd = socket(AF_INET6, SOCK_DGRAM, 0);
  1677.             if (probe_fd < 0) {
  1678.                 perror("socket");
  1679.                 return;
  1680.             }
  1681.             if (device) {
  1682.                 if (setsockopt
  1683.                     (probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device,
  1684.                      strlen(device) + 1) == -1)
  1685.                     perror("WARNING: interface is ignored");
  1686.             }
  1687.             firsthop.sin6_port = htons(1025);
  1688.             if (connect
  1689.                 (probe_fd, (struct sockaddr *) &firsthop,
  1690.                  sizeof(firsthop)) == -1) {
  1691.                 perror("connect");
  1692.                 return;
  1693.             }
  1694.             alen = sizeof(saddr);
  1695.             if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) ==
  1696.                 -1) {
  1697.                 perror("getsockname");
  1698.                 return;
  1699.             }
  1700.             saddr.sin6_port = 0;
  1701.             close(probe_fd);
  1702.         } else {
  1703.             (void) bzero((char *) &saddr, sizeof(struct sockaddr_in6));
  1704.             saddr.sin6_family = AF_INET6;
  1705.             if (inet_pton(AF_INET6, source, &saddr.sin6_addr) < 0) {
  1706.                 Printf("traceroute: unknown addr %sn", source);
  1707.                 return;
  1708.             }
  1709.         }
  1710.         if (bind(sndsock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
  1711.             perror("traceroute: bind sending socket");
  1712.             return;
  1713.         }
  1714.         if (bind(icmp_sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
  1715.             perror("traceroute: bind icmp6 socket");
  1716.             return;
  1717.         }
  1718.         Fprintf(stderr, "traceroute to %s (%s)", hostname,
  1719.                 inet_ntop(AF_INET6, &to->sin6_addr, pa, 64));
  1720.         Fprintf(stderr, " from %s",
  1721.                 inet_ntop(AF_INET6, &saddr.sin6_addr, pa, 64));
  1722.         Fprintf(stderr, ", %d hops max, %d byte packetsn",
  1723.                 item->traceRouteCtlMaxTtl, datalen);
  1724.         (void) fflush(stderr);
  1725.         struct traceRouteResultsTable_data *StorageResults = NULL;
  1726.         netsnmp_variable_list *vars_results = NULL;
  1727.         struct traceRouteHopsTable_data *StorageHops = NULL;
  1728.         struct traceRouteHopsTable_data *temp = NULL;
  1729.         struct traceRouteHopsTable_data *current_temp = NULL;
  1730.         struct traceRouteHopsTable_data *current = NULL;
  1731.         unsigned long   index = 0;
  1732.         struct traceRouteProbeHistoryTable_data *StorageProbe = NULL;
  1733.         struct traceRouteProbeHistoryTable_data *temp_his = NULL;
  1734.         struct traceRouteProbeHistoryTable_data *current_temp_his = NULL;
  1735.         netsnmp_variable_list *vars_probe = NULL;
  1736.         snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen);     /*  traceRouteCtlOwnerIndex  */
  1737.         snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /*  traceRouteCtlTestName  */
  1738.         if ((StorageResults =
  1739.              header_complex_get(traceRouteResultsTableStorage,
  1740.                                 vars_results)) == NULL)
  1741.             return;
  1742.         snmp_free_varbind(vars_results);
  1743.         vars_results = NULL;
  1744.         for (ttl = item->traceRouteCtlInitialTtl;
  1745.              ttl <= item->traceRouteCtlMaxTtl; ++ttl) {
  1746.             struct in6_addr lastaddr = { {{0,}} };
  1747.             int             got_there = 0;
  1748.             int             unreachable = 0;
  1749.             time_t          timep = 0;
  1750.             Printf("%2d ", ttl);
  1751.             StorageResults->traceRouteResultsCurHopCount = ttl;
  1752.             if (item->traceRouteCtlCreateHopsEntries == 1) {
  1753.                 if (ttl == item->traceRouteCtlInitialTtl) {
  1754.                     int             k = 0;
  1755.                     count = traceRouteHopsTable_count(item);
  1756.                     struct traceRouteHopsTable_data *StorageTmp = NULL;
  1757.                     struct header_complex_index *hciptr2 = NULL;
  1758.                     netsnmp_variable_list *vars = NULL;
  1759.                     oid             newoid[MAX_OID_LEN];
  1760.                     size_t          newoid_len;
  1761.                     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */
  1762.                     snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen);     /* traceRouteCtlTestName */
  1763.                     header_complex_generate_oid(newoid, &newoid_len, NULL,
  1764.                                                 0, vars);
  1765.                     snmp_free_varbind(vars);
  1766.                     vars = NULL;
  1767.                     for (hciptr2 = traceRouteHopsTableStorage;
  1768.                          hciptr2 != NULL; hciptr2 = hciptr2->next) {
  1769.                         if (snmp_oid_compare
  1770.                             (newoid, newoid_len, hciptr2->name,
  1771.                              newoid_len) == 0) {
  1772.                             StorageTmp =
  1773.                                 header_complex_extract_entry
  1774.                                 (&traceRouteHopsTableStorage, hciptr2);
  1775.                             old_HopsAddress[k] =
  1776.                                 (char *) malloc(StorageTmp->
  1777.                                                 traceRouteHopsIpTgtAddressLen
  1778.                                                 + 1);
  1779.                             if (old_HopsAddress[k] == NULL) {
  1780.                                 exit(1);
  1781.                             }
  1782.                             memdup((u_char **) & old_HopsAddress[k],
  1783.                                    StorageTmp->traceRouteHopsIpTgtAddress,
  1784.                                    StorageTmp->
  1785.                                    traceRouteHopsIpTgtAddressLen + 1);
  1786.                             old_HopsAddress[k][StorageTmp->
  1787.                                                traceRouteHopsIpTgtAddressLen]
  1788.                                 = '';
  1789.                             k++;
  1790.                         }
  1791.                     }
  1792.                     traceRouteHopsTable_del(item);
  1793.                     index = 0;
  1794.                 }
  1795.                 temp = SNMP_MALLOC_STRUCT(traceRouteHopsTable_data);
  1796.                 temp->traceRouteCtlOwnerIndex =
  1797.                     (char *) malloc(item->traceRouteCtlOwnerIndexLen + 1);
  1798.                 memcpy(temp->traceRouteCtlOwnerIndex,
  1799.                        item->traceRouteCtlOwnerIndex,
  1800.                        item->traceRouteCtlOwnerIndexLen + 1);
  1801.                 temp->traceRouteCtlOwnerIndex[item->
  1802.                                               traceRouteCtlOwnerIndexLen] =
  1803.                     '';
  1804.                 temp->traceRouteCtlOwnerIndexLen =
  1805.                     item->traceRouteCtlOwnerIndexLen;
  1806.                 temp->traceRouteCtlTestName =
  1807.                     (char *) malloc(item->traceRouteCtlTestNameLen + 1);
  1808.                 memcpy(temp->traceRouteCtlTestName,
  1809.                        item->traceRouteCtlTestName,
  1810.                        item->traceRouteCtlTestNameLen + 1);
  1811.                 temp->traceRouteCtlTestName[item->
  1812.                                             traceRouteCtlTestNameLen] =
  1813.                     '';
  1814.                 temp->traceRouteCtlTestNameLen =
  1815.                     item->traceRouteCtlTestNameLen;
  1816.                 /* add lock to protect */
  1817.                 pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
  1818.                 pthread_mutex_lock(&counter_mutex);
  1819.                 temp->traceRouteHopsHopIndex = ++index;
  1820.                 pthread_mutex_unlock(&counter_mutex);
  1821.                 /* endsadsadsad */
  1822.                 temp->traceRouteHopsIpTgtAddressType = 0;
  1823.                 temp->traceRouteHopsIpTgtAddress = strdup("");
  1824.                 temp->traceRouteHopsIpTgtAddressLen = 0;
  1825.                 temp->traceRouteHopsMinRtt = 0;
  1826.                 temp->traceRouteHopsMaxRtt = 0;
  1827.                 temp->traceRouteHopsAverageRtt = 0;
  1828.                 temp->traceRouteHopsRttSumOfSquares = 0;
  1829.                 temp->traceRouteHopsSentProbes = 0;
  1830.                 temp->traceRouteHopsProbeResponses = 0;
  1831.                 temp->traceRouteHopsLastGoodProbe = strdup("");
  1832.                 temp->traceRouteHopsLastGoodProbeLen = 0;
  1833.                 if (index == 1)
  1834.                     item->traceRouteHops = temp;
  1835.                 else {
  1836.                     (current_temp)->next = temp;
  1837.                 }
  1838.                 current_temp = temp;
  1839.                 if (index >= item->traceRouteCtlMaxTtl) {
  1840.                     current_temp->next = NULL;
  1841.                 }
  1842.                 if (item->traceRouteHops != NULL)
  1843.                     if (traceRouteHopsTable_add(current_temp) !=
  1844.                         SNMPERR_SUCCESS)
  1845.                         DEBUGMSGTL(("traceRouteHopsTable",
  1846.                                     "registered an entry errorn"));
  1847.             }
  1848.             register unsigned long maxRtt = 0;
  1849.             register unsigned long minRtt = 0;
  1850.             register unsigned long averageRtt = 0;
  1851.             register unsigned long sumRtt = 0;
  1852.             register unsigned long responseProbe = 0;
  1853.             register unsigned long sumOfSquare = 0;
  1854.             for (probe = 0; probe < nprobes; ++probe) {
  1855.                 int             cc = 0, reset_timer = 0;
  1856.                 struct timeval  t1, t2;
  1857.                 struct timezone tz;
  1858.                 register unsigned long Rtt = 0;
  1859.                 gettimeofday(&t1, &tz);
  1860.                 send_probe_v6(++seq, ttl, sendbuff, ident, &tz, sndsock,
  1861.                               datalen, &whereto, hostname);
  1862.                 reset_timer = 1;
  1863.                 while ((cc =
  1864.                         wait_for_reply_v6(icmp_sock, &from, reset_timer,
  1865.                                           waittime, icmp_sock,
  1866.                                           packet)) != 0) {
  1867.                     gettimeofday(&t2, &tz);
  1868.                     timep = 0;
  1869.                     time(&timep);
  1870.                     if ((i =
  1871.                          packet_ok_v6(packet, cc, &from, seq, &t1,
  1872.                                       ident))) {
  1873.                         reset_timer = 1;
  1874.                         if (memcmp
  1875.                             (&from.sin6_addr, &lastaddr,
  1876.                              sizeof(struct in6_addr))) {
  1877.                             memcpy(&lastaddr,
  1878.                                    &from.sin6_addr,
  1879.                                    sizeof(struct in6_addr));
  1880.                         }
  1881.                         Rtt = deltaT(&t1, &t2);
  1882.                         responseProbe = responseProbe + 1;
  1883.                         if (probe == 0) {
  1884.                             minRtt = Rtt;
  1885.                             maxRtt = Rtt;
  1886.                             averageRtt = Rtt;
  1887.                             sumRtt = Rtt;
  1888.                             sumOfSquare = Rtt * Rtt;
  1889.                         } else {
  1890.                             if (Rtt < minRtt)
  1891.                                 minRtt = Rtt;
  1892.                             if (Rtt > maxRtt)
  1893.                                 maxRtt = Rtt;
  1894.                             sumRtt = (sumRtt) + Rtt;
  1895.                             averageRtt =
  1896.                                 round((double) (sumRtt) /
  1897.                                       (double) responseProbe);
  1898.                             sumOfSquare = sumOfSquare + Rtt * Rtt;
  1899.                         }
  1900.                         StorageResults->traceRouteResultsCurProbeCount =
  1901.                             probe + 1;
  1902.                         switch (i - 1) {
  1903.                         case ICMPV6_PORT_UNREACH:
  1904.                             ++got_there;
  1905.                             break;
  1906.                         case ICMPV6_NOROUTE:
  1907.                             ++unreachable;
  1908.                             Printf(" !N");
  1909.                             break;
  1910.                         case ICMPV6_ADDR_UNREACH:
  1911.                             ++unreachable;
  1912.                             Printf(" !H");
  1913.                             break;
  1914.                         case ICMPV6_ADM_PROHIBITED:
  1915.                             ++unreachable;
  1916.                             Printf(" !S");
  1917.                             break;
  1918.                         }
  1919.                         break;
  1920.                     } else
  1921.                         reset_timer = 0;
  1922.                 }
  1923.                 if (cc == 0) {
  1924.                     timep = 0;
  1925.                     time(&timep);
  1926.                     Printf(" *");
  1927.                     Rtt = (item->traceRouteCtlTimeOut) * 1000;
  1928.                 }
  1929.                 if (item->traceRouteCtlMaxRows != 0) {
  1930.                     temp_his =
  1931.                         SNMP_MALLOC_STRUCT
  1932.                         (traceRouteProbeHistoryTable_data);
  1933.                     temp_his->traceRouteCtlOwnerIndex =
  1934.                         (char *) malloc(item->traceRouteCtlOwnerIndexLen +
  1935.                                         1);
  1936.                     memcpy(temp_his->traceRouteCtlOwnerIndex,
  1937.                            item->traceRouteCtlOwnerIndex,
  1938.                            item->traceRouteCtlOwnerIndexLen + 1);
  1939.                     temp_his->traceRouteCtlOwnerIndex[item->
  1940.                                                       traceRouteCtlOwnerIndexLen]
  1941.                         = '';
  1942.                     temp_his->traceRouteCtlOwnerIndexLen =
  1943.                         item->traceRouteCtlOwnerIndexLen;
  1944.                     temp_his->traceRouteCtlTestName =
  1945.                         (char *) malloc(item->traceRouteCtlTestNameLen +
  1946.                                         1);
  1947.                     memcpy(temp_his->traceRouteCtlTestName,
  1948.                            item->traceRouteCtlTestName,
  1949.                            item->traceRouteCtlTestNameLen + 1);
  1950.                     temp_his->traceRouteCtlTestName[item->
  1951.                                                     traceRouteCtlTestNameLen]
  1952.                         = '';
  1953.                     temp_his->traceRouteCtlTestNameLen =
  1954.                         item->traceRouteCtlTestNameLen;
  1955.                     /* add lock to protect */
  1956.                     pthread_mutex_t counter_mutex =
  1957.                         PTHREAD_MUTEX_INITIALIZER;
  1958.                     pthread_mutex_lock(&counter_mutex);
  1959.                     if (item->traceRouteProbeHistoryMaxIndex >=
  1960.                         (unsigned long) (2147483647))
  1961.                         item->traceRouteProbeHistoryMaxIndex = 0;
  1962.                     temp_his->traceRouteProbeHistoryIndex =
  1963.                         ++(item->traceRouteProbeHistoryMaxIndex);
  1964.                     pthread_mutex_unlock(&counter_mutex);
  1965.                     /* endsadsadsad */
  1966.                     temp_his->traceRouteProbeHistoryHopIndex = ttl;
  1967.                     temp_his->traceRouteProbeHistoryProbeIndex = probe + 1;
  1968.                     temp_his->traceRouteProbeHistoryHAddrType = 2;
  1969.                     temp_his->traceRouteProbeHistoryHAddr =
  1970.                         (char *)
  1971.                         malloc(strlen
  1972.                                (inet_ntop
  1973.                                 (AF_INET6, &from.sin6_addr, pa, 64)) + 1);
  1974.                     temp_his->traceRouteProbeHistoryHAddr =
  1975.                         strdup(inet_ntop
  1976.                                (AF_INET6, &from.sin6_addr, pa, 64));
  1977.                     temp_his->
  1978.                         traceRouteProbeHistoryHAddr[strlen
  1979.                                                     (inet_ntop
  1980.                                                      (AF_INET6,
  1981.                                                       &from.sin6_addr, pa,
  1982.                                                       64))] = '';
  1983.                     temp_his->traceRouteProbeHistoryHAddrLen =
  1984.                         strlen(inet_ntop
  1985.                                (AF_INET6, &from.sin6_addr, pa, 64));
  1986.                     temp_his->traceRouteProbeHistoryResponse = Rtt;
  1987.                     temp_his->traceRouteProbeHistoryStatus = 1;
  1988.                     temp_his->traceRouteProbeHistoryLastRC = 0;
  1989.                     temp_his->traceRouteProbeHistoryTime =
  1990.                         (char *) malloc(strlen(asctime(gmtime(&timep))));
  1991.                     temp_his->traceRouteProbeHistoryTime =
  1992.                         strdup(asctime(gmtime(&timep)));
  1993.                     temp_his->
  1994.                         traceRouteProbeHistoryTime[strlen
  1995.                                                    (asctime
  1996.                                                     (gmtime(&timep))) -
  1997.                                                    1] = '';
  1998.                     temp_his->traceRouteProbeHistoryTimeLen =
  1999.                         strlen(asctime(gmtime(&timep))) - 1;
  2000.                     if (probe == 0)
  2001.                         item->traceRouteProbeHis = temp_his;
  2002.                     else {
  2003.                         (current_temp_his)->next = temp_his;
  2004.                     }
  2005.                     current_temp_his = temp_his;
  2006.                     if (probe + 1 >= nprobes) {
  2007.                         current_temp_his->next = NULL;
  2008.                     }
  2009.                     if (item->traceRouteProbeHis != NULL)
  2010.                         if (traceRouteProbeHistoryTable_count(item) <
  2011.                             item->traceRouteCtlMaxRows) {
  2012.                             if (traceRouteProbeHistoryTable_add
  2013.                                 (current_temp_his) != SNMPERR_SUCCESS)
  2014.                                 DEBUGMSGTL(("traceRouteProbeHistoryTable",
  2015.                                             "registered an entry errorn"));
  2016.                         } else {
  2017.                             traceRouteProbeHistoryTable_delLast(item);
  2018.                             if (traceRouteProbeHistoryTable_add
  2019.                                 (current_temp_his) != SNMPERR_SUCCESS)
  2020.                                 DEBUGMSGTL(("traceRouteProbeHistoryTable",
  2021.                                             "registered an entry errorn"));
  2022.                         }
  2023.                 }
  2024.                 if (item->traceRouteCtlCreateHopsEntries == 1) {
  2025.                     netsnmp_variable_list *vars_hops = NULL;
  2026.                     snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen);    /*  traceRouteCtlOwnerIndex  */
  2027.                     snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen);        /*  traceRouteCtlTestName  */
  2028.                     snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_UNSIGNED, (char *) &index, sizeof(index));       /*  traceRouteHopsIndex  */
  2029.                     if ((current =
  2030.                          header_complex_get(traceRouteHopsTableStorage,
  2031.                                             vars_hops)) == NULL)
  2032.                         return;
  2033.                     current->traceRouteHopsIpTgtAddressType = 2;
  2034.                     current->traceRouteHopsIpTgtAddress =
  2035.                         (char *)
  2036.                         malloc(strlen
  2037.                                (inet_ntop
  2038.                                 (AF_INET6, &from.sin6_addr, pa, 64)) + 1);
  2039.                     current->traceRouteHopsIpTgtAddress =
  2040.                         strdup(inet_ntop
  2041.                                (AF_INET6, &from.sin6_addr, pa, 64));
  2042.                     current->
  2043.                         traceRouteHopsIpTgtAddress[strlen
  2044.                                                    (inet_ntop
  2045.                                                     (AF_INET6,
  2046.                                                      &from.sin6_addr, pa,
  2047.                                                      64))] = '';
  2048.                     if (count != 0) {
  2049.                         if (strcmp
  2050.                             (old_HopsAddress[index - 1],
  2051.                              current->traceRouteHopsIpTgtAddress) != 0)
  2052.                             flag = 1;
  2053.                     }
  2054.                     current->traceRouteHopsIpTgtAddressLen =
  2055.                         strlen(inet_ntop
  2056.                                (AF_INET6, &from.sin6_addr, pa, 64));
  2057.                     current->traceRouteHopsMinRtt = minRtt;
  2058.                     current->traceRouteHopsMaxRtt = maxRtt;
  2059.                     current->traceRouteHopsAverageRtt = averageRtt;
  2060.                     current->traceRouteHopsRttSumOfSquares = sumOfSquare;
  2061.                     current->traceRouteHopsSentProbes = probe + 1;
  2062.                     current->traceRouteHopsProbeResponses = responseProbe;
  2063.                     current->traceRouteHopsLastGoodProbe =
  2064.                         (char *) malloc(strlen(asctime(gmtime(&timep))));
  2065.                     current->traceRouteHopsLastGoodProbe =
  2066.                         strdup(asctime(gmtime(&timep)));
  2067.                     current->
  2068.                         traceRouteHopsLastGoodProbe[strlen
  2069.                                                     (asctime
  2070.                                                      (gmtime(&timep))) -
  2071.                                                     1] = '';
  2072.                     current->traceRouteHopsLastGoodProbeLen =
  2073.                         strlen(asctime(gmtime(&timep))) - 1;
  2074.                     snmp_free_varbind(vars_hops);
  2075.                     vars_hops = NULL;
  2076.                 }
  2077.                 (void) fflush(stdout);
  2078.             }
  2079.             putchar('n');
  2080.             if (got_there || unreachable >= nprobes - 1) {
  2081.                 if (got_there != 0) {
  2082.                     StorageResults->traceRouteResultsTestAttempts =
  2083.                         StorageResults->traceRouteResultsTestAttempts + 1;
  2084.                     StorageResults->traceRouteResultsTestSuccesses =
  2085.                         StorageResults->traceRouteResultsTestSuccesses + 1;
  2086.                     StorageResults->traceRouteResultsLastGoodPath =
  2087.                         (char *) malloc(strlen(asctime(gmtime(&timep))) -
  2088.                                         1);
  2089.                     StorageResults->traceRouteResultsLastGoodPath =
  2090.                         strdup(asctime(gmtime(&timep)));
  2091.                     StorageResults->
  2092.                         traceRouteResultsLastGoodPath[strlen
  2093.                                                       (asctime
  2094.                                                        (gmtime(&timep))) -
  2095.                                                       1] = '';
  2096.                     StorageResults->traceRouteResultsLastGoodPathLen =
  2097.                         strlen(asctime(gmtime(&timep))) - 1;
  2098.                     if ((item->
  2099.                          traceRouteCtlTrapGeneration[0] &
  2100.                          TRACEROUTETRAPGENERATION_TESTCOMPLETED) != 0) {
  2101.                         printf("TEST completed!n");
  2102.                         send_traceRoute_trap(item, traceRouteTestCompleted,
  2103.                                              sizeof
  2104.                                              (traceRouteTestCompleted) /
  2105.                                              sizeof(oid));
  2106.                     }
  2107.                 }
  2108.                 else {
  2109.                     StorageResults->traceRouteResultsTestAttempts =
  2110.                         StorageResults->traceRouteResultsTestAttempts + 1;
  2111.                     if ((item->
  2112.                          traceRouteCtlTrapGeneration[0] &
  2113.                          TRACEROUTETRAPGENERATION_TESTFAILED) != 0) {
  2114.                         printf("test Failed!n");
  2115.                         send_traceRoute_trap(item, traceRouteTestFailed,
  2116.                                              sizeof(traceRouteTestFailed) /
  2117.                                              sizeof(oid));
  2118.                     }
  2119.                 }
  2120.                 break;
  2121.             } else if (ttl == item->traceRouteCtlMaxTtl
  2122.                        && (probe + 1) == nprobes) {
  2123.                 StorageResults->traceRouteResultsTestAttempts =
  2124.                     StorageResults->traceRouteResultsTestAttempts + 1;
  2125.                 if ((item->
  2126.                      traceRouteCtlTrapGeneration[0] &
  2127.                      TRACEROUTETRAPGENERATION_TESTFAILED) != 0) {
  2128.                     printf("test Failed!n");
  2129.                     send_ping_trap(item, traceRouteTestFailed,
  2130.                                    sizeof(traceRouteTestFailed) /
  2131.                                    sizeof(oid));
  2132.                 }
  2133.             }
  2134.         }
  2135.         if (flag == 1) {
  2136.             printf("path changed!n");
  2137.             send_traceRoute_trap(item, traceRoutePathChange,
  2138.                                  sizeof(traceRoutePathChange) /
  2139.                                  sizeof(oid));
  2140.         }
  2141.         int             k = 0;
  2142.         for (k = 0; k < count; k++) {
  2143.             free(old_HopsAddress[k]);
  2144.             old_HopsAddress[k] = NULL;
  2145.         }
  2146.     }
  2147.     return;
  2148. }
  2149. int
  2150. wait_for_reply(register int sock, register struct sockaddr_in *fromp,
  2151.                register const struct timeval *tp, u_char * packet,
  2152.                int waittime)
  2153. {
  2154.     fd_set          fds;
  2155.     struct timeval  now, wait;
  2156.     struct timezone tz;
  2157.     register int    cc = 0;
  2158.     int             fromlen = sizeof(*fromp);
  2159.     FD_ZERO(&fds);
  2160.     FD_SET(sock, &fds);
  2161.     wait.tv_sec = tp->tv_sec + waittime;
  2162.     wait.tv_usec = tp->tv_usec;
  2163.     (void) gettimeofday(&now, &tz);
  2164.     tvsub(&wait, &now);
  2165.     if (select(sock + 1, &fds, NULL, NULL, &wait) > 0)
  2166.         cc = recvfrom(sock, (char *) packet, 512, 0,
  2167.                       (struct sockaddr *) fromp, &fromlen);
  2168.     return (cc);
  2169. }
  2170. int
  2171. wait_for_reply_v6(int sock, struct sockaddr_in6 *from, int reset_timer,
  2172.                   int waittime, int icmp_sock, u_char * packet)
  2173. {
  2174.     fd_set          fds;
  2175.     static struct timeval wait;
  2176.     int             cc = 0;
  2177.     int             fromlen = sizeof(*from);
  2178.     FD_ZERO(&fds);
  2179.     FD_SET(sock, &fds);
  2180.     if (reset_timer) {
  2181.         /*
  2182.          * traceroute could hang if someone else has a ping
  2183.          * running and our ICMP reply gets dropped but we don't
  2184.          * realize it because we keep waking up to handle those
  2185.          * other ICMP packets that keep coming in.  To fix this,
  2186.          * "reset_timer" will only be true if the last packet that
  2187.          * came in was for us or if this is the first time we're
  2188.          * waiting for a reply since sending out a probe.  Note
  2189.          * that this takes advantage of the select() feature on
  2190.          * Linux where the remaining timeout is written to the
  2191.          * struct timeval area.
  2192.          */
  2193.         wait.tv_sec = waittime;
  2194.         wait.tv_usec = 0;
  2195.     }
  2196.     if (select(sock + 1, &fds, (fd_set *) 0, (fd_set *) 0, &wait) > 0) {
  2197.         cc = recvfrom(icmp_sock, (char *) packet, 512, 0,
  2198.                       (struct sockaddr *) from, &fromlen);
  2199.     }
  2200.     return (cc);
  2201. }
  2202. void
  2203. send_probe(struct sockaddr_in *whereto, register int seq, int ttl,
  2204.            register struct timeval *tp, register struct ip *outip,
  2205.            register struct udphdr *outudp, int packlen, int optlen,
  2206.            char *hostname, u_short ident, int sndsock, u_short port,
  2207.            struct outdata *outdata)
  2208. {
  2209.     register int    cc = 0;
  2210.     register struct udpiphdr *ui = NULL, *oui = NULL;
  2211.     struct ip       tip;
  2212.     outip->ip_ttl = ttl;
  2213. #ifndef __hpux
  2214.     outip->ip_id = htons(ident + seq);
  2215. #endif
  2216.     /*
  2217.      * In most cases, the kernel will recalculate the ip checksum.
  2218.      * But we must do it anyway so that the udp checksum comes out
  2219.      * right.
  2220.      */
  2221.     outip->ip_sum =
  2222.         in_checksum((u_short *) outip, sizeof(*outip) + optlen);
  2223.     if (outip->ip_sum == 0)
  2224.         outip->ip_sum = 0xffff;
  2225.     /*
  2226.      * Payload 
  2227.      */
  2228.     outdata->seq = seq;
  2229.     outdata->ttl = ttl;
  2230.     outdata->tv = *tp;
  2231.     outudp->dest = htons(port + seq);
  2232.     /*
  2233.      * Checksum (we must save and restore ip header) 
  2234.      */
  2235.     tip = *outip;
  2236.     ui = (struct udpiphdr *) outip;
  2237.     oui = (struct udpiphdr *) &tip;
  2238.     /*
  2239.      * Easier to zero and put back things that are ok 
  2240.      */
  2241.     memset((char *) ui, 0, sizeof(ui->ui_i));
  2242.     ui->ui_src = oui->ui_src;
  2243.     ui->ui_dst = oui->ui_dst;
  2244.     ui->ui_pr = oui->ui_pr;
  2245.     ui->ui_len = outudp->len;
  2246.     outudp->check = 0;
  2247.     outudp->check = in_checksum((u_short *) ui, packlen);
  2248.     if (outudp->check == 0)
  2249.         outudp->check = 0xffff;
  2250.     *outip = tip;
  2251.     /*
  2252.      * XXX undocumented debugging hack 
  2253.      */
  2254. #if !defined(IP_HDRINCL) && defined(IP_TTL)
  2255.     printf("ttln");
  2256.     if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
  2257.                    (char *) &ttl, sizeof(ttl)) < 0) {
  2258.         Fprintf(stderr, "%s: setsockopt ttl %d: %sn",
  2259.                 prog, ttl, strerror(errno));
  2260.         exit(1);
  2261.     }
  2262. #endif
  2263. #ifdef __hpux
  2264.     Printf("whereto=%sn",
  2265.            inet_ntoa(((struct sockaddr_in *) whereto)->sin_addr));
  2266.     cc = sendto(sndsock, (char *) outudp,
  2267.                 packlen - (sizeof(*outip) + optlen), 0, whereto,
  2268.                 sizeof(*whereto));
  2269.     if (cc > 0)
  2270.         cc += sizeof(*outip) + optlen;
  2271. #else
  2272.     cc = sendto(sndsock, (char *) outip,
  2273.                 packlen, 0, whereto, sizeof(*whereto));
  2274. #endif
  2275.     if (cc < 0 || cc != packlen) {
  2276.         if (cc < 0)
  2277.             Fprintf(stderr, "%s: sendto: %sn", prog, strerror(errno));
  2278.         Printf("%s: wrote %s %d chars, ret=%dn",
  2279.                prog, hostname, packlen, cc);
  2280.         (void) fflush(stdout);
  2281.     }
  2282. }
  2283. void
  2284. send_probe_v6(int seq, int ttl, char *sendbuff, pid_t ident,
  2285.               struct timezone *tz, int sndsock, int datalen,
  2286.               struct sockaddr_in6 *whereto, char *hostname)
  2287. {
  2288.     struct pkt_format *pkt = (struct pkt_format *) sendbuff;
  2289.     int             i = 0;
  2290.     pkt->ident = htonl(ident);
  2291.     pkt->seq = htonl(seq);
  2292.     gettimeofday(&pkt->tv, tz);
  2293.     i = setsockopt(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl,
  2294.                    sizeof(int));
  2295.     if (i < 0) {
  2296.         perror("setsockopt");
  2297.         exit(1);
  2298.     }
  2299.     do {
  2300.         i = sendto(sndsock, sendbuff, datalen, 0,
  2301.                    (struct sockaddr *) whereto,
  2302.                    sizeof(struct sockaddr_in6));
  2303.     } while (i < 0 && errno == ECONNREFUSED);
  2304.     if (i < 0 || i != datalen) {
  2305.         if (i < 0)
  2306.             perror("sendto");
  2307.         Printf("traceroute: wrote %s %d chars, ret=%dn", hostname,
  2308.                datalen, i);
  2309.         (void) fflush(stdout);
  2310.     }
  2311. }
  2312. unsigned long
  2313. deltaT(struct timeval *t1p, struct timeval *t2p)
  2314. {
  2315.     register unsigned long dt;
  2316.     dt = (unsigned long) ((long) (t2p->tv_sec - t1p->tv_sec) * 1000 +
  2317.                           (long) (t2p->tv_usec - t1p->tv_usec) / 1000);
  2318.     return (dt);
  2319. }
  2320. int
  2321. packet_ok(register u_char * buf, int cc, register struct sockaddr_in *from,
  2322.           register int seq, u_short ident, int pmtu, u_short port)
  2323. {
  2324.     register struct icmp *icp = NULL;
  2325.     register u_char type, code;
  2326.     register int    hlen = 0;
  2327. #ifndef ARCHAIC
  2328.     register struct ip *ip = NULL;
  2329.     ip = (struct ip *) buf;
  2330.     hlen = ip->ip_hl << 2;
  2331.     if (cc < hlen + ICMP_MINLEN) {
  2332.         return (0);
  2333.     }
  2334.     cc -= hlen;
  2335.     icp = (struct icmp *) (buf + hlen);
  2336. #else
  2337.     icp = (struct icmp *) buf;
  2338. #endif
  2339.     type = icp->icmp_type;
  2340.     code = icp->icmp_code;
  2341.     /*
  2342.      * Path MTU Discovery (RFC1191) 
  2343.      */
  2344.     if (code != ICMP_UNREACH_NEEDFRAG)
  2345.         pmtu = 0;
  2346.     else {
  2347. #ifdef HAVE_ICMP_NEXTMTU
  2348.         pmtu = ntohs(icp->icmp_nextmtu);
  2349. #else
  2350.         pmtu = ntohs(((struct my_pmtu *) &icp->icmp_void)->ipm_nextmtu);
  2351. #endif
  2352.     }
  2353.     if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
  2354.         type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
  2355.         register struct ip *hip;
  2356.         register struct udphdr *up;
  2357.         register struct icmp *hicmp;
  2358.         hip = &icp->icmp_ip;
  2359.         hlen = hip->ip_hl << 2;
  2360.         up = (struct udphdr *) ((u_char *) hip + hlen);
  2361.         /*
  2362.          * XXX 8 is a magic number 
  2363.          */
  2364.         if (hlen + 12 <= cc &&
  2365.             hip->ip_p == IPPROTO_UDP &&
  2366.             up->source == htons(ident) && up->dest == htons(port + seq))
  2367.             return (type == ICMP_TIMXCEED ? -1 : code + 1);
  2368.     }
  2369.     return (0);
  2370. }
  2371. int
  2372. packet_ok_v6(u_char * buf, int cc, struct sockaddr_in6 *from, int seq,
  2373.              struct timeval *tv, pid_t ident)
  2374. {
  2375.     struct icmp6hdr *icp = NULL;
  2376.     u_char          type, code;
  2377.     icp = (struct icmp6hdr *) buf;
  2378.     type = icp->icmp6_type;
  2379.     code = icp->icmp6_code;
  2380.     if ((type == ICMPV6_TIME_EXCEED && code == ICMPV6_EXC_HOPLIMIT) ||
  2381.         type == ICMPV6_DEST_UNREACH) {
  2382.         struct ipv6hdr *hip = NULL;
  2383.         struct udphdr  *up = NULL;
  2384.         int             nexthdr = 0;
  2385.         hip = (struct ipv6hdr *) (icp + 1);
  2386.         up = (struct udphdr *) (hip + 1);
  2387.         nexthdr = hip->nexthdr;
  2388.         if (nexthdr == 44) {
  2389.             nexthdr = *(unsigned char *) up;
  2390.             up++;
  2391.         }
  2392.         if (nexthdr == IPPROTO_UDP) {
  2393.             struct pkt_format *pkt;
  2394.             pkt = (struct pkt_format *) (up + 1);
  2395.             if (ntohl(pkt->ident) == ident && ntohl(pkt->seq) == seq) {
  2396.                 *tv = pkt->tv;
  2397.                 return (type == ICMPV6_TIME_EXCEED ? -1 : code + 1);
  2398.             }
  2399.         }
  2400.     }
  2401.     return (0);
  2402. }
  2403. /*
  2404.  * Checksum routine for Internet Protocol family headers (C Version)
  2405.  */
  2406. u_short
  2407. in_checksum(register u_short * addr, register int len)
  2408. {
  2409.     register int    nleft = len;
  2410.     register u_short *w = addr;
  2411.     register u_short answer;
  2412.     register int    sum = 0;
  2413.     /*
  2414.      *  Our algorithm is simple, using a 32 bit accumulator (sum),
  2415.      *  we add sequential 16 bit words to it, and at the end, fold
  2416.      *  back all the carry bits from the top 16 bits into the lower
  2417.      *  16 bits.
  2418.      */
  2419.     while (nleft > 1) {
  2420.         sum += *w++;
  2421.         nleft -= 2;
  2422.     }
  2423.     /*
  2424.      * mop up an odd byte, if necessary 
  2425.      */
  2426.     if (nleft == 1)
  2427.         sum += *(u_char *) w;
  2428.     /*
  2429.      * add back carry outs from top 16 bits to low 16 bits
  2430.      */
  2431.     sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
  2432.     sum += (sum >> 16);         /* add carry */
  2433.     answer = ~sum;              /* truncate to 16 bits */
  2434.     return (answer);
  2435. }
  2436. /*
  2437.  * Subtract 2 timeval structs:  out = out - in.
  2438.  * Out is assumed to be >= in.
  2439.  */
  2440. void
  2441. tvsub(register struct timeval *out, register struct timeval *in)
  2442. {
  2443.     if ((out->tv_usec -= in->tv_usec) < 0) {
  2444.         --out->tv_sec;
  2445.         out->tv_usec += 1000000;
  2446.     }
  2447.     out->tv_sec -= in->tv_sec;
  2448. }
  2449. struct hostinfo *
  2450. gethostinfo(register char *hostname)
  2451. {
  2452.     register int    n;
  2453.     register struct hostent *hp = NULL;
  2454.     register struct hostinfo *hi = NULL;
  2455.     register char **p = NULL;
  2456.     register u_int32_t addr, *ap = NULL;
  2457.     if (strlen(hostname) > 64) {
  2458.         Fprintf(stderr, "%s: hostname "%.32s..." is too longn",
  2459.                 prog, hostname);
  2460.         exit(1);
  2461.     }
  2462.     hi = calloc(1, sizeof(*hi));
  2463.     if (hi == NULL) {
  2464.         Fprintf(stderr, "%s: calloc %sn", prog, strerror(errno));
  2465.         exit(1);
  2466.     }
  2467.     addr = inet_addr(hostname);
  2468.     if ((int32_t) addr != -1) {
  2469.         hi->name = strdup(hostname);
  2470.         hi->n = 1;
  2471.         hi->addrs = calloc(1, sizeof(hi->addrs[0]));
  2472.         if (hi->addrs == NULL) {
  2473.             Fprintf(stderr, "%s: calloc %sn", prog, strerror(errno));
  2474.             exit(1);
  2475.         }
  2476.         hi->addrs[0] = addr;
  2477.         return (hi);
  2478.     }
  2479.     hp = gethostbyname(hostname);
  2480.     if (hp == NULL) {
  2481.         Fprintf(stderr, "%s: unknown host %sn", prog, hostname);
  2482.         printf("hp=NULLn");
  2483.         exit(1);
  2484.     }
  2485.     if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
  2486.         Fprintf(stderr, "%s: bad host %sn", prog, hostname);
  2487.         exit(1);
  2488.     }
  2489.     hi->name = strdup(hp->h_name);
  2490.     for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
  2491.         continue;
  2492.     hi->n = n;
  2493.     hi->addrs = calloc(n, sizeof(hi->addrs[0]));
  2494.     if (hi->addrs == NULL) {
  2495.         Fprintf(stderr, "%s: calloc %sn", prog, strerror(errno));
  2496.         exit(1);
  2497.     }
  2498.     for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
  2499.         memcpy(ap, *p, sizeof(*ap));
  2500.     return (hi);
  2501. }
  2502. void
  2503. freehostinfo(register struct hostinfo *hi)
  2504. {
  2505.     if (hi->name != NULL) {
  2506.         free(hi->name);
  2507.         hi->name = NULL;
  2508.     }
  2509.     free((char *) hi->addrs);
  2510.     free((char *) hi);
  2511. }
  2512. void
  2513. setsin(register struct sockaddr_in *sin, register u_int32_t addr)
  2514. {
  2515.     memset(sin, 0, sizeof(*sin));
  2516. #ifdef HAVE_SOCKADDR_SA_LEN
  2517.     sin->sin_len = sizeof(*sin);
  2518. #endif
  2519.     sin->sin_family = AF_INET;
  2520.     sin->sin_addr.s_addr = addr;
  2521. }
  2522. /*
  2523.  * Return the source address for the given destination address
  2524.  */
  2525. const char     *
  2526. findsaddr(register const struct sockaddr_in *to,
  2527.           register struct sockaddr_in *from)
  2528. {
  2529.     register int    i, n;
  2530.     register FILE  *f;
  2531.     register u_int32_t mask;
  2532.     u_int32_t       dest, tmask;
  2533.     struct ifaddrlist *al;
  2534.     char            buf[256], tdevice[256], device[256];
  2535.     static char     errbuf[132];
  2536.     static const char route[] = "/proc/net/route";
  2537.     if ((f = fopen(route, "r")) == NULL) {
  2538.         sprintf(errbuf, "open %s: %.128s", route, strerror(errno));
  2539.         return (errbuf);
  2540.     }
  2541.     /*
  2542.      * Find the appropriate interface 
  2543.      */
  2544.     n = 0;
  2545.     mask = 0;
  2546.     device[0] = '';
  2547.     while (fgets(buf, sizeof(buf), f) != NULL) {
  2548.         ++n;
  2549.         if (n == 1 && strncmp(buf, "Iface", 5) == 0)
  2550.             continue;
  2551.         if ((i = sscanf(buf, "%s %x %*s %*s %*s %*s %*s %x",
  2552.                         tdevice, &dest, &tmask)) != 3)
  2553.             return ("junk in buffer");
  2554.         if ((to->sin_addr.s_addr & tmask) == dest &&
  2555.             (tmask > mask || mask == 0)) {
  2556.             mask = tmask;
  2557.             strcpy(device, tdevice);
  2558.         }
  2559.     }
  2560.     fclose(f);
  2561.     if (device[0] == '')
  2562.         return ("Can't find interface");
  2563.     /*
  2564.      * Get the interface address list 
  2565.      */
  2566.     if ((n = ifaddrlist(&al, errbuf)) < 0)
  2567.         return (errbuf);
  2568.     if (n == 0)
  2569.         return ("Can't find any network interfaces");
  2570.     /*
  2571.      * Find our appropriate source address 
  2572.      */
  2573.     for (i = n; i > 0; --i, ++al)
  2574.         if (strcmp(device, al->device) == 0)
  2575.             break;
  2576.     if (i <= 0) {
  2577.         sprintf(errbuf, "Can't find interface "%.32s"", device);
  2578.         return (errbuf);
  2579.     }
  2580.     setsin(from, al->addr);
  2581.     return (NULL);
  2582. }
  2583. int
  2584. ifaddrlist(register struct ifaddrlist **ipaddrp, register char *errbuf)
  2585. {
  2586.     register int    fd, nipaddr;
  2587. #ifdef HAVE_SOCKADDR_SA_LEN
  2588.     register int    n;
  2589. #endif
  2590.     register struct ifreq *ifrp, *ifend, *ifnext, *mp;
  2591.     register struct sockaddr_in *sin;
  2592.     register struct ifaddrlist *al;
  2593.     struct ifconf   ifc;
  2594.     struct ifreq    ibuf[(32 * 1024) / sizeof(struct ifreq)], ifr;
  2595. #define MAX_IPADDR (sizeof(ibuf) / sizeof(ibuf[0]))
  2596.     static struct ifaddrlist ifaddrlist[MAX_IPADDR];
  2597.     char            device[sizeof(ifr.ifr_name) + 1];
  2598.     fd = socket(AF_INET, SOCK_DGRAM, 0);
  2599.     if (fd < 0) {
  2600.         (void) sprintf(errbuf, "socket: %s", strerror(errno));
  2601.         return (-1);
  2602.     }
  2603.     ifc.ifc_len = sizeof(ibuf);
  2604.     ifc.ifc_buf = (caddr_t) ibuf;
  2605.     if (ioctl(fd, SIOCGIFCONF, (char *) &ifc) < 0 ||
  2606.         ifc.ifc_len < sizeof(struct ifreq)) {
  2607.         if (errno == EINVAL)
  2608.             (void) sprintf(errbuf,
  2609.                            "SIOCGIFCONF: ifreq struct too small (%d bytes)",
  2610.                            sizeof(ibuf));
  2611.         else
  2612.             (void) sprintf(errbuf, "SIOCGIFCONF: %s", strerror(errno));
  2613.         (void) close(fd);
  2614.         return (-1);
  2615.     }
  2616.     ifrp = ibuf;
  2617.     ifend = (struct ifreq *) ((char *) ibuf + ifc.ifc_len);
  2618.     al = ifaddrlist;
  2619.     mp = NULL;
  2620.     nipaddr = 0;
  2621.     for (; ifrp < ifend; ifrp = ifnext) {
  2622. #ifdef HAVE_SOCKADDR_SA_LEN
  2623.         n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
  2624.         if (n < sizeof(*ifrp))
  2625.             ifnext = ifrp + 1;
  2626.         else
  2627.             ifnext = (struct ifreq *) ((char *) ifrp + n);
  2628.         if (ifrp->ifr_addr.sa_family != AF_INET)
  2629.             continue;
  2630. #else
  2631.         ifnext = ifrp + 1;
  2632. #endif
  2633.         /*
  2634.          * Need a template to preserve address info that is
  2635.          * used below to locate the next entry.  (Otherwise,
  2636.          * SIOCGIFFLAGS stomps over it because the requests
  2637.          * are returned in a union.)
  2638.          */
  2639.         strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
  2640.         if (ioctl(fd, SIOCGIFFLAGS, (char *) &ifr) < 0) {
  2641.             if (errno == ENXIO)
  2642.                 continue;
  2643.             (void) sprintf(errbuf, "SIOCGIFFLAGS: %.*s: %s",
  2644.                            (int) sizeof(ifr.ifr_name), ifr.ifr_name,
  2645.                            strerror(errno));
  2646.             (void) close(fd);
  2647.             return (-1);
  2648.         }
  2649.         /*
  2650.          * Must be up 
  2651.          */
  2652.         if ((ifr.ifr_flags & IFF_UP) == 0)
  2653.             continue;
  2654.         (void) strncpy(device, ifr.ifr_name, sizeof(ifr.ifr_name));
  2655.         device[sizeof(device) - 1] = '';
  2656. #ifdef sun
  2657.         /*
  2658.          * Ignore sun virtual interfaces 
  2659.          */
  2660.         if (strchr(device, ':') != NULL)
  2661.             continue;
  2662. #endif
  2663.         if (ioctl(fd, SIOCGIFADDR, (char *) &ifr) < 0) {
  2664.             (void) sprintf(errbuf, "SIOCGIFADDR: %s: %s",
  2665.                            device, strerror(errno));
  2666.             (void) close(fd);
  2667.             return (-1);
  2668.         }
  2669.         if (nipaddr >= MAX_IPADDR) {
  2670.             (void) sprintf(errbuf, "Too many interfaces (%d)", MAX_IPADDR);
  2671.             (void) close(fd);
  2672.             return (-1);
  2673.         }
  2674.         sin = (struct sockaddr_in *) &ifr.ifr_addr;
  2675.         al->addr = sin->sin_addr.s_addr;
  2676.         al->device = strdup(device);
  2677.         ++al;
  2678.         ++nipaddr;
  2679.     }
  2680.     (void) close(fd);
  2681.     *ipaddrp = ifaddrlist;
  2682.     return (nipaddr);
  2683. }