pcap 라이브러리에서 MAC어드레스 얻는 방법 알려주세요

gate21의 이미지

pcap 라이브러리 써서

포트스캐너를 만드려고 하는데요 pcap라이브러리에서 처음에 디바이스 얻은다음에

디바이스 struct에서 mac어드레스 부분이 어디인가요?

태훈의 이미지

#include <pcap.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
 
#define PROMISCUOUS 1
#define NONPROMISCUOUS 0
 
void callback(u_char *useless, const struct pcap_pkthdr *pkthdr,
    const u_char *packet)
{
    struct ether_header *ep;
    struct ip *iph;
    unsigned short ether_type;
    int chcnt = 0;
    int len = pkthdr->len;
    int i;
 
    // Get Ethernet header.
    ep = (struct ether_header *)packet;
    // Get upper protocol type.
    //ether_type = ntohs(ep->ether_type);
    ether_type = ntohs((packet[15]<<8)|packet[14]);
 
    if (ether_type == ETHERTYPE_IP) {
        printf("ETHER Source Address = ");
        for (i=0; i<ETH_ALEN; ++i)
            printf("%.2X ", ep->ether_shost[i]);
        printf("\n");
        printf("ETHER Dest Address = ");
        for (i=0; i<ETH_ALEN; ++i)
            printf("%.2X ", ep->ether_dhost[i]);
        printf("\n");
 
        // Move packet pointer for upper protocol header.
        //packet += sizeof(struct ether_header);
        packet += sizeof(struct ether_header)+2;
        iph = (struct ip *)packet;
        printf("IP Ver = %d\n", iph->ip_v);
        printf("IP Header len = %d\n", iph->ip_hl<<2);
        printf("IP Source Address = %s\n", inet_ntoa(iph->ip_src));
        printf("IP Dest Address = %s\n", inet_ntoa(iph->ip_dst));
        printf("IP Packet size = %d\n", len-16);
    }
}
 
int main(int argc, char **argv)
{
  char *dev;
  char *net;
  char *mask;
  char errbuf[PCAP_ERRBUF_SIZE];
  struct bpf_program fp;
  pcap_t *pcd; // packet caputre descriptor.
  bpf_u_int32 netp;
  bpf_u_int32 maskp;
  struct in_addr net_addr, mask_addr;
 
  dev = pcap_lookupdev(errbuf);
  if (dev == NULL)
  {
      printf("%s\n", errbuf);
      exit(1);
  }
  printf("DEV : %s\n", dev);
 
  // Get netmask
  if (pcap_lookupnet(dev, &netp, &maskp, errbuf) == -1) {
    fprintf(stderr, "%s\n", errbuf);
    return 1;
  }
  net_addr.s_addr = netp;
  net = inet_ntoa(net_addr);
  printf("NET : %s\n", net);
  mask_addr.s_addr = maskp;
  mask = inet_ntoa(mask_addr);
  printf("MASK : %s\n", mask);
 
  // Get packet capture descriptor.
  pcd = pcap_open_live("any", BUFSIZ, NONPROMISCUOUS, -1, errbuf);
  if (pcd == NULL) {
    fprintf(stderr, "%s\n", errbuf);
    return 1;
  }
 
  // Set compile option.
  if (pcap_compile(pcd, &fp, "tcp", 0, netp) == -1) {
    fprintf(stderr, "compile error\n");
    return 1; }
 
  // Set packet filter role by compile option.
  if (pcap_setfilter(pcd, &fp) == -1) {
    fprintf(stderr, "set filter error\n");
    return 1;
  }
 
  // Capture packet. When packet captured, call callback function.
  pcap_loop(pcd, 0, callback, NULL);
  return 0;
} 

답변겸 저도 질문 하나 하겠습니다. ethernet packet header의 type field 앞에 붙은 2 byte 정채가 뭔가요?

Just do it!

태훈의 이미지

pcd = pcap_open_live("any", BUFSIZ, NONPROMISCUOUS, -1, errbuf);

이 라인을

pcd = pcap_open_live(dev, BUFSIZ, NONPROMISCUOUS, -1, errbuf);

으로 고치니까 ethernet header가 제대로 읽히는군요. 결국, ethernet headet type 앞의 2 byte는 다른 Network Interface와 연관이 있는것 같은데, 정확히 뭐하는건지 모르겠습니다.

Just do it!

bacon의 이미지

any를 사용하면 헤더부분이 다음처럼 됩니다.

#define SLL_HDR_LEN 16 /* total header length */
#define SLL_ADDRLEN 8 /* length of address field */

struct sll_header {
u_int16_t sll_pkttype; /* packet type */
u_int16_t sll_hatype; /* link-layer address type */
u_int16_t sll_halen; /* link-layer address length */
u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
u_int16_t sll_protocol; /* protocol */
};

sll_halen이 6이 었을것 같으므로 2바이트는 그냥 의미 없습니다.

태훈의 이미지

답변 감사합니다.

Just do it!

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.