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);
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바이트는 그냥 의미 없습니다.
답변 감사합니다.
텍스트 포맷에 대한 자세한 정보
<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]
#include <pcap.h> #include
답변겸 저도 질문 하나 하겠습니다. ethernet packet header의 type field 앞에 붙은 2 byte 정채가 뭔가요?
Just do it!
pcd = pcap_open_live("any",
이 라인을
으로 고치니까 ethernet header가 제대로 읽히는군요. 결국, ethernet headet type 앞의 2 byte는 다른 Network Interface와 연관이 있는것 같은데, 정확히 뭐하는건지 모르겠습니다.
Just do it!
any를 사용하면 헤더부분이 다음처럼 됩니다.
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!
댓글 달기