참고문서는
http://www.cisco.com/en/US/tech/tk648/tk362/technologies_tech_note09186a0080094a9b.shtml

Avaya스위치에 실행을 해봤는데 적용이 된다.
[root@gamja root]# snmpwalk -v 1 -c tech 140.24.24.2 .1.3.6.1.2.1.17.4.3
SNMPv2-SMI::mib-2.17.4.3.1.1.0.0.12.249.75.72 = Hex-STRING: 00 00 0C F9 4B 48
SNMPv2-SMI::mib-2.17.4.3.1.1.0.0.240.137.133.73 = Hex-STRING: 00 00 F0 89 85 49
==> OID : .1.3.6.1.2.1.17.4.3.1은 CAM 테이블의 dynamic MAC address의 값들인것 같고…
OID : .1.3.6.1.2.1.17.4.3.2는 해당 MAC에 대한 인터페이스인것 같다…
SNMPv2-SMI::mib-2.17.4.3.1.2.0.0.12.249.75.72 = INTEGER: 13
SNMPv2-SMI::mib-2.17.4.3.1.2.0.0.240.137.133.73 = INTEGER: 3

스위치의 CAM 테이블 항목을 주기적으로 가져다가 DB에 정보를 저장하여 이용하는 방안을 모색중…

사용자 삽입 이미지

[스크립트 수정]

1. Avaya

- switch_info.inc : 스위치의 IP와 snmp community정보를 지정

- switch_mac.inc : 스위치와 라우터의 MAC address를 기록. 이것은 100Mbps의 업링크 포트를 찾기 위함

- make_cam_class.php : 스위치의 CAM테이블을 읽어와서 Gigabit업링크와 100Mbps업링크 포트의 정보만 제외하고 나머지를 DB에 저장하는 루틴

- get_port_number.php: avaya MIB의 port description은 모델마다 틀린경우가 존재하여 별도의 포트번호를 계산하는 루틴을 만듬

- cam2db.php : 메인 프로그램

2. Cisco

- switch_info.inc : 스위치의 IP와 snmp community(community@vlan-id)정보를 지정

- make_cam_class.php : 스위치의 CAM테이블을 읽어와서 DB에 저장하는 루틴

- cam2db.php : 메인 프로그램

3. search모듈

- find_cam.php : CLI상태에서 mac address로 스위치의 포트를 찾는 스크립트

- find_ip_cam.php : CLI상태에서 IP address로 노드의 MAC과 스위치의 포트를 찾는 스크립트

- search.php : 웹브라우저를 통하여 IP address로 노드의 MAC과 스위치의 포트를 찾는 스크립트

[2006년 4월7일 PHP코드작성 - 초판]

#!/usr/local/bin/php
# 작성자: 한상구(ssanggu@gmail.com)
# 작성일: 2006년 4월6일
# 작성목적: Layer2스위치의 Dynamic CAM Table의 내용을 5분주기로 SNMP get 하여 DB에
# 저장하여 향후 노드추적의 정보로 이용하고자 함..

$switch_ip = array(’14.248.2.2′);
$community_name = ‘xxxx’;

$db_host = “localhost”;
$db_user = “xxxx”;
$db_password = “xxxx”;
$db_name = “xxxx”;

$db_connect = mysql_connect($db_host, $db_user, $db_password) or die(”DB서버에 연결할 수 없습니다. ” . mysql_error());
mysql_select_db($db_name) or die(”데이터베이스를 선택할 수 없습니다.”);

foreach ($switch_ip as $s_ip) {
do_snmp($s_ip, $community_name);
}

