네트워크 시스템관리를 하거나 네트워크 시스템 어플리케이션을 작성하다 보면

네트워크 패킷을 훔쳐 보아야 하는 경우가 있습니다. 

이때 tcpdump 또는  Wireshark 을 사용하는데 

경우에 따라서 특정 처리가 필요하여 자체적인 패킷 덤프 라이브러리가 필요합니다.

이때 쓰는 것이 pcap 라이브러리 입니다. 

이것을 node.js 에 사용하고 싶을 때는 

pcap 모듈을 사용하면 됩니다.

오늘은 node.js 용 pcap 모듈에 대해서 설명하겠습니다 

pcap 라이브러리에 대해서는 여기서 자세하게 다루지 않을 겁니다. 

워낙 유명한 라이브러리라서 인터넷 검색을 하시는 것이 빠릅니다. 

node.js 에서 사용하는 pcap 모듈은 pcap 라이브러리를 모듈형태로 

사용하도록 한 것이기 때문에 

시스템에는 pcap 라이브러리가 설치되어 있어야 합니다.

만약 시스템에 설치가 되어 있지 않았다면 

우분투에서는 다음과 같이 설치 하시면 됩니다.

sudo apt-get install libpcap-dev

이제 설치를 마치셨다면 pcap 모듈을 설치하면 되는데 다음과 같이 하시면 됩니다. 

npm install pcap
이 모듈에는 cpp 소스 형식이 숨어 있기 때문에 설치 과정에 빌드 과정이 있음을 주의 하셔야 합니다.

특별한 경우가 아니면 잘 될 겁니다. 

자 이제 간단한 소스를 보면서 사용법을 알아 보죠..

[C020_pcap_simple.js]------------------------------------------------------

var pcap = require('pcap');

console.log( pcap.lib_version);

var pcap_session = pcap.createSession( 'eth0' );

pcap_session.on('packet', function (raw_packet) {
console.log( raw_packet );
});
-----------------------------------------------------------------------------------
이 소스는 eth0 이더넷 장치에 들어오고 나가는 로우 패킷들을 모두 보여 주는 겁니다. 

정말 간단하죠?

실제로 동작 시키기 위해서는 다음과 같이 합니다. 

$ sudo node pcap_simple.js
sudo 를 주는 이유는 패킷 캡쳐는 root 권한에 속하기 때문입니다. 

다음과 같이 무지막지 한 패킷들이 나오는데 이유는 제가 텔넷으로 접근했기 때문에 

패킷 출력 결과가 다시 패킷 캡쳐 데이터가 되는 되돌이 현상 때문입니다. 

$ sudo node pcap_simple.js
libpcap version 1.1.1
<Buffer 01 00 5e 7f ff fa 00 0e 0c dd c4 e2 08 00 45 00 01 47 00 00 40 00 04 11 ba e4 c0 a8 0a 1f ef ff ff fa a8 0d 07 6c 01 33 48 7f 4e 4f 54 49 46 59 20 2a 20 ...>
<Buffer 01 00 5e 7f ff fa 00 0e 0c dd c4 e2 08 00 45 00 01 47 00 01 40 00 04 11 ba e3 c0 a8 0a 1f ef ff ff fa a8 0d 07 6c 01 33 48 7f 4e 4f 54 49 46 59 20 2a 20 ...>
<Buffer b8 88 e3 89 f7 6e e8 03 9a 1d f3 ff 08 00 45 00 00 28 51 d3 40 00 80 06 1d 4e c0 a8 00 21 c0 a8 0a 3d eb ee 00 16 6d a5 dc 58 fb 79 ca 89 50 10 3f 79 e8 ...>
<Buffer b8 88 e3 89 f7 6e e8 03 9a 1d f3 ff 08 00 45 00 00 28 51 d4 40 00 80 06 1d 4d c0 a8 00 21 c0 a8 0a 3d e9 85 01 bd be 7b a2 8c 1c 2e 0c ea 50 10 3f b2 6f ...>
<Buffer 01 00 5e 7f ff fa 00 0e 0c dd c4 e2 08 00 45 00 01 48 00 02 40 00 04 11 ba e1 c0 a8 0a 1f ef ff ff fa a8 0d 07 6c 01 34 7e 80 4e 4f 54 49 46 59 20 2a 20 ...>
<Buffer 01 00 5e 7f ff fa 00 0e 0c dd c4 e2 08 00 45 00 01 48 00 03 40 00 04 11 ba e0 c0 a8 0a 1f ef ff ff fa a8 0d 07 6c 01 34 7e 80 4e 4f 54 49 46 59 20 2a 20 ...>
             :
:
 
pcap 라이브러리는 이런 기본적인 로우 패킷 획득 뿐만 아니라 분석해서 해석해주는 기능도 엄청나게 가지고 있습니다. 

이번에는 이 로우 패킷을 분석한 데이터를 뿌려 주는 예제를 보죠..

[C021_pcap_anal.js]------------------------------------------------------
var pcap = require('pcap');
var pcap_session = pcap.createSession( 'eth0' );

pcap_session.on('packet', function (raw_packet) {

var packet = pcap.decode.packet(raw_packet);
console.log(pcap.print.packet(packet));
});

-----------------------------------------------------------------------------------

수신된 로우 패킷을 해석하는 것이 
pcap.decode.packet() 
함수 입니다. 
이제 실행해 봅시다.

$ sudo node pcap_anal.js
b8:88:e3:89:f7:6e -> e8:03:9a:1d:f3:ff 192.168.10.61:22 -> 192.168.0.33:60398 TCP len 188 [ack,psh]
b8:88:e3:89:f7:6e -> e8:03:9a:1d:f3:ff 192.168.10.61:22 -> 192.168.0.33:60398 TCP len 188 [ack,psh]
b8:88:e3:89:f7:6e -> e8:03:9a:1d:f3:ff 192.168.10.61:22 -> 192.168.0.33:60398 TCP len 188 [ack,psh]
b8:88:e3:89:f7:6e -> e8:03:9a:1d:f3:ff 192.168.10.61:22 -> 192.168.0.33:60398 TCP len 188 [ack,psh]
e8:03:9a:1d:f3:ff -> b8:88:e3:89:f7:6e 192.168.0.33:60398 -> 192.168.10.61:22 TCP len 40 [ack]
e8:03:9a:1d:f3:ff -> b8:88:e3:89:f7:6e 192.168.0.33:60398 -> 192.168.10.61:22 TCP len 40 [ack]
e8:03:9a:1d:f3:ff -> b8:88:e3:89:f7:6e 192.168.0.33:60398 -> 192.168.10.61:22 TCP len 40 [ack]
b8:88:e3:89:f7:6e -> e8:03:9a:1d:f3:ff 192.168.10.61:22 -> 192.168.0.33:60398 TCP len 1500 [ack]
b8:88:e3:89:f7:6e -> e8:03:9a:1d:f3:ff 192.168.10.61:22 -> 192.168.0.33:60398 TCP len 1500 [ack]
b8:88:e3:89:f7:6e -> e8:03:9a:1d:f3:ff 192.168.10.61:22 -> 192.168.0.33:60398 TCP len 1268 [ack,psh]
b8:88:e3:89:f7:6e -> e8:03:9a:1d:f3:ff 192.168.10.61:22 -> 192.168.0.33:60398 TCP len 1500 [ack]
b8:88:e3:89:f7:6e -> e8:03:9a:1d:f3:ff 192.168.10.61:22 -> 192.168.0.33:60398 TCP len 1288 [ack,psh]
 
어디서 많이 보던 것과 비슷하다고 하시는 분이 있을 겁니다. ^^

자.. 마지막으로 시스템에 존재하는 장치명과 IP 를 얻는 것을 해 보죠.

다음이 예제 소스 입니다. 

[C022_pcap_all_device.js]------------------------------------------------------
var pcap = require('pcap');

var pcap_session = pcap.createSession( 'eth0' );
var all_devs = pcap_session.findalldevs();

console.log( all_devs ); 
console.log( '------------------------------------------------' ); 
all_devs.forEach(function (dev) {
if (dev.addresses.length > 0) {
dev.addresses.forEach(function (address) {
if( address.addr.indexOf(':') === -1 ) { 
console.log( dev.name , address.addr, address.netmask );
}
});
}
});

-----------------------------------------------------------------------------------
        
IPv4 주소의 장치 목록만 얻도록 
if( address.addr.indexOf(':') === -1 ) { 
}
으로 걸러내고 있습니다. 

나머지는 대충 보시면 감이 오실 것으로 믿습니다. 
그정도 실력은...  ^^;

위 소스를 실행한 결과 입니다. 

$ sudo node pcap_all_device.js
[sudo] password for frog:
[ { name: 'eth0',
addresses:
[ ,
  [Object],
  [Object],
  [Object],
  [Object],
  [Object],
  [Object],
  [Object] ] },
 { name: 'wlan0', addresses: [] },
 { name: 'any',
description: 'Pseudo-device that captures on all interfaces',
addresses: [] },
 { name: 'lo',
addresses: [ , [Object], [Object] ],
flags: 'PCAP_IF_LOOPBACK' } ]
eth0 192.168.10.61 255.255.0.0
lo 127.0.0.1 255.0.0.0
^Cfrog@frog-Lenovo-IdeaPad-Y580:~/jot$ sudo node pcap_all_device.js
[ { name: 'eth0',
addresses:
[ ,
  [Object],
  [Object],
  [Object],
  [Object],
  [Object],
  [Object],
  [Object] ] },
 { name: 'wlan0', addresses: [] },
 { name: 'any',
description: 'Pseudo-device that captures on all interfaces',
addresses: [] },
 { name: 'lo',
addresses: [ , [Object], [Object] ],
flags: 'PCAP_IF_LOOPBACK' } ]
------------------------------------------------
eth0 192.168.10.61 255.255.0.0
lo 127.0.0.1 255.0.0.0

쉽죠?