[질문] libpcap을 이용한 패킷캡쳐중 인터페이스가 다운될경우 문제

ecstasy5001의 이미지

libpcap을 이용해서 패킷을 캡쳐하는 프로그램을 만들고 있는데

물리적인 인터페이스나 논리적인 인터페이스(ipsec0 같은)가 다운될경우

프로그램이 종료되게 할라고 하는데 이게 잘 안됩니다.

pcap_open_live 함수를 이용해서 타임아웃을 지정하고

pcap_loop, pcap_detatch, pcap_next 등 여러가지 함수를 사용해봤지만

모든함수 전부다 인터페이스가 다운되면 타임아웃이 무시된채 무한 대기상태가 되었습니다.

인터페이스가 다운되었을때 이것을 확인할수 있는방법이 있는지 궁금합니다.

monovision의 이미지

아래는 제가 예전에 브릿지 방화벽에 사용하려고 만든 테스트용 소스입니다.
아래의 소스는 상단 백본 스위치나 하단 백본 스위치의 오류로 인해 스위치쪽 포트의 링크가 다운이 되었을 경우 방화벽에서 bypass 를 하기 위해 작성했었습니다.
브릿지 방화벽이 스위치 사이에 들어가니 상단이나 하단 스위치 하나가 죽었음에도 불구하고 계속 트래픽이 흘러 트래픽이 유실이 되더라구요 ㅡ.ㅡ;;;

단순하게 NIC 의 LINK 상태만 감지하여 출력해 주는 프로그램인데 요걸 응용하면 아마 원하시는 기능을 간단하게 나마 만드실 수 있을거라 봅니다.

저도 ethtool 이나 mii-tool 을 보고 만든거라 허접합니다.
더 깊게 보고 싶으시면 ethtool 이나 mii-tool 소스를 보시는게 나을 겁니다.
그리고.. 물리적인 eth2(in), eth3(out) 를 브릿지로 묶은 br0 도 측정이 되었으니 아마 논리 인터페이스도 제대로 검출하지 않을까 합니다.
단, 아래의 코드는 물리적인 인터페이스가 죽으면 해당 인터페이스는 인식을 하지 못합니다.
즉, "ip link show" 나 ethtool 로 보았을때 물리적 인터페이스가 인식은 되었지만, ifconfig 에 나타나지 않는 경우에는 정상적으로 출력을 하지 않습니다.
제가 테스트한 모든 리눅스 서버에서는 정상적으로 되었었는데 글쎄요.. 안될지도 모르겠네요.

커널단이나 iptables 단에서는 패킷 캡쳐를 해봤는데.. libpcap 은 써보질 않아서 약간 엉뚱한 쪽으로 답변을 달게 되네요.
도움이 되었으면 좋겠습니다.

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <linux/sockios.h>
 
#define ETHTOOL_GLINK                   0x0000000a
 
typedef __uint32_t __u32;
 
struct ethtool_value
{
  __u32 cmd;
  __u32 data;
};
 
int
main (int argc, char **argv)
{
  // 이더넷 데이터 구조체
  struct ifreq *ifr;
  struct sockaddr_in *sin;
  struct sockaddr *sa;
 
  // 이더넷 설정 구조체
  struct ifconf ifcfg;
  struct ethtool_value edata;
 
  int fd;
  int n;
  int numreqs = 30;
  fd = socket (AF_INET, SOCK_DGRAM, 0);
  int link;
 
 
  memset (&ifcfg, 0, sizeof (ifcfg));
  ifcfg.ifc_buf = NULL;
  ifcfg.ifc_len = sizeof (struct ifreq) * numreqs;
  ifcfg.ifc_buf = malloc (ifcfg.ifc_len);
 
  for (;;)
    {
      ifcfg.ifc_len = sizeof (struct ifreq) * numreqs;
      ifcfg.ifc_buf = realloc (ifcfg.ifc_buf, ifcfg.ifc_len);
      if (ioctl (fd, SIOCGIFCONF, (char *) &ifcfg) < 0)
        {
          perror ("SIOCGIFCONF ");
          exit;
        }
      break;
    }
 
  // 네트워크 장치의 정보를 얻어온다.
  ifr = ifcfg.ifc_req;
  for (n = 0; n < ifcfg.ifc_len; n += sizeof (struct ifreq))
    {
      // 주소값을 출력하고 링크 상태 확인
      sin = (struct sockaddr_in *) &ifr->ifr_addr;
      printf ("[%s]\n", ifr->ifr_name);
      printf ("IP    %s\n", inet_ntoa (sin->sin_addr));
 
      edata.cmd = ETHTOOL_GLINK;
      ifr->ifr_data = (caddr_t) & edata;
      link = ioctl (fd, SIOCETHTOOL, (char *) ifr);
      printf ("Link : %s\n\n", edata.data ? "connected" : "not connect");
 
      ifr++;
    }
}

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.