function do_snmp ($host, $community)
{
# 스위치의 Dynamic CAM Table에 대한 OID
$cam_oid = ‘.1.3.6.1.2.1.17.4.3.1.1′;
# cam_oid를 이용하여 스위치의 CAM table을 읽어와 배열에 저장한다.
$cam = snmpwalk($host, $community, $cam_oid);

# 스위치의 CAM 항목에 대한 iFindex object instance정보를 가지고 있는 OID
$mac_port_oid = ‘.1.3.6.1.2.1.17.4.3.1.2′;
$mac_port = snmpwalk($host, $community, $mac_port_oid);

for($i=0; $i $m1 = trim(substr($cam[$i],12));
$m2 = preg_split(’/ /’,$m1);
# DB테이블을 MAC Vendor별로 테이블을 만들기 위하여 추출
# 향후에 검색과 테이블의 사이즈 증가를 예방하기 위함`
$vendor_mac = $m2[0].$m2[1].$m2[2];
$mac_address = join(’:',$m2);
#MIB-II에서 정의한 ifindex object에 대한 번호추출
$p_number = substr($mac_port[$i],9);
$ifindex = substr(snmpget($host, $community, “.1.3.6.1.2.1.17.1.4.1.2.$p_number”),9);
#uplink포트에서 Learning하는 CAM정보는 저장을 하면 안된다. 따라서 업링크 포트를
#찾기 위하여 포트의 bandwidth에서 100M가 넘는 포트를 업링크로 간주하여 제외한다.
$p_speed = substr(snmpget($host, $community, “.1.3.6.1.2.1.2.2.1.5.$ifindex”),9);

$port_desc = snmpget($host, $community, “.1.3.6.1.2.1.2.2.1.2.$ifindex”);
$port_desc_arr = preg_split(’/ /’, $port_desc);

#Port의 대역폭이 10M/100M인경우에만 DB작업에 들어간다.
if((trim($p_speed) == ‘10000000′) or (trim($p_speed) == ‘100000000′)) {

if(trim($port_desc_arr[1]) == ‘Avaya’) {
$port_number = $port_desc_arr[7];
$module_number = $port_desc_arr[10];
}

# DB테이블이 존재하는지를 검사하여 없는 경우에 테이블을 생성
$tbl_exists = mysql_query(”DESCRIBE `$vendor_mac`”);

if(!$tbl_exists) {
$create_table=mysql_query(”CREATE TABLE `$vendor_mac` (`mac` varchar(20) not null default ”, `s_ip` varchar(20) not null default ”, `module_no` smallint(2) not null default 0, `port_no` smallint(5) not null default 0, `first` timestamp not null default 0, `last` timestamp not null default 0, primary key (`mac`))”);
}

# MAC이 존재하면 UPDATE를 존재하지 않으면 INSERT
$m_exists = mysql_query(”SELECT * FROM `$vendor_mac` WHERE `mac` = ‘$mac_address’”);

if(!$m_exists) {
$insert_q=mysql_query(”INSERT INTO `$vendor_mac` VALUES (’$mac_address’,'$host’,$module_number,$port_number,NOW(),NOW())”);
} else {
$update_q=mysql_query(”UPDATE `$vendor_mac` SET `s_ip`=’$host’, `module_no`=$module_number, `port_no`=$port_number, `last`=NOW() WHERE `mac` = ‘$mac_address’”);
}

echo “\t$mac_address\t$module_number\t$port_number\n”;
}
}
}

mysql_close($db_connect);
?>

[Mac address조회 루틴]

#!/usr/local/bin/php
# 작성자: 한상구(ssanggu@gmail.com)
# 작성일: 2006년 4월7일
# 작성목적: DB에 저장된 CAM정보에서 입력받은 MAC에 대한 정보를 찾아서 출력

$db_connect = mysql_connect($db_host, $db_user, $db_password) or die(”DB서버에 연결할 수 없>
습니다. ” . mysql_error());
mysql_select_db($db_name) or die(”데이터베이스를 선택할 수 없습니다.”);

if($argc == 2) {
if(preg_match(”/^\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2}$/”,trim($argv[1]))) {
$mac_address = strtoupper(trim($argv[1]));

$mac_arr = preg_split(’/:/’,$mac_address);
$table_name = $mac_arr[0].$mac_arr[1].$mac_arr[2];

$find_query = mysql_query(”SELECT * FROM `$table_name` WHERE `mac` = ‘$mac_address’”);
if($find_query) {
while($row = mysql_fetch_assoc($find_query)) {
echo “MAC address:\t\t”.$row[”mac”].”\n”;
echo “스위치 IP address:\t”.$row[”s_ip”].”\n”;
echo “Stack Module No:\t”.$row[”module_no”].”\n”;
echo “처음감지일자:\t\t”.$row[”first”].”\n”;
echo “마지막감지일자:\t\t”.$row[”last”].”\n”;
}
} else {
die(”데이터베이스에서 입력한 MAC address가 발견되지 않았습니다.\n”);
}
} else {
die(”입력된 MAC address의 형식이 틀립니다.\n”);
}
} else {
die(”사용법: ./find_cam.php Mac-address(예: ./find_cam.php 00:00:F0:EF:AA:BB)\n”);
}

mysql_close($db_connect);
?>

[2006년 4월10일]

기존의 스크립트에서는 포트번호와 모듈번호를 찾기 위하여 port description에서 정보를 추출했는데 이 정보가 스위치의 버전에 따라서 저장되는 내용이 다른 문제때문에 MySQL 쿼리문이 제대로 작성이 안되는 문제점이 발생하였다. 따라서, 포트번호와 모듈번호 추출을 위한 다른 방식으로 스크립트를 조정함..


# 작성자: 한상구(ssanggu@gmail.com)
# 작성일: 2006년 4월6일
# 작성목적: Layer2스위치의 Dynamic CAM Table의 내용을 5분주기로 SNMP get 하여 DB에
# 저장하여 향후 노드추적의 정보로 이용하고자 함..

$switch_ip = array(’143.248.240.2′);
$community_name = ‘public’;

$db_connect = mysql_connect($db_host, $db_user, $db_password) or die(”DB서버에 연결할 수 없습니다. ” . mysql_error());
mysql_select_db($db_name) or die(”데이터베이스를 선택할 수 없습니다.”);

foreach ($switch_ip as $s_ip) {
do_snmp($s_ip, $community_name);
}

function do_snmp ($host, $community)
{
# 스위치의 Dynamic CAM Table에 대한 OID
$cam_oid = ‘.1.3.6.1.2.1.17.4.3.1.1′;
# cam_oid를 이용하여 스위치의 CAM table을 읽어와 배열에 저장한다.
$cam = snmpwalk($host, $community, $cam_oid);

# 스위치의 CAM 항목에 대한 iFindex object instance정보를 가지고 있는 OID
$mac_port_oid = ‘.1.3.6.1.2.1.17.4.3.1.2′;
$mac_port = snmpwalk($host, $community, $mac_port_oid);

$if_list = snmpwalk($host, $community, ‘.1.3.6.1.2.1.16.1.1.1.1′);

$tag = 0;
$d_tag = 0;
$port_number = 1;

for($i = 1; $i

$port_index = substr($if_list[$i],9);
$module_number = (int)((int)($port_index) / 1000);
$p_module_number = (int)((int)(substr($if_list[$i-1],9)) / 1000);

$d_tag = $module_number - $p_module_number;

$p_speed = substr(snmpget($host, $community, “.1.3.6.1.2.1.2.2.1.5.$port_index”),9);

if((trim($p_speed) == ‘10000000′) or (trim($p_speed) == ‘100000000′)) {
if($tag > 0) {
$tag = 0;
$port_number = 1;

$module_arr[”$port_index”] = $module_number;
$port_arr[”$port_index”] = $port_number;
$port_number++;
} else {
if($d_tag != 0) {
$port_number = 1;

$module_arr[”$port_index”] = $module_number;
$port_arr[”$port_index”] = $port_number;
$port_number++;
$d_tag = 0;
} else {
$module_arr[”$port_index”] = $module_number;
$port_arr[”$port_index”] = $port_number;
$port_number++;
}
}
} else {
$tag++;
}
}

for($i=0; $i
$m1 = trim(substr($cam[$i],12));
$m2 = preg_split(’/ /’,$m1);
# DB테이블을 MAC Vendor별로 테이블을 만들기 위하여 추출
# 향후에 검색과 테이블의 사이즈 증가를 예방하기 위함`
$vendor_mac = $m2[0].$m2[1].$m2[2];
$mac_address = join(’:',$m2);
#MIB-II에서 정의한 ifindex object에 대한 번호추출
$p_number = substr($mac_port[$i],9);
$ifindex = substr(snmpget($host, $community, “.1.3.6.1.2.1.17.1.4.1.2.$p_number”),9);
#uplink포트에서 Learning하는 CAM정보는 저장을 하면 안된다. 따라서 업링크 포트를
#찾기 위하여 포트의 bandwidth에서 100M가 넘는 포트를 업링크로 간주하여 제외한다.
$p_speed = substr(snmpget($host, $community, “.1.3.6.1.2.1.2.2.1.5.$ifindex”),9);

#Port의 대역폭이 10M/100M인경우에만 DB작업에 들어간다.
if((trim($p_speed) == ‘10000000′) or (trim($p_speed) == ‘100000000′)) {

$port_number = $port_arr[”$ifindex”];
$module_number = $module_arr[”$ifindex”];

# DB테이블이 존재하는지를 검사하여 없는 경우에 테이블을 생성
$tbl_exists = mysql_query(”DESCRIBE `$vendor_mac`”);

if(!$tbl_exists) {
$create_table=mysql_query(”CREATE TABLE `$vendor_mac` (`mac` varchar(20) not null default ”, `s_ip` varchar(20) not null default ”, `module_no` smallint(2) not null default 0, `port_no` smallint(5) not null default 0, `first` datetime , `last` datetime , primary key (`mac`))”);
}

# MAC이 존재하면 UPDATE를 존재하지 않으면 INSERT
$m_exists = mysql_query(”SELECT * FROM `$vendor_mac` WHERE `mac` = ‘$mac_address’”);

if(mysql_num_rows($m_exists) == 0) {
$insert_q=mysql_query(”INSERT INTO `$vendor_mac` VALUES (’$mac_address’,'$host’,$module_number,$port_number,NOW(),NOW())”);
} else {
$update_q=mysql_query(”UPDATE `$vendor_mac` SET `s_ip`=’$host’, `module_no`=$module_number, `port_no`=$port_number, `last`=NOW() WHERE `mac` = ‘$mac_address’”);
}

echo “\t$mac_address\t$module_number\t$port_number\n”;
}
}
}

mysql_close($db_connect);
?>

Posted by salgunamu
: