- Visual C++源码
- Visual Basic源码
- C++ Builder源码
- Java源码
- Delphi源码
- C/C++源码
- PHP源码
- Perl源码
- Python源码
- Asm源码
- Pascal源码
- Borland C++源码
- Others源码
- SQL源码
- VBScript源码
- JavaScript源码
- ASP/ASPX源码
- C#源码
- Flash/ActionScript源码
- matlab源码
- PowerBuilder源码
- LabView源码
- Flex源码
- MathCAD源码
- VBA源码
- IDL源码
- Lisp/Scheme源码
- VHDL源码
- Objective-C源码
- Fortran源码
- tcl/tk源码
- QT源码
traceRouteCtlTable.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:215k
源码类别:
SNMP编程
开发平台:
Unix_Linux
- if (var_val_type != ASN_INTEGER) {
- snmp_log(LOG_ERR,
- "write to traceRouteCtlIfIndex not ASN_INTEGERn");
- return SNMP_ERR_WRONGTYPE;
- }
- break;
- case RESERVE2:
- /*
- * memory reseveration, final preparation...
- */
- break;
- case FREE:
- /*
- * Release any resources that have been allocated
- */
- break;
- case ACTION:
- /*
- * The variable has been stored in objid for
- * you to use, and you have just been asked to do something with
- * it. Note that anything done here must be reversable in the UNDO case
- */
- tmpvar = StorageTmp->traceRouteCtlAdminStatus;
- StorageTmp->traceRouteCtlAdminStatus = *((long *) var_val);
- break;
- case UNDO:
- /*
- * Back out any changes made in the ACTION case
- */
- StorageTmp->traceRouteCtlAdminStatus = tmpvar;
- break;
- case COMMIT:
- /*
- * Things are working well, so it's now safe to make the change
- * permanently. Make sure that anything done here can't fail!
- */
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) StorageTmp->traceRouteCtlOwnerIndex, StorageTmp->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) StorageTmp->traceRouteCtlTestName, StorageTmp->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */
- StorageNew =
- header_complex_get(traceRouteResultsTableStorage, vars);
- if (StorageTmp->traceRouteCtlAdminStatus == 1
- && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
- if (StorageNew == NULL)
- init_trResultsTable(StorageTmp);
- else {
- StorageTmp->traceRouteResults->
- traceRouteResultsOperStatus = 1;
- modify_trResultsOper(StorageTmp, 1);
- }
- if (StorageTmp->traceRouteCtlFrequency != 0)
- StorageTmp->timer_id =
- snmp_alarm_register(StorageTmp->traceRouteCtlFrequency,
- SA_REPEAT, run_traceRoute,
- StorageTmp);
- else
- StorageTmp->timer_id = snmp_alarm_register(1, (int) NULL,
- run_traceRoute,
- StorageTmp);
- } else if (StorageTmp->traceRouteCtlAdminStatus == 2
- && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
- snmp_alarm_unregister(StorageTmp->timer_id);
- if (StorageNew == NULL)
- init_trResultsTable(StorageTmp);
- else {
- StorageTmp->traceRouteResults->
- traceRouteResultsOperStatus = 2;
- modify_trResultsOper(StorageTmp, 2);
- }
- }
- break;
- }
- return SNMP_ERR_NOERROR;
- }
- int
- write_traceRouteCtlDescr(int action,
- u_char * var_val,
- u_char var_val_type,
- size_t var_val_len,
- u_char * statP, oid * name, size_t name_len)
- {
- static char *tmpvar;
- static size_t tmplen;
- struct traceRouteCtlTable_data *StorageTmp = NULL;
- size_t newlen =
- name_len -
- (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1);
- if ((StorageTmp =
- header_complex(traceRouteCtlTableStorage, NULL,
- &name[sizeof(traceRouteCtlTable_variables_oid) /
- sizeof(oid) + 3 - 1], &newlen, 1, NULL,
- NULL)) == NULL)
- return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
- if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
- return SNMP_ERR_NOTWRITABLE;
- }
- if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
- return SNMP_ERR_NOTWRITABLE;
- }
- switch (action) {
- case RESERVE1:
- if (var_val_type != ASN_OCTET_STR) {
- snmp_log(LOG_ERR,
- "write to traceRouteCtlTargetAddress not ASN_OCTET_STRn");
- return SNMP_ERR_WRONGTYPE;
- }
- break;
- case RESERVE2:
- /*
- * memory reseveration, final preparation...
- */
- break;
- case FREE:
- /*
- * Release any resources that have been allocated
- */
- break;
- case ACTION:
- /*
- * The variable has been stored in long_ret for
- * you to use, and you have just been asked to do something with
- * it. Note that anything done here must be reversable in the UNDO case
- */
- tmpvar = StorageTmp->traceRouteCtlDescr;
- tmplen = StorageTmp->traceRouteCtlDescrLen;
- StorageTmp->traceRouteCtlDescr = (char *) malloc(var_val_len + 1);
- if (StorageTmp->traceRouteCtlDescr == NULL) {
- exit(1);
- }
- memcpy(StorageTmp->traceRouteCtlDescr, var_val, var_val_len + 1);
- StorageTmp->traceRouteCtlDescr[var_val_len] = '';
- StorageTmp->traceRouteCtlDescrLen = var_val_len;
- break;
- case UNDO:
- /*
- * Back out any changes made in the ACTION case
- */
- SNMP_FREE(StorageTmp->traceRouteCtlDescr);
- StorageTmp->traceRouteCtlDescr = NULL;
- StorageTmp->traceRouteCtlDescr = tmpvar;
- StorageTmp->traceRouteCtlDescrLen = tmplen;
- break;
- case COMMIT:
- /*
- * Things are working well, so it's now safe to make the change
- * permanently. Make sure that anything done here can't fail!
- */
- SNMP_FREE(tmpvar);
- tmpvar = NULL;
- break;
- }
- return SNMP_ERR_NOERROR;
- }
- int
- write_traceRouteCtlMaxRows(int action,
- u_char * var_val,
- u_char var_val_type,
- size_t var_val_len,
- u_char * statP, oid * name, size_t name_len)
- {
- static size_t tmpvar;
- struct traceRouteCtlTable_data *StorageTmp = NULL;
- static size_t tmplen;
- size_t newlen =
- name_len -
- (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1);
- if ((StorageTmp =
- header_complex(traceRouteCtlTableStorage, NULL,
- &name[sizeof(traceRouteCtlTable_variables_oid) /
- sizeof(oid) + 3 - 1], &newlen, 1, NULL,
- NULL)) == NULL)
- return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
- if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
- return SNMP_ERR_NOTWRITABLE;
- }
- if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
- return SNMP_ERR_NOTWRITABLE;
- }
- switch (action) {
- case RESERVE1:
- if (var_val_type != ASN_UNSIGNED) {
- snmp_log(LOG_ERR,
- "write to traceRouteCtlDSField not ASN_UNSIGNEDn");
- return SNMP_ERR_WRONGTYPE;
- }
- break;
- case RESERVE2:
- /*
- * memory reseveration, final preparation...
- */
- break;
- case FREE:
- /*
- * Release any resources that have been allocated
- */
- break;
- case ACTION:
- /*
- * The variable has been stored in objid for
- * you to use, and you have just been asked to do something with
- * it. Note that anything done here must be reversable in the UNDO case
- */
- tmpvar = StorageTmp->traceRouteCtlMaxRows;
- StorageTmp->traceRouteCtlMaxRows = *((long *) var_val);
- break;
- case UNDO:
- /*
- * Back out any changes made in the ACTION case
- */
- StorageTmp->traceRouteCtlMaxRows = tmpvar;
- break;
- case COMMIT:
- /*
- * Things are working well, so it's now safe to make the change
- * permanently. Make sure that anything done here can't fail!
- */
- break;
- }
- return SNMP_ERR_NOERROR;
- }
- int
- write_traceRouteCtlTrapGeneration(int action,
- u_char * var_val,
- u_char var_val_type,
- size_t var_val_len,
- u_char * statP, oid * name,
- size_t name_len)
- {
- static char *tmpvar;
- static size_t tmplen;
- struct traceRouteCtlTable_data *StorageTmp = NULL;
- size_t newlen =
- name_len -
- (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1);
- if ((StorageTmp =
- header_complex(traceRouteCtlTableStorage, NULL,
- &name[sizeof(traceRouteCtlTable_variables_oid) /
- sizeof(oid) + 3 - 1], &newlen, 1, NULL,
- NULL)) == NULL)
- return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
- if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
- return SNMP_ERR_NOTWRITABLE;
- }
- if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
- return SNMP_ERR_NOTWRITABLE;
- }
- switch (action) {
- case RESERVE1:
- if (var_val_type != ASN_OCTET_STR) {
- snmp_log(LOG_ERR,
- "write to traceRouteCtlTargetAddress not ASN_OCTET_STRn");
- return SNMP_ERR_WRONGTYPE;
- }
- break;
- case RESERVE2:
- /*
- * memory reseveration, final preparation...
- */
- break;
- case FREE:
- /*
- * Release any resources that have been allocated
- */
- break;
- case ACTION:
- /*
- * The variable has been stored in long_ret for
- * you to use, and you have just been asked to do something with
- * it. Note that anything done here must be reversable in the UNDO case
- */
- tmpvar = StorageTmp->traceRouteCtlTrapGeneration;
- tmplen = StorageTmp->traceRouteCtlTrapGenerationLen;
- StorageTmp->traceRouteCtlTrapGeneration =
- (char *) malloc(var_val_len + 1);
- if (StorageTmp->traceRouteCtlTrapGeneration == NULL) {
- exit(1);
- }
- memcpy(StorageTmp->traceRouteCtlTrapGeneration, var_val,
- var_val_len + 1);
- StorageTmp->traceRouteCtlTrapGeneration[var_val_len] = '';
- StorageTmp->traceRouteCtlTrapGenerationLen = var_val_len;
- break;
- case UNDO:
- /*
- * Back out any changes made in the ACTION case
- */
- SNMP_FREE(StorageTmp->traceRouteCtlTrapGeneration);
- StorageTmp->traceRouteCtlTrapGeneration = NULL;
- StorageTmp->traceRouteCtlTrapGeneration = tmpvar;
- StorageTmp->traceRouteCtlTrapGenerationLen = tmplen;
- break;
- case COMMIT:
- /*
- * Things are working well, so it's now safe to make the change
- * permanently. Make sure that anything done here can't fail!
- */
- SNMP_FREE(tmpvar);
- tmpvar = NULL;
- break;
- }
- return SNMP_ERR_NOERROR;
- }
- int
- write_traceRouteCtlCreateHopsEntries(int action,
- u_char * var_val,
- u_char var_val_type,
- size_t var_val_len,
- u_char * statP, oid * name,
- size_t name_len)
- {
- static size_t tmpvar;
- struct traceRouteCtlTable_data *StorageTmp = NULL;
- static size_t tmplen;
- size_t newlen =
- name_len -
- (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1);
- if ((StorageTmp =
- header_complex(traceRouteCtlTableStorage, NULL,
- &name[sizeof(traceRouteCtlTable_variables_oid) /
- sizeof(oid) + 3 - 1], &newlen, 1, NULL,
- NULL)) == NULL)
- return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
- if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
- return SNMP_ERR_NOTWRITABLE;
- }
- if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
- return SNMP_ERR_NOTWRITABLE;
- }
- switch (action) {
- case RESERVE1:
- if (var_val_type != ASN_INTEGER) {
- snmp_log(LOG_ERR,
- "write to traceRouteCtlDSField not ASN_INTEGERn");
- return SNMP_ERR_WRONGTYPE;
- }
- break;
- case RESERVE2:
- /*
- * memory reseveration, final preparation...
- */
- break;
- case FREE:
- /*
- * Release any resources that have been allocated
- */
- break;
- case ACTION:
- /*
- * The variable has been stored in objid for
- * you to use, and you have just been asked to do something with
- * it. Note that anything done here must be reversable in the UNDO case
- */
- tmpvar = StorageTmp->traceRouteCtlCreateHopsEntries;
- StorageTmp->traceRouteCtlCreateHopsEntries = *((long *) var_val);
- break;
- case UNDO:
- /*
- * Back out any changes made in the ACTION case
- */
- StorageTmp->traceRouteCtlCreateHopsEntries = tmpvar;
- break;
- case COMMIT:
- /*
- * Things are working well, so it's now safe to make the change
- * permanently. Make sure that anything done here can't fail!
- */
- break;
- }
- return SNMP_ERR_NOERROR;
- }
- int
- write_traceRouteCtlType(int action,
- u_char * var_val,
- u_char var_val_type,
- size_t var_val_len,
- u_char * statP, oid * name, size_t name_len)
- {
- static oid *tmpvar;
- static size_t tmplen;
- struct traceRouteCtlTable_data *StorageTmp = NULL;
- size_t newlen =
- name_len -
- (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1);
- if ((StorageTmp =
- header_complex(traceRouteCtlTableStorage, NULL,
- &name[sizeof(traceRouteCtlTable_variables_oid) /
- sizeof(oid) + 3 - 1], &newlen, 1, NULL,
- NULL)) == NULL)
- return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
- if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
- return SNMP_ERR_NOTWRITABLE;
- }
- if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
- return SNMP_ERR_NOTWRITABLE;
- }
- switch (action) {
- case RESERVE1:
- if (var_val_type != ASN_OBJECT_ID) {
- snmp_log(LOG_ERR,
- "write to traceRouteCtlType not ASN_OBJECT_IDn");
- return SNMP_ERR_WRONGTYPE;
- }
- break;
- case RESERVE2:
- /*
- * memory reseveration, final preparation...
- */
- break;
- case FREE:
- /*
- * Release any resources that have been allocated
- */
- break;
- case ACTION:
- /*
- * The variable has been stored in long_ret for
- * you to use, and you have just been asked to do something with
- * it. Note that anything done here must be reversable in the UNDO case
- */
- tmpvar = StorageTmp->traceRouteCtlType;
- tmplen = StorageTmp->traceRouteCtlTypeLen;
- StorageTmp->traceRouteCtlType = (oid *) malloc(var_val_len);
- if (StorageTmp->traceRouteCtlType == NULL) {
- exit(1);
- }
- memcpy(StorageTmp->traceRouteCtlType, var_val, var_val_len);
- StorageTmp->traceRouteCtlTypeLen = var_val_len / sizeof(oid);
- break;
- case UNDO:
- /*
- * Back out any changes made in the ACTION case
- */
- SNMP_FREE(StorageTmp->traceRouteCtlType);
- StorageTmp->traceRouteCtlType = NULL;
- StorageTmp->traceRouteCtlType = tmpvar;
- StorageTmp->traceRouteCtlTypeLen = tmplen;
- break;
- case COMMIT:
- /*
- * Things are working well, so it's now safe to make the change
- * permanently. Make sure that anything done here can't fail!
- */
- SNMP_FREE(tmpvar);
- tmpvar = NULL;
- break;
- }
- return SNMP_ERR_NOERROR;
- }
- int
- write_traceRouteCtlRowStatus(int action,
- u_char * var_val,
- u_char var_val_type,
- size_t var_val_len,
- u_char * statP, oid * name, size_t name_len)
- {
- struct traceRouteCtlTable_data *StorageTmp = NULL;
- static struct traceRouteCtlTable_data *StorageNew = NULL;
- static struct traceRouteCtlTable_data *StorageDel = NULL;
- size_t newlen =
- name_len -
- (sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) + 3 - 1);
- static int old_value;
- int set_value;
- static netsnmp_variable_list *vars = NULL, *vp = NULL;
- struct header_complex_index *hciptr = NULL;
- StorageTmp =
- header_complex(traceRouteCtlTableStorage, NULL,
- &name[sizeof(traceRouteCtlTable_variables_oid) /
- sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL);
- if (var_val_type != ASN_INTEGER || var_val == NULL) {
- snmp_log(LOG_ERR,
- "write to traceRouteCtlRowStatus not ASN_INTEGERn");
- return SNMP_ERR_WRONGTYPE;
- }
- if (StorageTmp && StorageTmp->storageType == ST_READONLY) {
- return SNMP_ERR_NOTWRITABLE;
- }
- set_value = *((long *) var_val);
- /*
- * check legal range, and notReady is reserved for us, not a user
- */
- if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY)
- return SNMP_ERR_INCONSISTENTVALUE;
- switch (action) {
- case RESERVE1:
- /*
- * stage one: test validity
- */
- if (StorageTmp == NULL) {
- /*
- * create the row now?
- */
- /*
- * ditch illegal values now
- */
- if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
- return SNMP_ERR_INCONSISTENTVALUE;
- }
- /*
- * destroying a non-existent row is actually legal
- */
- if (set_value == RS_DESTROY) {
- return SNMP_ERR_NOERROR;
- }
- /*
- * illegal creation values
- */
- if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
- return SNMP_ERR_INCONSISTENTVALUE;
- }
- } else {
- /*
- * row exists. Check for a valid state change
- */
- if (set_value == RS_CREATEANDGO
- || set_value == RS_CREATEANDWAIT) {
- /*
- * can't create a row that exists
- */
- return SNMP_ERR_INCONSISTENTVALUE;
- }
- /*
- * XXX: interaction with row storage type needed
- */
- if (StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE &&
- set_value != RS_DESTROY) {
- /*
- * "Once made active an entry may not be modified except to
- * delete it." XXX: doesn't this in fact apply to ALL
- * columns of the table and not just this one?
- */
- return SNMP_ERR_INCONSISTENTVALUE;
- }
- if (StorageTmp->storageType != ST_NONVOLATILE) {
- return SNMP_ERR_NOTWRITABLE;
- }
- }
- break;
- case RESERVE2:
- /*
- * memory reseveration, final preparation...
- */
- if (StorageTmp == NULL) {
- if (set_value == RS_DESTROY) {
- return SNMP_ERR_NOERROR;
- }
- /*
- * creation
- */
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* traceRouteCtlOwnerIndex */
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0); /* traceRouteCtlTestName */
- if (header_complex_parse_oid
- (&
- (name
- [sizeof(traceRouteCtlTable_variables_oid) / sizeof(oid) +
- 2]), newlen, vars) != SNMPERR_SUCCESS) {
- /*
- * XXX: free, zero vars
- */
- return SNMP_ERR_INCONSISTENTNAME;
- }
- StorageNew = create_traceRouteCtlTable_data();
- if (vars->val_len <= 32) {
- StorageNew->traceRouteCtlOwnerIndex =
- malloc(vars->val_len + 1);
- memcpy(StorageNew->traceRouteCtlOwnerIndex,
- vars->val.string, vars->val_len);
- StorageNew->traceRouteCtlOwnerIndex[vars->val_len] = '';
- StorageNew->traceRouteCtlOwnerIndexLen = vars->val_len;
- } else {
- StorageNew->traceRouteCtlOwnerIndex = malloc(33);
- memcpy(StorageNew->traceRouteCtlOwnerIndex,
- vars->val.string, 32);
- StorageNew->traceRouteCtlOwnerIndex[32] = '';
- StorageNew->traceRouteCtlOwnerIndexLen = 32;
- }
- vars = vars->next_variable;
- if (vars->val_len <= 32) {
- StorageNew->traceRouteCtlTestName =
- malloc(vars->val_len + 1);
- memcpy(StorageNew->traceRouteCtlTestName, vars->val.string,
- vars->val_len);
- StorageNew->traceRouteCtlTestName[vars->val_len] = '';
- StorageNew->traceRouteCtlTestNameLen = vars->val_len;
- } else {
- StorageNew->traceRouteCtlTestName = malloc(33);
- memcpy(StorageNew->traceRouteCtlTestName, vars->val.string,
- 32);
- StorageNew->traceRouteCtlTestName[32] = '';
- StorageNew->traceRouteCtlTestNameLen = 32;
- }
- vars = vars->next_variable;
- /*
- * XXX: fill in default row values here into StorageNew
- */
- StorageNew->traceRouteCtlRowStatus = set_value;
- /*
- * XXX: free, zero vars, no longer needed?
- */
- }
- snmp_free_varbind(vars);
- vars = NULL;
- break;
- case FREE:
- /*
- * XXX: free, zero vars
- */
- snmp_free_varbind(vars);
- vars = NULL;
- /*
- * Release any resources that have been allocated
- */
- break;
- case ACTION:
- /*
- * The variable has been stored in set_value for you to
- * use, and you have just been asked to do something with
- * it. Note that anything done here must be reversable in
- * the UNDO case
- */
- if (StorageTmp == NULL) {
- if (set_value == RS_DESTROY) {
- return SNMP_ERR_NOERROR;
- }
- /*
- * row creation, so add it
- */
- if (StorageNew != NULL) {
- #if 1
- DEBUGMSGTL(("traceRouteCtlTable",
- "write_traceRouteCtlRowStatus entering new=%d... n",
- action));
- #endif
- traceRouteCtlTable_add(StorageNew);
- }
- /*
- * XXX: ack, and if it is NULL?
- */
- } else if (set_value != RS_DESTROY) {
- /*
- * set the flag?
- */
- old_value = StorageTmp->traceRouteCtlRowStatus;
- StorageTmp->traceRouteCtlRowStatus = *((long *) var_val);
- } else {
- /*
- * destroy... extract it for now
- */
- hciptr =
- header_complex_find_entry(traceRouteCtlTableStorage,
- StorageTmp);
- StorageDel =
- header_complex_extract_entry(&traceRouteCtlTableStorage,
- hciptr);
- snmp_alarm_unregister(StorageDel->timer_id);
- traceRouteResultsTable_del(StorageTmp);
- traceRouteProbeHistoryTable_del(StorageTmp);
- traceRouteHopsTable_del(StorageTmp);
- }
- break;
- case UNDO:
- /*
- * Back out any changes made in the ACTION case
- */
- if (StorageTmp == NULL) {
- if (set_value == RS_DESTROY) {
- return SNMP_ERR_NOERROR;
- }
- /*
- * row creation, so remove it again
- */
- hciptr =
- header_complex_find_entry(traceRouteCtlTableStorage,
- StorageTmp);
- StorageDel =
- header_complex_extract_entry(&traceRouteCtlTableStorage,
- hciptr);
- /*
- * XXX: free it
- */
- } else if (StorageDel != NULL) {
- /*
- * row deletion, so add it again
- */
- traceRouteCtlTable_add(StorageDel);
- traceRouteResultsTable_add(StorageDel);
- traceRouteProbeHistoryTable_addall(StorageDel);
- traceRouteHopsTable_addall(StorageDel);
- } else {
- StorageTmp->traceRouteCtlRowStatus = old_value;
- }
- break;
- case COMMIT:
- /*
- * Things are working well, so it's now safe to make the change
- * permanently. Make sure that anything done here can't fail!
- */
- if (StorageTmp == NULL) {
- if (set_value == RS_DESTROY) {
- return SNMP_ERR_NOERROR;
- }
- }
- if (StorageDel != NULL) {
- free(StorageDel->traceRouteCtlOwnerIndex);
- StorageDel->traceRouteCtlOwnerIndex = NULL;
- free(StorageDel->traceRouteCtlTestName);
- StorageDel->traceRouteCtlTestName = NULL;
- free(StorageDel->traceRouteCtlTargetAddress);
- StorageDel->traceRouteCtlTargetAddress = NULL;
- free(StorageDel->traceRouteCtlSourceAddress);
- StorageDel->traceRouteCtlSourceAddress = NULL;
- free(StorageDel->traceRouteCtlMiscOptions);
- StorageDel->traceRouteCtlMiscOptions = NULL;
- free(StorageDel->traceRouteCtlDescr);
- StorageDel->traceRouteCtlDescr = NULL;
- free(StorageDel->traceRouteCtlTrapGeneration);
- StorageDel->traceRouteCtlTrapGeneration = NULL;
- free(StorageDel->traceRouteCtlType);
- StorageDel->traceRouteCtlType = NULL;
- free(StorageDel);
- StorageDel = NULL;
- /*
- * XXX: free it, its dead
- */
- } else {
- if (StorageTmp
- && StorageTmp->traceRouteCtlRowStatus == RS_CREATEANDGO) {
- StorageTmp->traceRouteCtlRowStatus = RS_ACTIVE;
- } else if (StorageTmp &&
- StorageTmp->traceRouteCtlRowStatus ==
- RS_CREATEANDWAIT) {
- StorageTmp->traceRouteCtlRowStatus = RS_NOTINSERVICE;
- }
- }
- if (StorageTmp && StorageTmp->traceRouteCtlRowStatus == RS_ACTIVE) {
- #if 1
- DEBUGMSGTL(("traceRouteCtlTable",
- "write_traceRouteCtlRowStatus entering runbefore=%ld... n",
- StorageTmp->traceRouteCtlTargetAddressType));
- #endif
- if (StorageTmp->traceRouteCtlAdminStatus == 1) {
- init_trResultsTable(StorageTmp);
- if (StorageTmp->traceRouteCtlFrequency != 0)
- StorageTmp->timer_id =
- snmp_alarm_register(StorageTmp->
- traceRouteCtlFrequency,
- SA_REPEAT, run_traceRoute,
- StorageTmp);
- else
- StorageTmp->timer_id =
- snmp_alarm_register(1, (int) NULL, run_traceRoute,
- StorageTmp);
- }
- }
- break;
- }
- return SNMP_ERR_NOERROR;
- }
- unsigned long
- round(double number)
- {
- unsigned long ret_num = 0;
- if (number - (unsigned long) number < 0.5)
- ret_num = (unsigned long) number;
- else
- ret_num = (unsigned long) number + 1;
- return ret_num;
- }
- void
- run_traceRoute(unsigned int clientreg, void *clientarg)
- {
- struct traceRouteCtlTable_data *item = clientarg;
- u_short port = item->traceRouteCtlPort; /* start udp dest port # for probe packets 相当于ctlport */
- int waittime = item->traceRouteCtlTimeOut; /* time to wait for response (in seconds) 相等于ctltimeout */
- prog = "traceroute";
- int nprobes = item->traceRouteCtlProbesPerHop;
- if (item->traceRouteCtlInitialTtl > item->traceRouteCtlMaxTtl) {
- DEBUGMSGTL(("traceRouteCtlTable",
- "first ttl (%d) may not be greater than max ttl (%d)n",
- item->traceRouteCtlInitialTtl,
- item->traceRouteCtlMaxTtl));
- return;
- }
- char *old_HopsAddress[255];
- int count = 0;
- int flag = 0;
- if (item->traceRouteCtlTargetAddressType == 1
- || item->traceRouteCtlTargetAddressType == 16) {
- register int op, code, n;
- register char *cp;
- register const char *err;
- register u_char *outp;
- register u_int32_t *ap;
- struct sockaddr whereto; /* Who to try to reach */
- struct sockaddr wherefrom; /* Who we are */
- register struct sockaddr_in *from =
- (struct sockaddr_in *) &wherefrom;
- register struct sockaddr_in *to = (struct sockaddr_in *) &whereto;
- register struct hostinfo *hi;
- int on = 1;
- register struct protoent *pe;
- register int ttl, probe, i;
- register int seq = 0;
- int tos = 0, settos = 0;
- register int lsrr = 0;
- register u_short off = 0;
- struct ifaddrlist *al;
- char errbuf[132];
- int minpacket = 0; /* min ip packet size */
- struct ip *outip; /* last output (udp) packet */
- struct udphdr *outudp; /* last output (udp) packet */
- int packlen = 0; /* total length of packet */
- int optlen = 0; /* length of ip options */
- int options = 0; /* socket options */
- int s; /* receive (icmp) socket file descriptor */
- int sndsock; /* send (udp/icmp) socket file descriptor */
- u_short ident;
- /*
- * loose source route gateway list (including room for final destination)
- */
- u_int32_t gwlist[NGATEWAYS + 1];
- static const char devnull[] = "/dev/null";
- char *device = NULL;
- char *source = NULL;
- char *hostname;
- u_int pausemsecs = 0;
- u_char packet[512]; /* last inbound (icmp) packet */
- int pmtu = 0; /* Path MTU Discovery (RFC1191) */
- struct outdata *outdata; /* last output (udp) packet */
- minpacket = sizeof(*outip) + sizeof(*outdata) + optlen;
- minpacket += sizeof(*outudp);
- packlen = minpacket; /* minimum sized packet */
- hostname =
- (char *) malloc(item->traceRouteCtlTargetAddressLen + 1);
- if (hostname == NULL)
- return;
- memcpy(hostname, item->traceRouteCtlTargetAddress,
- item->traceRouteCtlTargetAddressLen + 1);
- hostname[item->traceRouteCtlTargetAddressLen] = '';
- hi = gethostinfo(hostname);
- setsin(to, hi->addrs[0]);
- if (hi->n > 1)
- DEBUGMSGTL(("traceRouteCtlTable",
- "Warning: %s has multiple addresses; using %sn",
- hostname, inet_ntoa(to->sin_addr)));
- hostname = hi->name;
- hi->name = NULL;
- freehostinfo(hi);
- #ifdef HAVE_SETLINEBUF
- setlinebuf(stdout);
- #else
- setvbuf(stdout, NULL, _IOLBF, 0);
- #endif
- outip = (struct ip *) malloc(packlen);
- if (outip == NULL) {
- DEBUGMSGTL(("traceRouteCtlTable",
- "malloc: %sn", strerror(errno)));
- exit(1);
- }
- memset((char *) outip, 0, packlen);
- outip->ip_v = IPVERSION;
- if (settos)
- outip->ip_tos = tos;
- #ifdef BYTESWAP_IP_HDR
- outip->ip_len = htons(packlen);
- outip->ip_off = htons(off);
- #else
- outip->ip_len = packlen;
- outip->ip_off = off;
- #endif
- outp = (u_char *) (outip + 1);
- #ifdef HAVE_RAW_OPTIONS
- if (lsrr > 0) {
- register u_char *optlist;
- optlist = outp;
- outp += optlen;
- /*
- * final hop
- */
- gwlist[lsrr] = to->sin_addr.s_addr;
- outip->ip_dst.s_addr = gwlist[0];
- /*
- * force 4 byte alignment
- */
- optlist[0] = IPOPT_NOP;
- /*
- * loose source route option
- */
- optlist[1] = IPOPT_LSRR;
- i = lsrr * sizeof(gwlist[0]);
- optlist[2] = i + 3;
- /*
- * Pointer to LSRR addresses
- */
- optlist[3] = IPOPT_MINOFF;
- memcpy(optlist + 4, gwlist + 1, i);
- } else
- #endif
- outip->ip_dst = to->sin_addr;
- outip->ip_hl = (outp - (u_char *) outip) >> 2;
- ident = (getpid() & 0xffff) | 0x8000;
- outip->ip_p = IPPROTO_UDP;
- outudp = (struct udphdr *) outp;
- outudp->source = htons(ident);
- outudp->len =
- htons((u_short) (packlen - (sizeof(*outip) + optlen)));
- outdata = (struct outdata *) (outudp + 1);
- cp = "icmp";
- if ((pe = getprotobyname(cp)) == NULL) {
- DEBUGMSGTL(("traceRouteCtlTable",
- "unknown protocol %sn", cp));
- exit(1);
- }
- /*
- * Insure the socket fds won't be 0, 1 or 2
- */
- if (open(devnull, O_RDONLY) < 0 ||
- open(devnull, O_RDONLY) < 0 || open(devnull, O_RDONLY) < 0) {
- DEBUGMSGTL(("traceRouteCtlTable",
- "open "%s": %sn", devnull, strerror(errno)));
- exit(1);
- }
- if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0) {
- DEBUGMSGTL(("traceRouteCtlTable",
- "icmp socket: %sn", strerror(errno)));
- exit(1);
- }
- if (options & SO_DEBUG)
- (void) setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *) &on,
- sizeof(on));
- if (options & SO_DONTROUTE)
- (void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *) &on,
- sizeof(on));
- #ifndef __hpux
- printf("rawn");
- sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
- #else
- printf("udpn");
- sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
- #endif
- if (sndsock < 0) {
- DEBUGMSGTL(("traceRouteCtlTable",
- "raw socket: %sn", strerror(errno)));
- exit(1);
- }
- #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
- if (lsrr > 0) {
- u_char optlist[MAX_IPOPTLEN];
- cp = "ip";
- if ((pe = getprotobyname(cp)) == NULL) {
- DEBUGMSGTL(("traceRouteCtlTable",
- "unknown protocol %sn", cp));
- exit(1);
- }
- /*
- * final hop
- */
- gwlist[lsrr] = to->sin_addr.s_addr;
- ++lsrr;
- /*
- * force 4 byte alignment
- */
- optlist[0] = IPOPT_NOP;
- /*
- * loose source route option
- */
- optlist[1] = IPOPT_LSRR;
- i = lsrr * sizeof(gwlist[0]);
- optlist[2] = i + 3;
- /*
- * Pointer to LSRR addresses
- */
- optlist[3] = IPOPT_MINOFF;
- memcpy(optlist + 4, gwlist, i);
- if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS,
- (char *) optlist,
- i + sizeof(gwlist[0]))) < 0) {
- DEBUGMSGTL(("traceRouteCtlTable", "IP_OPTIONS: %sn",
- strerror(errno)));
- exit(1);
- }
- }
- #endif
- #ifdef SO_SNDBUF
- if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *) &packlen,
- sizeof(packlen)) < 0) {
- DEBUGMSGTL(("traceRouteCtlTable",
- "SO_SNDBUF: %sn", strerror(errno)));
- exit(1);
- }
- #endif
- #ifdef IP_HDRINCL
- if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *) &on,
- sizeof(on)) < 0) {
- DEBUGMSGTL(("traceRouteCtlTable",
- "IP_HDRINCL: %sn", strerror(errno)));
- exit(1);
- }
- #else
- #ifdef IP_TOS
- if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS,
- (char *) &tos, sizeof(tos)) < 0) {
- DEBUGMSGTL(("traceRouteCtlTable",
- "setsockopt tos %d: %sn", strerror(errno)));
- exit(1);
- }
- #endif
- #endif
- if (options & SO_DEBUG)
- (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *) &on,
- sizeof(on));
- if (options & SO_DONTROUTE)
- (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
- (char *) &on, sizeof(on));
- /*
- * Get the interface address list
- */
- n = ifaddrlist(&al, errbuf);
- if (n < 0) {
- DEBUGMSGTL(("traceRouteCtlTable",
- " ifaddrlist: %sn", errbuf));
- exit(1);
- }
- if (n == 0) {
- DEBUGMSGTL(("traceRouteCtlTable",
- " Can't find any network interfacesn"));
- exit(1);
- }
- /*
- * Look for a specific device
- */
- if (device != NULL) {
- for (i = n; i > 0; --i, ++al)
- if (strcmp(device, al->device) == 0)
- break;
- if (i <= 0) {
- DEBUGMSGTL(("traceRouteCtlTable",
- " Can't find interface %.32sn", device));
- exit(1);
- }
- }
- /*
- * Determine our source address
- */
- if (source == NULL) {
- /*
- * If a device was specified, use the interface address.
- * Otherwise, try to determine our source address.
- */
- if (device != NULL)
- setsin(from, al->addr);
- else if ((err = findsaddr(to, from)) != NULL) {
- DEBUGMSGTL(("traceRouteCtlTable",
- " findsaddr: %sn", err));
- exit(1);
- }
- } else {
- hi = gethostinfo(source);
- source = hi->name;
- hi->name = NULL;
- /*
- * If the device was specified make sure it
- * corresponds to the source address specified.
- * Otherwise, use the first address (and warn if
- * there are more than one).
- */
- if (device != NULL) {
- for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
- if (*ap == al->addr)
- break;
- if (i <= 0) {
- DEBUGMSGTL(("traceRouteCtlTable",
- " %s is not on interface %.32sn",
- source, device));
- exit(1);
- }
- setsin(from, *ap);
- } else {
- setsin(from, hi->addrs[0]);
- if (hi->n > 1)
- DEBUGMSGTL(("traceRouteCtlTable",
- " Warning: %s has multiple addresses; using %sn",
- source, inet_ntoa(from->sin_addr)));
- }
- freehostinfo(hi);
- }
- /*
- * Revert to non-privileged user after opening sockets
- */
- setgid(getgid());
- setuid(getuid());
- outip->ip_src = from->sin_addr;
- #ifndef IP_HDRINCL
- if (bind(sndsock, (struct sockaddr *) from, sizeof(*from)) < 0) {
- DEBUGMSGTL(("traceRouteCtlTable",
- " bind: %sn", strerror(errno)));
- exit(1);
- }
- #endif
- DEBUGMSGTL(("traceRouteCtlTable",
- " to %s (%s)", hostname, inet_ntoa(to->sin_addr)));
- if (source)
- DEBUGMSGTL(("traceRouteCtlTable", " from %s", source));
- DEBUGMSGTL(("traceRouteCtlTable",
- ", %d hops max, %d byte packetsn",
- item->traceRouteCtlMaxTtl, packlen));
- (void) fflush(stderr);
- struct traceRouteResultsTable_data *StorageResults = NULL;
- netsnmp_variable_list *vars_results = NULL;
- struct traceRouteHopsTable_data *StorageHops = NULL;
- struct traceRouteHopsTable_data *temp = NULL;
- struct traceRouteHopsTable_data *current_temp = NULL;
- struct traceRouteHopsTable_data *current = NULL;
- unsigned long index = 0;
- struct traceRouteProbeHistoryTable_data *StorageProbe = NULL;
- struct traceRouteProbeHistoryTable_data *temp_his = NULL;
- struct traceRouteProbeHistoryTable_data *current_temp_his = NULL;
- netsnmp_variable_list *vars_probe = NULL;
- snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */
- snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */
- if ((StorageResults =
- header_complex_get(traceRouteResultsTableStorage,
- vars_results)) == NULL)
- return;
- snmp_free_varbind(vars_results);
- vars_results = NULL;
- for (ttl = item->traceRouteCtlInitialTtl;
- ttl <= item->traceRouteCtlMaxTtl; ++ttl) {
- u_int32_t lastaddr = 0;
- int gotlastaddr = 0;
- int got_there = 0;
- int unreachable = 0;
- int sentfirst = 0;
- time_t timep = 0;
- StorageResults->traceRouteResultsCurHopCount = ttl;
- if (item->traceRouteCtlCreateHopsEntries == 1) {
- if (ttl == item->traceRouteCtlInitialTtl) {
- int k = 0;
- count = traceRouteHopsTable_count(item);
- struct traceRouteHopsTable_data *StorageTmp = NULL;
- struct header_complex_index *hciptr2 = NULL;
- netsnmp_variable_list *vars = NULL;
- oid newoid[MAX_OID_LEN];
- size_t newoid_len;
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */
- header_complex_generate_oid(newoid, &newoid_len, NULL,
- 0, vars);
- for (hciptr2 = traceRouteHopsTableStorage;
- hciptr2 != NULL; hciptr2 = hciptr2->next) {
- if (snmp_oid_compare
- (newoid, newoid_len, hciptr2->name,
- newoid_len) == 0) {
- StorageTmp =
- header_complex_extract_entry
- (&traceRouteHopsTableStorage, hciptr2);
- old_HopsAddress[k] =
- (char *) malloc(StorageTmp->
- traceRouteHopsIpTgtAddressLen
- + 1);
- if (old_HopsAddress[k] == NULL) {
- exit(1);
- }
- memdup((u_char **) & old_HopsAddress[k],
- StorageTmp->traceRouteHopsIpTgtAddress,
- StorageTmp->
- traceRouteHopsIpTgtAddressLen + 1);
- old_HopsAddress[k][StorageTmp->
- traceRouteHopsIpTgtAddressLen]
- = '';
- k++;
- StorageTmp = NULL;
- }
- }
- traceRouteHopsTable_del(item);
- index = 0;
- }
- temp = SNMP_MALLOC_STRUCT(traceRouteHopsTable_data);
- temp->traceRouteCtlOwnerIndex =
- (char *) malloc(item->traceRouteCtlOwnerIndexLen + 1);
- memcpy(temp->traceRouteCtlOwnerIndex,
- item->traceRouteCtlOwnerIndex,
- item->traceRouteCtlOwnerIndexLen + 1);
- temp->traceRouteCtlOwnerIndex[item->
- traceRouteCtlOwnerIndexLen] =
- '';
- temp->traceRouteCtlOwnerIndexLen =
- item->traceRouteCtlOwnerIndexLen;
- temp->traceRouteCtlTestName =
- (char *) malloc(item->traceRouteCtlTestNameLen + 1);
- memcpy(temp->traceRouteCtlTestName,
- item->traceRouteCtlTestName,
- item->traceRouteCtlTestNameLen + 1);
- temp->traceRouteCtlTestName[item->
- traceRouteCtlTestNameLen] =
- '';
- temp->traceRouteCtlTestNameLen =
- item->traceRouteCtlTestNameLen;
- /* add lock to protect */
- pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
- pthread_mutex_lock(&counter_mutex);
- temp->traceRouteHopsHopIndex = ++index;
- pthread_mutex_unlock(&counter_mutex);
- /* endsadsadsad */
- temp->traceRouteHopsIpTgtAddressType = 0;
- temp->traceRouteHopsIpTgtAddress = strdup("");
- temp->traceRouteHopsIpTgtAddressLen = 0;
- temp->traceRouteHopsMinRtt = 0;
- temp->traceRouteHopsMaxRtt = 0;
- temp->traceRouteHopsAverageRtt = 0;
- temp->traceRouteHopsRttSumOfSquares = 0;
- temp->traceRouteHopsSentProbes = 0;
- temp->traceRouteHopsProbeResponses = 0;
- temp->traceRouteHopsLastGoodProbe = strdup("");
- temp->traceRouteHopsLastGoodProbeLen = 0;
- if (index == 1)
- item->traceRouteHops = temp;
- else {
- (current_temp)->next = temp;
- }
- current_temp = temp;
- if (index + 1 >= item->traceRouteCtlMaxTtl) {
- current_temp->next = NULL;
- }
- if (item->traceRouteHops != NULL)
- if (traceRouteHopsTable_add(current_temp) !=
- SNMPERR_SUCCESS)
- DEBUGMSGTL(("traceRouteHopsTable",
- "registered an entry errorn"));
- }
- register unsigned long maxRtt = 0;
- register unsigned long minRtt = 0;
- register unsigned long averageRtt = 0;
- register unsigned long sumRtt = 0;
- register unsigned long responseProbe = 0;
- register unsigned long sumOfSquare = 0;
- for (probe = 0; probe < nprobes; ++probe) {
- register int cc;
- struct timeval t1, t2;
- struct timezone tz;
- register struct ip *ip = NULL;
- register unsigned long Rtt = 0;
- if (sentfirst && pausemsecs > 0)
- usleep(pausemsecs * 1000);
- (void) gettimeofday(&t1, &tz);
- send_probe(to, ++seq, ttl, &t1, outip, outudp, packlen,
- optlen, hostname, ident, sndsock, port,
- outdata);
- ++sentfirst;
- while ((cc =
- wait_for_reply(s, from, &t1, packet,
- waittime)) != 0) {
- (void) gettimeofday(&t2, &tz);
- timep = 0;
- time(&timep);
- i = packet_ok(packet, cc, from, seq, ident, pmtu,
- port);
- /*
- * Skip short packet
- */
- if (i == 0)
- continue;
- if (!gotlastaddr || from->sin_addr.s_addr != lastaddr) {
- register struct ip *ip;
- register int hlen;
- ip = (struct ip *) packet;
- hlen = ip->ip_hl << 2;
- cc -= hlen;
- DEBUGMSGTL(("traceRouteCtlTable",
- " %s", inet_ntoa(from->sin_addr)));
- lastaddr = from->sin_addr.s_addr;
- ++gotlastaddr;
- }
- Rtt = deltaT(&t1, &t2);
- responseProbe = responseProbe + 1;
- if (probe == 0) {
- minRtt = Rtt;
- maxRtt = Rtt;
- averageRtt = Rtt;
- sumRtt = Rtt;
- sumOfSquare = Rtt * Rtt;
- } else {
- if (Rtt < minRtt)
- minRtt = Rtt;
- if (Rtt > maxRtt)
- maxRtt = Rtt;
- sumRtt = (sumRtt) + Rtt;
- averageRtt =
- round((double) (sumRtt) /
- (double) responseProbe);
- sumOfSquare = sumOfSquare + Rtt * Rtt;
- }
- StorageResults->traceRouteResultsCurProbeCount =
- probe + 1;
- if (i == -2) {
- #ifndef ARCHAIC
- ip = (struct ip *) packet;
- if (ip->ip_ttl <= 1)
- Printf(" !");
- #endif
- ++got_there;
- break;
- }
- /*
- * time exceeded in transit
- */
- if (i == -1)
- break;
- code = i - 1;
- switch (code) {
- case ICMP_UNREACH_PORT:
- #ifndef ARCHAIC
- ip = (struct ip *) packet;
- if (ip->ip_ttl <= 1)
- Printf(" !");
- #endif
- ++got_there;
- break;
- case ICMP_UNREACH_NET:
- ++unreachable;
- Printf(" !N");
- break;
- case ICMP_UNREACH_HOST:
- ++unreachable;
- Printf(" !H");
- break;
- case ICMP_UNREACH_PROTOCOL:
- ++got_there;
- Printf(" !P");
- break;
- case ICMP_UNREACH_NEEDFRAG:
- ++unreachable;
- Printf(" !F-%d", pmtu);
- break;
- case ICMP_UNREACH_SRCFAIL:
- ++unreachable;
- Printf(" !S");
- break;
- case ICMP_UNREACH_FILTER_PROHIB:
- ++unreachable;
- Printf(" !X");
- break;
- case ICMP_UNREACH_HOST_PRECEDENCE:
- ++unreachable;
- Printf(" !V");
- break;
- case ICMP_UNREACH_PRECEDENCE_CUTOFF:
- ++unreachable;
- Printf(" !C");
- break;
- default:
- ++unreachable;
- Printf(" !<%d>", code);
- break;
- }
- break;
- }
- if (cc == 0) {
- timep = 0;
- time(&timep);
- Printf(" *");
- Rtt = (item->traceRouteCtlTimeOut) * 1000;
- }
- if (item->traceRouteCtlMaxRows != 0) {
- temp_his =
- SNMP_MALLOC_STRUCT
- (traceRouteProbeHistoryTable_data);
- temp_his->traceRouteCtlOwnerIndex =
- (char *) malloc(item->traceRouteCtlOwnerIndexLen +
- 1);
- memcpy(temp_his->traceRouteCtlOwnerIndex,
- item->traceRouteCtlOwnerIndex,
- item->traceRouteCtlOwnerIndexLen + 1);
- temp_his->traceRouteCtlOwnerIndex[item->
- traceRouteCtlOwnerIndexLen]
- = '';
- temp_his->traceRouteCtlOwnerIndexLen =
- item->traceRouteCtlOwnerIndexLen;
- temp_his->traceRouteCtlTestName =
- (char *) malloc(item->traceRouteCtlTestNameLen +
- 1);
- memcpy(temp_his->traceRouteCtlTestName,
- item->traceRouteCtlTestName,
- item->traceRouteCtlTestNameLen + 1);
- temp_his->traceRouteCtlTestName[item->
- traceRouteCtlTestNameLen]
- = '';
- temp_his->traceRouteCtlTestNameLen =
- item->traceRouteCtlTestNameLen;
- /* add lock to protect */
- pthread_mutex_t counter_mutex =
- PTHREAD_MUTEX_INITIALIZER;
- pthread_mutex_lock(&counter_mutex);
- if (item->traceRouteProbeHistoryMaxIndex >=
- (unsigned long) (2147483647))
- item->traceRouteProbeHistoryMaxIndex = 0;
- temp_his->traceRouteProbeHistoryIndex =
- ++(item->traceRouteProbeHistoryMaxIndex);
- pthread_mutex_unlock(&counter_mutex);
- /* endsadsadsad */
- temp_his->traceRouteProbeHistoryHopIndex = ttl;
- temp_his->traceRouteProbeHistoryProbeIndex = probe + 1;
- temp_his->traceRouteProbeHistoryHAddrType = 1;
- temp_his->traceRouteProbeHistoryHAddr =
- (char *) malloc(strlen(inet_ntoa(from->sin_addr)) +
- 1);
- strcpy(temp_his->traceRouteProbeHistoryHAddr,
- (inet_ntoa(from->sin_addr)));
- temp_his->
- traceRouteProbeHistoryHAddr[strlen
- (inet_ntoa
- (from->sin_addr))] =
- '';
- temp_his->traceRouteProbeHistoryHAddrLen =
- strlen(inet_ntoa(from->sin_addr));
- temp_his->traceRouteProbeHistoryResponse = Rtt;
- temp_his->traceRouteProbeHistoryStatus = 1;
- temp_his->traceRouteProbeHistoryLastRC = 0;
- temp_his->traceRouteProbeHistoryTime =
- (char *) malloc(strlen(asctime(gmtime(&timep))));
- temp_his->traceRouteProbeHistoryTime =
- strdup(asctime(gmtime(&timep)));
- temp_his->
- traceRouteProbeHistoryTime[strlen
- (asctime
- (gmtime(&timep))) -
- 1] = '';
- temp_his->traceRouteProbeHistoryTimeLen =
- strlen(asctime(gmtime(&timep))) - 1;
- if (probe == 0)
- item->traceRouteProbeHis = temp_his;
- else {
- (current_temp_his)->next = temp_his;
- }
- current_temp_his = temp_his;
- if (probe + 1 >= nprobes) {
- current_temp_his->next = NULL;
- }
- if (item->traceRouteProbeHis != NULL)
- if (traceRouteProbeHistoryTable_count(item) <
- item->traceRouteCtlMaxRows) {
- if (traceRouteProbeHistoryTable_add
- (current_temp_his) != SNMPERR_SUCCESS)
- DEBUGMSGTL(("traceRouteProbeHistoryTable",
- "registered an entry errorn"));
- } else {
- traceRouteProbeHistoryTable_delLast(item);
- if (traceRouteProbeHistoryTable_add
- (current_temp_his) != SNMPERR_SUCCESS)
- DEBUGMSGTL(("traceRouteProbeHistoryTable",
- "registered an entry errorn"));
- }
- }
- if (item->traceRouteCtlCreateHopsEntries == 1) {
- netsnmp_variable_list *vars_hops = NULL;
- snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */
- snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */
- snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_UNSIGNED, (char *) &index, sizeof(index)); /* traceRouteHopsIndex */
- if ((current =
- header_complex_get(traceRouteHopsTableStorage,
- vars_hops)) == NULL)
- return;
- snmp_free_varbind(vars_hops);
- vars_hops = NULL;
- current->traceRouteHopsIpTgtAddressType = 1;
- current->traceRouteHopsIpTgtAddress =
- (char *) malloc(strlen(inet_ntoa(from->sin_addr)) +
- 1);
- current->traceRouteHopsIpTgtAddress =
- strdup(inet_ntoa(from->sin_addr));
- current->
- traceRouteHopsIpTgtAddress[strlen
- (inet_ntoa
- (from->sin_addr))] =
- '';
- current->traceRouteHopsIpTgtAddressLen =
- strlen(inet_ntoa(from->sin_addr));
- if (count != 0) {
- if (strcmp
- (old_HopsAddress[index - 1],
- current->traceRouteHopsIpTgtAddress) != 0)
- flag = 1;
- }
- current->traceRouteHopsIpTgtAddressLen =
- strlen(inet_ntoa(from->sin_addr));
- current->traceRouteHopsMinRtt = minRtt;
- current->traceRouteHopsMaxRtt = maxRtt;
- current->traceRouteHopsAverageRtt = averageRtt;
- current->traceRouteHopsRttSumOfSquares = sumOfSquare;
- current->traceRouteHopsSentProbes = probe + 1;
- current->traceRouteHopsProbeResponses = responseProbe;
- current->traceRouteHopsLastGoodProbe =
- (char *) malloc(strlen(asctime(gmtime(&timep))));
- current->traceRouteHopsLastGoodProbe =
- strdup(asctime(gmtime(&timep)));
- current->
- traceRouteHopsLastGoodProbe[strlen
- (asctime
- (gmtime(&timep))) -
- 1] = '';
- current->traceRouteHopsLastGoodProbeLen =
- strlen(asctime(gmtime(&timep))) - 1;
- }
- (void) fflush(stdout);
- }
- putchar('n');
- if (got_there
- || (unreachable > 0 && unreachable >= nprobes - 1)) {
- if (got_there != 0) {
- StorageResults->traceRouteResultsTestAttempts =
- StorageResults->traceRouteResultsTestAttempts + 1;
- StorageResults->traceRouteResultsTestSuccesses =
- StorageResults->traceRouteResultsTestSuccesses + 1;
- StorageResults->traceRouteResultsLastGoodPath =
- (char *) malloc(strlen(asctime(gmtime(&timep))) -
- 1);
- StorageResults->traceRouteResultsLastGoodPath =
- strdup(asctime(gmtime(&timep)));
- StorageResults->
- traceRouteResultsLastGoodPath[strlen
- (asctime
- (gmtime(&timep))) -
- 1] = '';
- StorageResults->traceRouteResultsLastGoodPathLen =
- strlen(asctime(gmtime(&timep))) - 1;
- if ((item->
- traceRouteCtlTrapGeneration[0] &
- TRACEROUTETRAPGENERATION_TESTCOMPLETED) != 0) {
- DEBUGMSGTL(("traceRouteProbeHistoryTable",
- "TEST completed!n"));
- send_traceRoute_trap(item, traceRouteTestCompleted,
- sizeof
- (traceRouteTestCompleted) /
- sizeof(oid));
- }
- }
- else {
- StorageResults->traceRouteResultsTestAttempts =
- StorageResults->traceRouteResultsTestAttempts + 1;
- if ((item->
- traceRouteCtlTrapGeneration[0] &
- TRACEROUTETRAPGENERATION_TESTFAILED) != 0) {
- DEBUGMSGTL(("traceRouteProbeHistoryTable",
- "test Failed!n"));
- send_ping_trap(item, traceRouteTestFailed,
- sizeof(traceRouteTestFailed) /
- sizeof(oid));
- }
- }
- break;
- } else if (ttl == item->traceRouteCtlMaxTtl
- && (probe + 1) == nprobes) {
- StorageResults->traceRouteResultsTestAttempts =
- StorageResults->traceRouteResultsTestAttempts + 1;
- if ((item->
- traceRouteCtlTrapGeneration[0] &
- TRACEROUTETRAPGENERATION_TESTFAILED) != 0) {
- DEBUGMSGTL(("traceRouteProbeHistoryTable",
- "test Failed!n"));
- send_ping_trap(item, traceRouteTestFailed,
- sizeof(traceRouteTestFailed) /
- sizeof(oid));
- }
- }
- }
- if (flag == 1) {
- DEBUGMSGTL(("traceRouteProbeHistoryTable", "path changed!n"));
- send_traceRoute_trap(item, traceRoutePathChange,
- sizeof(traceRoutePathChange) /
- sizeof(oid));
- }
- int k = 0;
- for (k = 0; k < count; k++) {
- free(old_HopsAddress[k]);
- old_HopsAddress[k] = NULL;
- }
- }
- if (item->traceRouteCtlTargetAddressType == 2) {
- static char SNAPSHOT[] = "020124";
- int icmp_sock = 0; /* receive (icmp) socket file descriptor */
- int sndsock = 0; /* send (udp) socket file descriptor */
- struct timezone tz; /* leftover */
- struct sockaddr_in6 whereto; /* Who to try to reach */
- struct sockaddr_in6 saddr;
- struct sockaddr_in6 firsthop;
- char *source = NULL;
- char *device = NULL;
- char *hostname = NULL;
- pid_t ident = 0;
- u_short port = 32768 + 666; /* start udp dest port # for probe packets */
- int options = 0; /* socket options */
- int verbose = 0;
- int waittime = 5; /* time to wait for response (in seconds) */
- int nflag = 0; /* print addresses numerically */
- char *sendbuff = NULL;
- int datalen = sizeof(struct pkt_format);
- u_char packet[512]; /* last inbound (icmp) packet */
- char pa[64];
- struct hostent *hp = NULL;
- struct sockaddr_in6 from, *to = NULL;
- int ch = 0, i = 0, on = 0, probe = 0, seq = 0, tos =
- 0, ttl = 0;
- int socket_errno = 0;
- icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
- socket_errno = errno;
- setuid(getuid());
- on = 1;
- seq = tos = 0;
- to = (struct sockaddr_in6 *) &whereto;
- hostname =
- (char *) malloc(item->traceRouteCtlTargetAddressLen + 1);
- memcpy(hostname, item->traceRouteCtlTargetAddress,
- item->traceRouteCtlTargetAddressLen + 1);
- hostname[item->traceRouteCtlTargetAddressLen] = '';
- setlinebuf(stdout);
- (void) bzero((char *) &whereto, sizeof(struct sockaddr_in6));
- to->sin6_family = AF_INET6;
- to->sin6_port = htons(port);
- if (inet_pton(AF_INET6, hostname, &to->sin6_addr) > 0) {
- NULL;
- } else {
- hp = gethostbyname2(hostname, AF_INET6);
- if (hp != NULL) {
- memmove((caddr_t) & to->sin6_addr, hp->h_addr, 16);
- hostname = (char *) hp->h_name;
- } else {
- (void) fprintf(stderr,
- "traceroute: unknown host %sn", hostname);
- return;
- }
- }
- firsthop = *to;
- datalen = item->traceRouteCtlDataSize;
- if (datalen < (int) sizeof(struct pkt_format)
- || datalen >= MAXPACKET) {
- Fprintf(stderr,
- "traceroute: packet size must be %d <= s < %d.n",
- (int) sizeof(struct pkt_format), MAXPACKET);
- datalen = 16;
- }
- ident = getpid();
- sendbuff = malloc(datalen);
- if (sendbuff == NULL) {
- fprintf(stderr, "malloc failedn");
- return;
- }
- if (icmp_sock < 0) {
- errno = socket_errno;
- perror("traceroute6: icmp socket");
- return;
- }
- if (options & SO_DEBUG)
- setsockopt(icmp_sock, SOL_SOCKET, SO_DEBUG,
- (char *) &on, sizeof(on));
- if (options & SO_DONTROUTE)
- setsockopt(icmp_sock, SOL_SOCKET, SO_DONTROUTE,
- (char *) &on, sizeof(on));
- if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
- perror("traceroute: UDP socket");
- return;
- }
- #ifdef SO_SNDBUF
- if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *) &datalen,
- sizeof(datalen)) < 0) {
- perror("traceroute: SO_SNDBUF");
- return;
- }
- #endif /* SO_SNDBUF */
- if (options & SO_DEBUG)
- (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
- (char *) &on, sizeof(on));
- if (options & SO_DONTROUTE)
- (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
- (char *) &on, sizeof(on));
- if (source == NULL) {
- int alen;
- int probe_fd = socket(AF_INET6, SOCK_DGRAM, 0);
- if (probe_fd < 0) {
- perror("socket");
- return;
- }
- if (device) {
- if (setsockopt
- (probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device,
- strlen(device) + 1) == -1)
- perror("WARNING: interface is ignored");
- }
- firsthop.sin6_port = htons(1025);
- if (connect
- (probe_fd, (struct sockaddr *) &firsthop,
- sizeof(firsthop)) == -1) {
- perror("connect");
- return;
- }
- alen = sizeof(saddr);
- if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) ==
- -1) {
- perror("getsockname");
- return;
- }
- saddr.sin6_port = 0;
- close(probe_fd);
- } else {
- (void) bzero((char *) &saddr, sizeof(struct sockaddr_in6));
- saddr.sin6_family = AF_INET6;
- if (inet_pton(AF_INET6, source, &saddr.sin6_addr) < 0) {
- Printf("traceroute: unknown addr %sn", source);
- return;
- }
- }
- if (bind(sndsock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
- perror("traceroute: bind sending socket");
- return;
- }
- if (bind(icmp_sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
- perror("traceroute: bind icmp6 socket");
- return;
- }
- Fprintf(stderr, "traceroute to %s (%s)", hostname,
- inet_ntop(AF_INET6, &to->sin6_addr, pa, 64));
- Fprintf(stderr, " from %s",
- inet_ntop(AF_INET6, &saddr.sin6_addr, pa, 64));
- Fprintf(stderr, ", %d hops max, %d byte packetsn",
- item->traceRouteCtlMaxTtl, datalen);
- (void) fflush(stderr);
- struct traceRouteResultsTable_data *StorageResults = NULL;
- netsnmp_variable_list *vars_results = NULL;
- struct traceRouteHopsTable_data *StorageHops = NULL;
- struct traceRouteHopsTable_data *temp = NULL;
- struct traceRouteHopsTable_data *current_temp = NULL;
- struct traceRouteHopsTable_data *current = NULL;
- unsigned long index = 0;
- struct traceRouteProbeHistoryTable_data *StorageProbe = NULL;
- struct traceRouteProbeHistoryTable_data *temp_his = NULL;
- struct traceRouteProbeHistoryTable_data *current_temp_his = NULL;
- netsnmp_variable_list *vars_probe = NULL;
- snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */
- snmp_varlist_add_variable(&vars_results, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */
- if ((StorageResults =
- header_complex_get(traceRouteResultsTableStorage,
- vars_results)) == NULL)
- return;
- snmp_free_varbind(vars_results);
- vars_results = NULL;
- for (ttl = item->traceRouteCtlInitialTtl;
- ttl <= item->traceRouteCtlMaxTtl; ++ttl) {
- struct in6_addr lastaddr = { {{0,}} };
- int got_there = 0;
- int unreachable = 0;
- time_t timep = 0;
- Printf("%2d ", ttl);
- StorageResults->traceRouteResultsCurHopCount = ttl;
- if (item->traceRouteCtlCreateHopsEntries == 1) {
- if (ttl == item->traceRouteCtlInitialTtl) {
- int k = 0;
- count = traceRouteHopsTable_count(item);
- struct traceRouteHopsTable_data *StorageTmp = NULL;
- struct header_complex_index *hciptr2 = NULL;
- netsnmp_variable_list *vars = NULL;
- oid newoid[MAX_OID_LEN];
- size_t newoid_len;
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */
- snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */
- header_complex_generate_oid(newoid, &newoid_len, NULL,
- 0, vars);
- snmp_free_varbind(vars);
- vars = NULL;
- for (hciptr2 = traceRouteHopsTableStorage;
- hciptr2 != NULL; hciptr2 = hciptr2->next) {
- if (snmp_oid_compare
- (newoid, newoid_len, hciptr2->name,
- newoid_len) == 0) {
- StorageTmp =
- header_complex_extract_entry
- (&traceRouteHopsTableStorage, hciptr2);
- old_HopsAddress[k] =
- (char *) malloc(StorageTmp->
- traceRouteHopsIpTgtAddressLen
- + 1);
- if (old_HopsAddress[k] == NULL) {
- exit(1);
- }
- memdup((u_char **) & old_HopsAddress[k],
- StorageTmp->traceRouteHopsIpTgtAddress,
- StorageTmp->
- traceRouteHopsIpTgtAddressLen + 1);
- old_HopsAddress[k][StorageTmp->
- traceRouteHopsIpTgtAddressLen]
- = '';
- k++;
- }
- }
- traceRouteHopsTable_del(item);
- index = 0;
- }
- temp = SNMP_MALLOC_STRUCT(traceRouteHopsTable_data);
- temp->traceRouteCtlOwnerIndex =
- (char *) malloc(item->traceRouteCtlOwnerIndexLen + 1);
- memcpy(temp->traceRouteCtlOwnerIndex,
- item->traceRouteCtlOwnerIndex,
- item->traceRouteCtlOwnerIndexLen + 1);
- temp->traceRouteCtlOwnerIndex[item->
- traceRouteCtlOwnerIndexLen] =
- '';
- temp->traceRouteCtlOwnerIndexLen =
- item->traceRouteCtlOwnerIndexLen;
- temp->traceRouteCtlTestName =
- (char *) malloc(item->traceRouteCtlTestNameLen + 1);
- memcpy(temp->traceRouteCtlTestName,
- item->traceRouteCtlTestName,
- item->traceRouteCtlTestNameLen + 1);
- temp->traceRouteCtlTestName[item->
- traceRouteCtlTestNameLen] =
- '';
- temp->traceRouteCtlTestNameLen =
- item->traceRouteCtlTestNameLen;
- /* add lock to protect */
- pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
- pthread_mutex_lock(&counter_mutex);
- temp->traceRouteHopsHopIndex = ++index;
- pthread_mutex_unlock(&counter_mutex);
- /* endsadsadsad */
- temp->traceRouteHopsIpTgtAddressType = 0;
- temp->traceRouteHopsIpTgtAddress = strdup("");
- temp->traceRouteHopsIpTgtAddressLen = 0;
- temp->traceRouteHopsMinRtt = 0;
- temp->traceRouteHopsMaxRtt = 0;
- temp->traceRouteHopsAverageRtt = 0;
- temp->traceRouteHopsRttSumOfSquares = 0;
- temp->traceRouteHopsSentProbes = 0;
- temp->traceRouteHopsProbeResponses = 0;
- temp->traceRouteHopsLastGoodProbe = strdup("");
- temp->traceRouteHopsLastGoodProbeLen = 0;
- if (index == 1)
- item->traceRouteHops = temp;
- else {
- (current_temp)->next = temp;
- }
- current_temp = temp;
- if (index >= item->traceRouteCtlMaxTtl) {
- current_temp->next = NULL;
- }
- if (item->traceRouteHops != NULL)
- if (traceRouteHopsTable_add(current_temp) !=
- SNMPERR_SUCCESS)
- DEBUGMSGTL(("traceRouteHopsTable",
- "registered an entry errorn"));
- }
- register unsigned long maxRtt = 0;
- register unsigned long minRtt = 0;
- register unsigned long averageRtt = 0;
- register unsigned long sumRtt = 0;
- register unsigned long responseProbe = 0;
- register unsigned long sumOfSquare = 0;
- for (probe = 0; probe < nprobes; ++probe) {
- int cc = 0, reset_timer = 0;
- struct timeval t1, t2;
- struct timezone tz;
- register unsigned long Rtt = 0;
- gettimeofday(&t1, &tz);
- send_probe_v6(++seq, ttl, sendbuff, ident, &tz, sndsock,
- datalen, &whereto, hostname);
- reset_timer = 1;
- while ((cc =
- wait_for_reply_v6(icmp_sock, &from, reset_timer,
- waittime, icmp_sock,
- packet)) != 0) {
- gettimeofday(&t2, &tz);
- timep = 0;
- time(&timep);
- if ((i =
- packet_ok_v6(packet, cc, &from, seq, &t1,
- ident))) {
- reset_timer = 1;
- if (memcmp
- (&from.sin6_addr, &lastaddr,
- sizeof(struct in6_addr))) {
- memcpy(&lastaddr,
- &from.sin6_addr,
- sizeof(struct in6_addr));
- }
- Rtt = deltaT(&t1, &t2);
- responseProbe = responseProbe + 1;
- if (probe == 0) {
- minRtt = Rtt;
- maxRtt = Rtt;
- averageRtt = Rtt;
- sumRtt = Rtt;
- sumOfSquare = Rtt * Rtt;
- } else {
- if (Rtt < minRtt)
- minRtt = Rtt;
- if (Rtt > maxRtt)
- maxRtt = Rtt;
- sumRtt = (sumRtt) + Rtt;
- averageRtt =
- round((double) (sumRtt) /
- (double) responseProbe);
- sumOfSquare = sumOfSquare + Rtt * Rtt;
- }
- StorageResults->traceRouteResultsCurProbeCount =
- probe + 1;
- switch (i - 1) {
- case ICMPV6_PORT_UNREACH:
- ++got_there;
- break;
- case ICMPV6_NOROUTE:
- ++unreachable;
- Printf(" !N");
- break;
- case ICMPV6_ADDR_UNREACH:
- ++unreachable;
- Printf(" !H");
- break;
- case ICMPV6_ADM_PROHIBITED:
- ++unreachable;
- Printf(" !S");
- break;
- }
- break;
- } else
- reset_timer = 0;
- }
- if (cc == 0) {
- timep = 0;
- time(&timep);
- Printf(" *");
- Rtt = (item->traceRouteCtlTimeOut) * 1000;
- }
- if (item->traceRouteCtlMaxRows != 0) {
- temp_his =
- SNMP_MALLOC_STRUCT
- (traceRouteProbeHistoryTable_data);
- temp_his->traceRouteCtlOwnerIndex =
- (char *) malloc(item->traceRouteCtlOwnerIndexLen +
- 1);
- memcpy(temp_his->traceRouteCtlOwnerIndex,
- item->traceRouteCtlOwnerIndex,
- item->traceRouteCtlOwnerIndexLen + 1);
- temp_his->traceRouteCtlOwnerIndex[item->
- traceRouteCtlOwnerIndexLen]
- = '';
- temp_his->traceRouteCtlOwnerIndexLen =
- item->traceRouteCtlOwnerIndexLen;
- temp_his->traceRouteCtlTestName =
- (char *) malloc(item->traceRouteCtlTestNameLen +
- 1);
- memcpy(temp_his->traceRouteCtlTestName,
- item->traceRouteCtlTestName,
- item->traceRouteCtlTestNameLen + 1);
- temp_his->traceRouteCtlTestName[item->
- traceRouteCtlTestNameLen]
- = '';
- temp_his->traceRouteCtlTestNameLen =
- item->traceRouteCtlTestNameLen;
- /* add lock to protect */
- pthread_mutex_t counter_mutex =
- PTHREAD_MUTEX_INITIALIZER;
- pthread_mutex_lock(&counter_mutex);
- if (item->traceRouteProbeHistoryMaxIndex >=
- (unsigned long) (2147483647))
- item->traceRouteProbeHistoryMaxIndex = 0;
- temp_his->traceRouteProbeHistoryIndex =
- ++(item->traceRouteProbeHistoryMaxIndex);
- pthread_mutex_unlock(&counter_mutex);
- /* endsadsadsad */
- temp_his->traceRouteProbeHistoryHopIndex = ttl;
- temp_his->traceRouteProbeHistoryProbeIndex = probe + 1;
- temp_his->traceRouteProbeHistoryHAddrType = 2;
- temp_his->traceRouteProbeHistoryHAddr =
- (char *)
- malloc(strlen
- (inet_ntop
- (AF_INET6, &from.sin6_addr, pa, 64)) + 1);
- temp_his->traceRouteProbeHistoryHAddr =
- strdup(inet_ntop
- (AF_INET6, &from.sin6_addr, pa, 64));
- temp_his->
- traceRouteProbeHistoryHAddr[strlen
- (inet_ntop
- (AF_INET6,
- &from.sin6_addr, pa,
- 64))] = '';
- temp_his->traceRouteProbeHistoryHAddrLen =
- strlen(inet_ntop
- (AF_INET6, &from.sin6_addr, pa, 64));
- temp_his->traceRouteProbeHistoryResponse = Rtt;
- temp_his->traceRouteProbeHistoryStatus = 1;
- temp_his->traceRouteProbeHistoryLastRC = 0;
- temp_his->traceRouteProbeHistoryTime =
- (char *) malloc(strlen(asctime(gmtime(&timep))));
- temp_his->traceRouteProbeHistoryTime =
- strdup(asctime(gmtime(&timep)));
- temp_his->
- traceRouteProbeHistoryTime[strlen
- (asctime
- (gmtime(&timep))) -
- 1] = '';
- temp_his->traceRouteProbeHistoryTimeLen =
- strlen(asctime(gmtime(&timep))) - 1;
- if (probe == 0)
- item->traceRouteProbeHis = temp_his;
- else {
- (current_temp_his)->next = temp_his;
- }
- current_temp_his = temp_his;
- if (probe + 1 >= nprobes) {
- current_temp_his->next = NULL;
- }
- if (item->traceRouteProbeHis != NULL)
- if (traceRouteProbeHistoryTable_count(item) <
- item->traceRouteCtlMaxRows) {
- if (traceRouteProbeHistoryTable_add
- (current_temp_his) != SNMPERR_SUCCESS)
- DEBUGMSGTL(("traceRouteProbeHistoryTable",
- "registered an entry errorn"));
- } else {
- traceRouteProbeHistoryTable_delLast(item);
- if (traceRouteProbeHistoryTable_add
- (current_temp_his) != SNMPERR_SUCCESS)
- DEBUGMSGTL(("traceRouteProbeHistoryTable",
- "registered an entry errorn"));
- }
- }
- if (item->traceRouteCtlCreateHopsEntries == 1) {
- netsnmp_variable_list *vars_hops = NULL;
- snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlOwnerIndex, item->traceRouteCtlOwnerIndexLen); /* traceRouteCtlOwnerIndex */
- snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_OCTET_STR, (char *) item->traceRouteCtlTestName, item->traceRouteCtlTestNameLen); /* traceRouteCtlTestName */
- snmp_varlist_add_variable(&vars_hops, NULL, 0, ASN_UNSIGNED, (char *) &index, sizeof(index)); /* traceRouteHopsIndex */
- if ((current =
- header_complex_get(traceRouteHopsTableStorage,
- vars_hops)) == NULL)
- return;
- current->traceRouteHopsIpTgtAddressType = 2;
- current->traceRouteHopsIpTgtAddress =
- (char *)
- malloc(strlen
- (inet_ntop
- (AF_INET6, &from.sin6_addr, pa, 64)) + 1);
- current->traceRouteHopsIpTgtAddress =
- strdup(inet_ntop
- (AF_INET6, &from.sin6_addr, pa, 64));
- current->
- traceRouteHopsIpTgtAddress[strlen
- (inet_ntop
- (AF_INET6,
- &from.sin6_addr, pa,
- 64))] = '';
- if (count != 0) {
- if (strcmp
- (old_HopsAddress[index - 1],
- current->traceRouteHopsIpTgtAddress) != 0)
- flag = 1;
- }
- current->traceRouteHopsIpTgtAddressLen =
- strlen(inet_ntop
- (AF_INET6, &from.sin6_addr, pa, 64));
- current->traceRouteHopsMinRtt = minRtt;
- current->traceRouteHopsMaxRtt = maxRtt;
- current->traceRouteHopsAverageRtt = averageRtt;
- current->traceRouteHopsRttSumOfSquares = sumOfSquare;
- current->traceRouteHopsSentProbes = probe + 1;
- current->traceRouteHopsProbeResponses = responseProbe;
- current->traceRouteHopsLastGoodProbe =
- (char *) malloc(strlen(asctime(gmtime(&timep))));
- current->traceRouteHopsLastGoodProbe =
- strdup(asctime(gmtime(&timep)));
- current->
- traceRouteHopsLastGoodProbe[strlen
- (asctime
- (gmtime(&timep))) -
- 1] = '';
- current->traceRouteHopsLastGoodProbeLen =
- strlen(asctime(gmtime(&timep))) - 1;
- snmp_free_varbind(vars_hops);
- vars_hops = NULL;
- }
- (void) fflush(stdout);
- }
- putchar('n');
- if (got_there || unreachable >= nprobes - 1) {
- if (got_there != 0) {
- StorageResults->traceRouteResultsTestAttempts =
- StorageResults->traceRouteResultsTestAttempts + 1;
- StorageResults->traceRouteResultsTestSuccesses =
- StorageResults->traceRouteResultsTestSuccesses + 1;
- StorageResults->traceRouteResultsLastGoodPath =
- (char *) malloc(strlen(asctime(gmtime(&timep))) -
- 1);
- StorageResults->traceRouteResultsLastGoodPath =
- strdup(asctime(gmtime(&timep)));
- StorageResults->
- traceRouteResultsLastGoodPath[strlen
- (asctime
- (gmtime(&timep))) -
- 1] = '';
- StorageResults->traceRouteResultsLastGoodPathLen =
- strlen(asctime(gmtime(&timep))) - 1;
- if ((item->
- traceRouteCtlTrapGeneration[0] &
- TRACEROUTETRAPGENERATION_TESTCOMPLETED) != 0) {
- printf("TEST completed!n");
- send_traceRoute_trap(item, traceRouteTestCompleted,
- sizeof
- (traceRouteTestCompleted) /
- sizeof(oid));
- }
- }
- else {
- StorageResults->traceRouteResultsTestAttempts =
- StorageResults->traceRouteResultsTestAttempts + 1;
- if ((item->
- traceRouteCtlTrapGeneration[0] &
- TRACEROUTETRAPGENERATION_TESTFAILED) != 0) {
- printf("test Failed!n");
- send_traceRoute_trap(item, traceRouteTestFailed,
- sizeof(traceRouteTestFailed) /
- sizeof(oid));
- }
- }
- break;
- } else if (ttl == item->traceRouteCtlMaxTtl
- && (probe + 1) == nprobes) {
- StorageResults->traceRouteResultsTestAttempts =
- StorageResults->traceRouteResultsTestAttempts + 1;
- if ((item->
- traceRouteCtlTrapGeneration[0] &
- TRACEROUTETRAPGENERATION_TESTFAILED) != 0) {
- printf("test Failed!n");
- send_ping_trap(item, traceRouteTestFailed,
- sizeof(traceRouteTestFailed) /
- sizeof(oid));
- }
- }
- }
- if (flag == 1) {
- printf("path changed!n");
- send_traceRoute_trap(item, traceRoutePathChange,
- sizeof(traceRoutePathChange) /
- sizeof(oid));
- }
- int k = 0;
- for (k = 0; k < count; k++) {
- free(old_HopsAddress[k]);
- old_HopsAddress[k] = NULL;
- }
- }
- return;
- }
- int
- wait_for_reply(register int sock, register struct sockaddr_in *fromp,
- register const struct timeval *tp, u_char * packet,
- int waittime)
- {
- fd_set fds;
- struct timeval now, wait;
- struct timezone tz;
- register int cc = 0;
- int fromlen = sizeof(*fromp);
- FD_ZERO(&fds);
- FD_SET(sock, &fds);
- wait.tv_sec = tp->tv_sec + waittime;
- wait.tv_usec = tp->tv_usec;
- (void) gettimeofday(&now, &tz);
- tvsub(&wait, &now);
- if (select(sock + 1, &fds, NULL, NULL, &wait) > 0)
- cc = recvfrom(sock, (char *) packet, 512, 0,
- (struct sockaddr *) fromp, &fromlen);
- return (cc);
- }
- int
- wait_for_reply_v6(int sock, struct sockaddr_in6 *from, int reset_timer,
- int waittime, int icmp_sock, u_char * packet)
- {
- fd_set fds;
- static struct timeval wait;
- int cc = 0;
- int fromlen = sizeof(*from);
- FD_ZERO(&fds);
- FD_SET(sock, &fds);
- if (reset_timer) {
- /*
- * traceroute could hang if someone else has a ping
- * running and our ICMP reply gets dropped but we don't
- * realize it because we keep waking up to handle those
- * other ICMP packets that keep coming in. To fix this,
- * "reset_timer" will only be true if the last packet that
- * came in was for us or if this is the first time we're
- * waiting for a reply since sending out a probe. Note
- * that this takes advantage of the select() feature on
- * Linux where the remaining timeout is written to the
- * struct timeval area.
- */
- wait.tv_sec = waittime;
- wait.tv_usec = 0;
- }
- if (select(sock + 1, &fds, (fd_set *) 0, (fd_set *) 0, &wait) > 0) {
- cc = recvfrom(icmp_sock, (char *) packet, 512, 0,
- (struct sockaddr *) from, &fromlen);
- }
- return (cc);
- }
- void
- send_probe(struct sockaddr_in *whereto, register int seq, int ttl,
- register struct timeval *tp, register struct ip *outip,
- register struct udphdr *outudp, int packlen, int optlen,
- char *hostname, u_short ident, int sndsock, u_short port,
- struct outdata *outdata)
- {
- register int cc = 0;
- register struct udpiphdr *ui = NULL, *oui = NULL;
- struct ip tip;
- outip->ip_ttl = ttl;
- #ifndef __hpux
- outip->ip_id = htons(ident + seq);
- #endif
- /*
- * In most cases, the kernel will recalculate the ip checksum.
- * But we must do it anyway so that the udp checksum comes out
- * right.
- */
- outip->ip_sum =
- in_checksum((u_short *) outip, sizeof(*outip) + optlen);
- if (outip->ip_sum == 0)
- outip->ip_sum = 0xffff;
- /*
- * Payload
- */
- outdata->seq = seq;
- outdata->ttl = ttl;
- outdata->tv = *tp;
- outudp->dest = htons(port + seq);
- /*
- * Checksum (we must save and restore ip header)
- */
- tip = *outip;
- ui = (struct udpiphdr *) outip;
- oui = (struct udpiphdr *) &tip;
- /*
- * Easier to zero and put back things that are ok
- */
- memset((char *) ui, 0, sizeof(ui->ui_i));
- ui->ui_src = oui->ui_src;
- ui->ui_dst = oui->ui_dst;
- ui->ui_pr = oui->ui_pr;
- ui->ui_len = outudp->len;
- outudp->check = 0;
- outudp->check = in_checksum((u_short *) ui, packlen);
- if (outudp->check == 0)
- outudp->check = 0xffff;
- *outip = tip;
- /*
- * XXX undocumented debugging hack
- */
- #if !defined(IP_HDRINCL) && defined(IP_TTL)
- printf("ttln");
- if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
- (char *) &ttl, sizeof(ttl)) < 0) {
- Fprintf(stderr, "%s: setsockopt ttl %d: %sn",
- prog, ttl, strerror(errno));
- exit(1);
- }
- #endif
- #ifdef __hpux
- Printf("whereto=%sn",
- inet_ntoa(((struct sockaddr_in *) whereto)->sin_addr));
- cc = sendto(sndsock, (char *) outudp,
- packlen - (sizeof(*outip) + optlen), 0, whereto,
- sizeof(*whereto));
- if (cc > 0)
- cc += sizeof(*outip) + optlen;
- #else
- cc = sendto(sndsock, (char *) outip,
- packlen, 0, whereto, sizeof(*whereto));
- #endif
- if (cc < 0 || cc != packlen) {
- if (cc < 0)
- Fprintf(stderr, "%s: sendto: %sn", prog, strerror(errno));
- Printf("%s: wrote %s %d chars, ret=%dn",
- prog, hostname, packlen, cc);
- (void) fflush(stdout);
- }
- }
- void
- send_probe_v6(int seq, int ttl, char *sendbuff, pid_t ident,
- struct timezone *tz, int sndsock, int datalen,
- struct sockaddr_in6 *whereto, char *hostname)
- {
- struct pkt_format *pkt = (struct pkt_format *) sendbuff;
- int i = 0;
- pkt->ident = htonl(ident);
- pkt->seq = htonl(seq);
- gettimeofday(&pkt->tv, tz);
- i = setsockopt(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl,
- sizeof(int));
- if (i < 0) {
- perror("setsockopt");
- exit(1);
- }
- do {
- i = sendto(sndsock, sendbuff, datalen, 0,
- (struct sockaddr *) whereto,
- sizeof(struct sockaddr_in6));
- } while (i < 0 && errno == ECONNREFUSED);
- if (i < 0 || i != datalen) {
- if (i < 0)
- perror("sendto");
- Printf("traceroute: wrote %s %d chars, ret=%dn", hostname,
- datalen, i);
- (void) fflush(stdout);
- }
- }
- unsigned long
- deltaT(struct timeval *t1p, struct timeval *t2p)
- {
- register unsigned long dt;
- dt = (unsigned long) ((long) (t2p->tv_sec - t1p->tv_sec) * 1000 +
- (long) (t2p->tv_usec - t1p->tv_usec) / 1000);
- return (dt);
- }
- int
- packet_ok(register u_char * buf, int cc, register struct sockaddr_in *from,
- register int seq, u_short ident, int pmtu, u_short port)
- {
- register struct icmp *icp = NULL;
- register u_char type, code;
- register int hlen = 0;
- #ifndef ARCHAIC
- register struct ip *ip = NULL;
- ip = (struct ip *) buf;
- hlen = ip->ip_hl << 2;
- if (cc < hlen + ICMP_MINLEN) {
- return (0);
- }
- cc -= hlen;
- icp = (struct icmp *) (buf + hlen);
- #else
- icp = (struct icmp *) buf;
- #endif
- type = icp->icmp_type;
- code = icp->icmp_code;
- /*
- * Path MTU Discovery (RFC1191)
- */
- if (code != ICMP_UNREACH_NEEDFRAG)
- pmtu = 0;
- else {
- #ifdef HAVE_ICMP_NEXTMTU
- pmtu = ntohs(icp->icmp_nextmtu);
- #else
- pmtu = ntohs(((struct my_pmtu *) &icp->icmp_void)->ipm_nextmtu);
- #endif
- }
- if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
- type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
- register struct ip *hip;
- register struct udphdr *up;
- register struct icmp *hicmp;
- hip = &icp->icmp_ip;
- hlen = hip->ip_hl << 2;
- up = (struct udphdr *) ((u_char *) hip + hlen);
- /*
- * XXX 8 is a magic number
- */
- if (hlen + 12 <= cc &&
- hip->ip_p == IPPROTO_UDP &&
- up->source == htons(ident) && up->dest == htons(port + seq))
- return (type == ICMP_TIMXCEED ? -1 : code + 1);
- }
- return (0);
- }
- int
- packet_ok_v6(u_char * buf, int cc, struct sockaddr_in6 *from, int seq,
- struct timeval *tv, pid_t ident)
- {
- struct icmp6hdr *icp = NULL;
- u_char type, code;
- icp = (struct icmp6hdr *) buf;
- type = icp->icmp6_type;
- code = icp->icmp6_code;
- if ((type == ICMPV6_TIME_EXCEED && code == ICMPV6_EXC_HOPLIMIT) ||
- type == ICMPV6_DEST_UNREACH) {
- struct ipv6hdr *hip = NULL;
- struct udphdr *up = NULL;
- int nexthdr = 0;
- hip = (struct ipv6hdr *) (icp + 1);
- up = (struct udphdr *) (hip + 1);
- nexthdr = hip->nexthdr;
- if (nexthdr == 44) {
- nexthdr = *(unsigned char *) up;
- up++;
- }
- if (nexthdr == IPPROTO_UDP) {
- struct pkt_format *pkt;
- pkt = (struct pkt_format *) (up + 1);
- if (ntohl(pkt->ident) == ident && ntohl(pkt->seq) == seq) {
- *tv = pkt->tv;
- return (type == ICMPV6_TIME_EXCEED ? -1 : code + 1);
- }
- }
- }
- return (0);
- }
- /*
- * Checksum routine for Internet Protocol family headers (C Version)
- */
- u_short
- in_checksum(register u_short * addr, register int len)
- {
- register int nleft = len;
- register u_short *w = addr;
- register u_short answer;
- register int sum = 0;
- /*
- * Our algorithm is simple, using a 32 bit accumulator (sum),
- * we add sequential 16 bit words to it, and at the end, fold
- * back all the carry bits from the top 16 bits into the lower
- * 16 bits.
- */
- while (nleft > 1) {
- sum += *w++;
- nleft -= 2;
- }
- /*
- * mop up an odd byte, if necessary
- */
- if (nleft == 1)
- sum += *(u_char *) w;
- /*
- * add back carry outs from top 16 bits to low 16 bits
- */
- sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
- sum += (sum >> 16); /* add carry */
- answer = ~sum; /* truncate to 16 bits */
- return (answer);
- }
- /*
- * Subtract 2 timeval structs: out = out - in.
- * Out is assumed to be >= in.
- */
- void
- tvsub(register struct timeval *out, register struct timeval *in)
- {
- if ((out->tv_usec -= in->tv_usec) < 0) {
- --out->tv_sec;
- out->tv_usec += 1000000;
- }
- out->tv_sec -= in->tv_sec;
- }
- struct hostinfo *
- gethostinfo(register char *hostname)
- {
- register int n;
- register struct hostent *hp = NULL;
- register struct hostinfo *hi = NULL;
- register char **p = NULL;
- register u_int32_t addr, *ap = NULL;
- if (strlen(hostname) > 64) {
- Fprintf(stderr, "%s: hostname "%.32s..." is too longn",
- prog, hostname);
- exit(1);
- }
- hi = calloc(1, sizeof(*hi));
- if (hi == NULL) {
- Fprintf(stderr, "%s: calloc %sn", prog, strerror(errno));
- exit(1);
- }
- addr = inet_addr(hostname);
- if ((int32_t) addr != -1) {
- hi->name = strdup(hostname);
- hi->n = 1;
- hi->addrs = calloc(1, sizeof(hi->addrs[0]));
- if (hi->addrs == NULL) {
- Fprintf(stderr, "%s: calloc %sn", prog, strerror(errno));
- exit(1);
- }
- hi->addrs[0] = addr;
- return (hi);
- }
- hp = gethostbyname(hostname);
- if (hp == NULL) {
- Fprintf(stderr, "%s: unknown host %sn", prog, hostname);
- printf("hp=NULLn");
- exit(1);
- }
- if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
- Fprintf(stderr, "%s: bad host %sn", prog, hostname);
- exit(1);
- }
- hi->name = strdup(hp->h_name);
- for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
- continue;
- hi->n = n;
- hi->addrs = calloc(n, sizeof(hi->addrs[0]));
- if (hi->addrs == NULL) {
- Fprintf(stderr, "%s: calloc %sn", prog, strerror(errno));
- exit(1);
- }
- for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
- memcpy(ap, *p, sizeof(*ap));
- return (hi);
- }
- void
- freehostinfo(register struct hostinfo *hi)
- {
- if (hi->name != NULL) {
- free(hi->name);
- hi->name = NULL;
- }
- free((char *) hi->addrs);
- free((char *) hi);
- }
- void
- setsin(register struct sockaddr_in *sin, register u_int32_t addr)
- {
- memset(sin, 0, sizeof(*sin));
- #ifdef HAVE_SOCKADDR_SA_LEN
- sin->sin_len = sizeof(*sin);
- #endif
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = addr;
- }
- /*
- * Return the source address for the given destination address
- */
- const char *
- findsaddr(register const struct sockaddr_in *to,
- register struct sockaddr_in *from)
- {
- register int i, n;
- register FILE *f;
- register u_int32_t mask;
- u_int32_t dest, tmask;
- struct ifaddrlist *al;
- char buf[256], tdevice[256], device[256];
- static char errbuf[132];
- static const char route[] = "/proc/net/route";
- if ((f = fopen(route, "r")) == NULL) {
- sprintf(errbuf, "open %s: %.128s", route, strerror(errno));
- return (errbuf);
- }
- /*
- * Find the appropriate interface
- */
- n = 0;
- mask = 0;
- device[0] = '';
- while (fgets(buf, sizeof(buf), f) != NULL) {
- ++n;
- if (n == 1 && strncmp(buf, "Iface", 5) == 0)
- continue;
- if ((i = sscanf(buf, "%s %x %*s %*s %*s %*s %*s %x",
- tdevice, &dest, &tmask)) != 3)
- return ("junk in buffer");
- if ((to->sin_addr.s_addr & tmask) == dest &&
- (tmask > mask || mask == 0)) {
- mask = tmask;
- strcpy(device, tdevice);
- }
- }
- fclose(f);
- if (device[0] == '')
- return ("Can't find interface");
- /*
- * Get the interface address list
- */
- if ((n = ifaddrlist(&al, errbuf)) < 0)
- return (errbuf);
- if (n == 0)
- return ("Can't find any network interfaces");
- /*
- * Find our appropriate source address
- */
- for (i = n; i > 0; --i, ++al)
- if (strcmp(device, al->device) == 0)
- break;
- if (i <= 0) {
- sprintf(errbuf, "Can't find interface "%.32s"", device);
- return (errbuf);
- }
- setsin(from, al->addr);
- return (NULL);
- }
- int
- ifaddrlist(register struct ifaddrlist **ipaddrp, register char *errbuf)
- {
- register int fd, nipaddr;
- #ifdef HAVE_SOCKADDR_SA_LEN
- register int n;
- #endif
- register struct ifreq *ifrp, *ifend, *ifnext, *mp;
- register struct sockaddr_in *sin;
- register struct ifaddrlist *al;
- struct ifconf ifc;
- struct ifreq ibuf[(32 * 1024) / sizeof(struct ifreq)], ifr;
- #define MAX_IPADDR (sizeof(ibuf) / sizeof(ibuf[0]))
- static struct ifaddrlist ifaddrlist[MAX_IPADDR];
- char device[sizeof(ifr.ifr_name) + 1];
- fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd < 0) {
- (void) sprintf(errbuf, "socket: %s", strerror(errno));
- return (-1);
- }
- ifc.ifc_len = sizeof(ibuf);
- ifc.ifc_buf = (caddr_t) ibuf;
- if (ioctl(fd, SIOCGIFCONF, (char *) &ifc) < 0 ||
- ifc.ifc_len < sizeof(struct ifreq)) {
- if (errno == EINVAL)
- (void) sprintf(errbuf,
- "SIOCGIFCONF: ifreq struct too small (%d bytes)",
- sizeof(ibuf));
- else
- (void) sprintf(errbuf, "SIOCGIFCONF: %s", strerror(errno));
- (void) close(fd);
- return (-1);
- }
- ifrp = ibuf;
- ifend = (struct ifreq *) ((char *) ibuf + ifc.ifc_len);
- al = ifaddrlist;
- mp = NULL;
- nipaddr = 0;
- for (; ifrp < ifend; ifrp = ifnext) {
- #ifdef HAVE_SOCKADDR_SA_LEN
- n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
- if (n < sizeof(*ifrp))
- ifnext = ifrp + 1;
- else
- ifnext = (struct ifreq *) ((char *) ifrp + n);
- if (ifrp->ifr_addr.sa_family != AF_INET)
- continue;
- #else
- ifnext = ifrp + 1;
- #endif
- /*
- * Need a template to preserve address info that is
- * used below to locate the next entry. (Otherwise,
- * SIOCGIFFLAGS stomps over it because the requests
- * are returned in a union.)
- */
- strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
- if (ioctl(fd, SIOCGIFFLAGS, (char *) &ifr) < 0) {
- if (errno == ENXIO)
- continue;
- (void) sprintf(errbuf, "SIOCGIFFLAGS: %.*s: %s",
- (int) sizeof(ifr.ifr_name), ifr.ifr_name,
- strerror(errno));
- (void) close(fd);
- return (-1);
- }
- /*
- * Must be up
- */
- if ((ifr.ifr_flags & IFF_UP) == 0)
- continue;
- (void) strncpy(device, ifr.ifr_name, sizeof(ifr.ifr_name));
- device[sizeof(device) - 1] = '';
- #ifdef sun
- /*
- * Ignore sun virtual interfaces
- */
- if (strchr(device, ':') != NULL)
- continue;
- #endif
- if (ioctl(fd, SIOCGIFADDR, (char *) &ifr) < 0) {
- (void) sprintf(errbuf, "SIOCGIFADDR: %s: %s",
- device, strerror(errno));
- (void) close(fd);
- return (-1);
- }
- if (nipaddr >= MAX_IPADDR) {
- (void) sprintf(errbuf, "Too many interfaces (%d)", MAX_IPADDR);
- (void) close(fd);
- return (-1);
- }
- sin = (struct sockaddr_in *) &ifr.ifr_addr;
- al->addr = sin->sin_addr.s_addr;
- al->device = strdup(device);
- ++al;
- ++nipaddr;
- }
- (void) close(fd);
- *ipaddrp = ifaddrlist;
- return (nipaddr);
- }