📄 at.c
字号:
at [i].at_enaddr[2] = zg; at [i].at_enaddr[3] = zh; at [i].at_enaddr[4] = zi; at [i].at_enaddr[5] = zj; tmp_a = ((u_long)za << 24) | ((u_long)zb << 16) | ((u_long)zc << 8) | ((u_long)zd ) ; at [i].at_iaddr.s_addr = htonl(tmp_a); at [i].if_index = Interface_Index_By_Name(ifname, strlen(ifname)); } fclose (in);#endif /* linux */#else /* CAN_USE_SYSCTL */ int mib[6]; size_t needed; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = AF_INET; mib[4] = NET_RT_FLAGS; mib[5] = RTF_LLINFO; if (at) free(at); if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) snmp_log_perror("route-sysctl-estimate"); if ((at = malloc(needed ? needed : 1)) == NULL) snmp_log_perror("malloc"); if (sysctl(mib, 6, at, &needed, NULL, 0) < 0) snmp_log_perror("actual retrieval of routing table"); lim = at + needed; rtnext = at;#endif /* CAN_USE_SYSCTL */}#ifdef ARP_SCAN_FOUR_ARGUMENTSstatic int ARP_Scan_Next(u_long *IPAddr, char *PhysAddr, u_long *ifType, u_short *ifIndex)#elsestatic int ARP_Scan_Next(u_long *IPAddr, char *PhysAddr, u_long *ifType)#endif{#ifndef CAN_USE_SYSCTL#ifdef linux if (arptab_current<arptab_size) { /* copy values */ *IPAddr= at[arptab_current].at_iaddr.s_addr; *ifType= (at[arptab_current].at_flags & ATF_PERM) ? 4/*static*/ : 3/*dynamic*/ ; *ifIndex = at[arptab_current].if_index; memcpy( PhysAddr, &at[arptab_current].at_enaddr, sizeof(at[arptab_current].at_enaddr) ); /* increment to point next entry */ arptab_current++; /* return success */ return( 1 ); }#endif /* linux */ return 0; /* we need someone with an irix box to fix this section */#else#if !defined(ARP_SCAN_FOUR_ARGUMENTS) || defined(hpux) register struct arptab *atab; while (arptab_current < arptab_size) {#ifdef STRUCT_ARPHD_HAS_AT_NEXT /* The arp table is an array of linked lists of arptab entries. Unused slots have pointers back to the array entry itself */ if ( at_ptr == (auto_nlist_value(ARPTAB_SYMBOL) + arptab_current*sizeof(struct arphd))) { /* Usused */ arptab_current++; at_ptr = at[arptab_current].at_next; continue; } klookup( at_ptr, (char *)&at_entry, sizeof(struct arptab)); klookup( at_entry.at_ac, (char *)&at_com, sizeof(struct arpcom)); at_ptr = at_entry.at_next; atab = &at_entry; *ifIndex = at_com.ac_if.if_index; /* not strictly ARPHD */#else /* STRUCT_ARPHD_HAS_AT_NEXT */ atab = &at[arptab_current++];#endif /* STRUCT_ARPHD_HAS_AT_NEXT */ if (!(atab->at_flags & ATF_COM)) continue; *ifType = (atab->at_flags & ATF_PERM) ? 4 : 3 ; *IPAddr = atab->at_iaddr.s_addr;#if defined (sunV3) || defined(sparc) || defined(hpux) memcpy( PhysAddr,(char *) &atab->at_enaddr, sizeof(atab->at_enaddr));#endif#if defined(mips) || defined(ibm032) memcpy( PhysAddr,(char *) atab->at_enaddr, sizeof(atab->at_enaddr));#endif return(1); }#else /* !defined(ARP_SCAN_FOUR_ARGUMENTS) || defined(hpux) */ struct rt_msghdr *rtm; struct sockaddr_inarp *sin; struct sockaddr_dl *sdl; while (rtnext < lim) { rtm = (struct rt_msghdr *)rtnext; sin = (struct sockaddr_inarp *)(rtm + 1); sdl = (struct sockaddr_dl *)(sin + 1); rtnext += rtm->rtm_msglen; if (sdl->sdl_alen) { *IPAddr = sin->sin_addr.s_addr; memcpy( PhysAddr,(char *) LLADDR(sdl), sdl->sdl_alen); *ifIndex = sdl->sdl_index; *ifType = 1; /* XXX */ return(1); } }#endif /* !defined(ARP_SCAN_FOUR_ARGUMENTS) || defined(hpux) */ return(0); /* "EOF" */#endif /* !CAN_USE_SYSCTL */}#endif /* solaris2 */#else /* WIN32 */#include <iphlpapi.h>extern WriteMethod write_arp;MIB_IPNETROW *arp_row = NULL;int create_flag = 0;u_char *var_atEntry(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ /* * Address Translation table object identifier is of form: * 1.3.6.1.2.1.3.1.?.interface.1.A.B.C.D, where A.B.C.D is IP address. * Interface is at offset 10, * IPADDR starts at offset 12. * * IP Net to Media table object identifier is of form: * 1.3.6.1.2.1.4.22.1.?.interface.A.B.C.D, where A.B.C.D is IP address. * Interface is at offset 10, * IPADDR starts at offset 11. */ u_char *cp; oid *op; oid lowest[16]; oid current[16]; int oid_length; int lowState = -1; /* Don't have one yet */ PMIB_IPNETTABLE pIpNetTable = NULL; DWORD status = NO_ERROR; DWORD dwActualSize = 0; UINT i; u_char dest_addr[4]; /* fill in object part of name for current (less sizeof instance part) */ memcpy((char *)current, (char *)vp->name, (int)vp->namelen * sizeof(oid)); if (current[6] == 3 ) { /* AT group oid */ oid_length = 16; } else { /* IP NetToMedia group oid */ oid_length = 15; } status = GetIpNetTable(pIpNetTable, &dwActualSize, TRUE); if (status == ERROR_INSUFFICIENT_BUFFER) { pIpNetTable = (PMIB_IPNETTABLE) malloc(dwActualSize); if(pIpNetTable != NULL){ /* Get the sorted IpNet Table */ status = GetIpNetTable(pIpNetTable, &dwActualSize, TRUE); } } if(status == NO_ERROR) { for (i = 0; i < pIpNetTable->dwNumEntries; ++i) { current[10] = pIpNetTable->table[i].dwIndex; if (current[6] == 3 ) { /* AT group oid */ current[11] = 1; op = current + 12; } else { /* IP NetToMedia group oid */ op = current + 11; } cp = (u_char *)&pIpNetTable->table[i].dwAddr; *op++ = *cp++; *op++ = *cp++; *op++ = *cp++; *op++ = *cp++; if (exact){ if (snmp_oid_compare(current, oid_length, name, *length) == 0){ memcpy( (char *)lowest,(char *)current, oid_length * sizeof(oid)); lowState = 0; break; /* no need to search further */ } } else { if (snmp_oid_compare(current, oid_length, name, *length) > 0){ memcpy( (char *)lowest,(char *)current, oid_length * sizeof(oid)); lowState = 0; break; /* As the table is sorted, no need to search further */ } } } } if(arp_row == NULL){ /* Free allocated memory in case of SET request's FREE phase */ arp_row = (PMIB_IPNETROW)malloc(sizeof(MIB_IPNETROW)); } if (lowState < 0 || status != NO_ERROR){ /* for creation of new row, only ipNetToMediaTable case is considered */ if(*length == 15 || *length == 16){ create_flag = 1; *write_method = write_arp; arp_row->dwIndex = name[10]; if(*length == 15)/* ipNetToMediaTable */ { i = 11; }else /* at Table */ { i = 12; } dest_addr[0] = (u_char)name[i]; dest_addr[1] = (u_char)name[i+1]; dest_addr[2] = (u_char)name[i+2]; dest_addr[3] = (u_char) name[i+3]; arp_row->dwAddr = *((DWORD *)dest_addr); arp_row->dwType = 4; /* Static */ arp_row->dwPhysAddrLen = 0; } free(pIpNetTable); return(NULL); } create_flag = 0; memcpy((char *)name,(char *)lowest, oid_length * sizeof(oid)); *length = oid_length; *write_method = write_arp; *arp_row = pIpNetTable->table[i]; switch(vp->magic){ case IPMEDIAIFINDEX: /* also ATIFINDEX */ *var_len = sizeof long_return; long_return = pIpNetTable->table[i].dwIndex; free(pIpNetTable); return (u_char *)&long_return; case IPMEDIAPHYSADDRESS: /* also ATPHYSADDRESS */ *var_len = pIpNetTable->table[i].dwPhysAddrLen; memcpy(return_buf, pIpNetTable->table[i].bPhysAddr, *var_len); free(pIpNetTable); return (u_char *)return_buf; case IPMEDIANETADDRESS: /* also ATNETADDRESS */ *var_len = sizeof long_return; long_return = pIpNetTable->table[i].dwAddr; free(pIpNetTable); return (u_char *)&long_return; case IPMEDIATYPE: *var_len = sizeof long_return; long_return = pIpNetTable->table[i].dwType; free(pIpNetTable); return (u_char *)&long_return; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_atEntry\n", vp->magic)); } return NULL;}intwrite_arp( int action, u_char *var_val, u_char var_val_type, size_t var_val_len, u_char *statP, oid *name, size_t length){ int var, retval = SNMP_ERR_NOERROR ; static PMIB_IPNETROW oldarp_row = NULL; MIB_IPNETROW temp_row; DWORD status = NO_ERROR; /* * IP Net to Media table object identifier is of form: * 1.3.6.1.2.1.4.22.1.?.interface.A.B.C.D, where A.B.C.D is IP address. * Interface is at offset 10, * IPADDR starts at offset 11. */ if (name[6] == 3 ) { /* AT group oid */ if (length != 16) { snmp_log(LOG_ERR, "length error\n"); return SNMP_ERR_NOCREATION; } } else { /* IP NetToMedia group oid */ if (length != 15) { snmp_log(LOG_ERR, "length error\n"); return SNMP_ERR_NOCREATION; } } /* #define for ipNetToMediaTable entries are 1 less than corresponding sub-id in MIB * i.e. IPMEDIAIFINDEX defined as 0, but ipNetToMediaIfIndex registered as 1 */ var = name[9] - 1; switch(action) { case RESERVE1: switch(var){ case IPMEDIAIFINDEX: if (var_val_type != ASN_INTEGER){ snmp_log(LOG_ERR, "not integer\n"); return SNMP_ERR_WRONGTYPE; } if((*((int *)var_val)) < 0 ){ snmp_log(LOG_ERR, "invalid media ifIndex"); return SNMP_ERR_WRONGVALUE; } if (var_val_len > sizeof(int)){ snmp_log(LOG_ERR, "bad length\n"); return SNMP_ERR_WRONGLENGTH; } break; case IPMEDIANETADDRESS: if (var_val_type != ASN_IPADDRESS){ snmp_log(LOG_ERR, "not IP Address\n"); return SNMP_ERR_WRONGTYPE; } if((*((int *)var_val)) < 0 ){ snmp_log(LOG_ERR, "invalid media net address"); return SNMP_ERR_WRONGVALUE; } if (var_val_len > sizeof(DWORD)){ snmp_log(LOG_ERR, "bad length\n"); return SNMP_ERR_WRONGLENGTH; } break; case IPMEDIATYPE: if (var_val_type != ASN_INTEGER){ snmp_log(LOG_ERR, "not integer\n"); return SNMP_ERR_WRONGTYPE; } if((*((int *)var_val)) < 1 || (*((int *)var_val)) > 4 ){ snmp_log(LOG_ERR, "invalid media type"); return SNMP_ERR_WRONGVALUE; } if (var_val_len > sizeof(int)){ snmp_log(LOG_ERR, "bad length\n"); return SNMP_ERR_WRONGLENGTH; } break; case IPMEDIAPHYSADDRESS: if (var_val_type != ASN_OCTET_STR) { snmp_log(LOG_ERR, "not octet str"); return SNMP_ERR_WRONGTYPE; } if (var_val_len != 6) { snmp_log(LOG_ERR, "not correct ipAddress length: %d", var_val_len); return SNMP_ERR_WRONGLENGTH; } break; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in write_rte\n", var+1)); return SNMP_ERR_NOTWRITABLE; } break; case RESERVE2: /* Save the old value, in case of UNDO */ if(oldarp_row == NULL){ oldarp_row = (PMIB_IPNETROW) malloc(sizeof(MIB_IPNETROW)); *oldarp_row = *arp_row; } break; case ACTION: /* Perform the SET action (if reversible) */ switch(var){ case IPMEDIAIFINDEX: temp_row = *arp_row; arp_row->dwIndex = *((int *)var_val) ; /* In case of new entry, physical address is mandatory. * SetIpNetEntry will be done in COMMIT case */ if(!create_flag){ if(SetIpNetEntry(arp_row) != NO_ERROR){ arp_row->dwIndex = temp_row.dwIndex; retval = SNMP_ERR_COMMITFAILED; } //Don't know yet, whether change in ifIndex creates new row or not //else{ //temp_row.dwType = 2; //if(SetIpNetEntry(&temp_row) != NO_ERROR) //retval = SNMP_ERR_COMMITFAILED; //} } break; case IPMEDIANETADDRESS: temp_row = *arp_row; arp_row->dwAddr = *((int *)var_val); if(!create_flag){ if(SetIpNetEntry(arp_row) != NO_ERROR){ arp_row->dwAddr = oldarp_row->dwAddr; retval = SNMP_ERR_COMMITFAILED; }else{ temp_row.dwType = 2; if(SetIpNetEntry(&temp_row) != NO_ERROR){ snmp_log(LOG_ERR, "Failed in ACTION, while deleting old row \n"); retval = SNMP_ERR_COMMITFAILED; } } } break; case IPMEDIATYPE: arp_row->dwType = *((int *)var_val); if(!create_flag){ if(SetIpNetEntry(arp_row) != NO_ERROR) retval = SNMP_ERR_COMMITFAILED; } break; case IPMEDIAPHYSADDRESS: memcpy(arp_row->bPhysAddr, var_val, var_val_len); arp_row->dwPhysAddrLen = var_val_len; if(!create_flag){ if(SetIpNetEntry(arp_row) != NO_ERROR) retval = SNMP_ERR_COMMITFAILED; } break; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in write_arp\n", var+1)); retval = SNMP_ERR_NOTWRITABLE; } return retval; case UNDO : /* Reverse the SET action and free resources */ if(oldarp_row != NULL){ //UNDO the changes done for existing entry. if(!create_flag){ if((status = SetIpNetEntry(oldarp_row)) != NO_ERROR){ snmp_log(LOG_ERR, "Error in case UNDO, status : %d\n", status); retval = SNMP_ERR_UNDOFAILED; } } if(oldarp_row->dwAddr != arp_row->dwAddr){ arp_row->dwType = 2; //If row was added/created delete that row if((status = SetIpNetEntry(arp_row)) != NO_ERROR){ snmp_log(LOG_ERR, "Error while deleting added row, status : %d\n", status); retval = SNMP_ERR_UNDOFAILED; } } free(oldarp_row); oldarp_row = NULL; free(arp_row); arp_row = NULL; return retval; } break; case COMMIT: /* if new entry and physical address specified, create new entry */ if(create_flag) { if(arp_row->dwPhysAddrLen != 0){ if((status =CreateIpNetEntry(arp_row) )!= NO_ERROR){ snmp_log(LOG_ERR, "Inside COMMIT: CreateIpNetEntry failed, status %d\n", status); retval = SNMP_ERR_COMMITFAILED; } }else{ /*For new entry, physical address must be set. */ snmp_log(LOG_ERR, "Can't create new entry without physical address\n"); retval = SNMP_ERR_WRONGVALUE; } /* unset the create_flag, so that CreateIpNetEntry called only once */ create_flag = 0; } case FREE: /* Free any resources allocated */ free(oldarp_row); oldarp_row = NULL; free(arp_row); arp_row = NULL; break; } return retval;}#endif /* WIN32 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -