내가 libpcap의는 C 라이브러리 사용에 문제를 해결 한 :
을 main.c를
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <string.h>
void my_callback(u_char *user, const struct pcap_pkthdr *pkthdr, const u_char *packet) {
int i = 0;
int k = 0;
for (i = 0; i < pkthdr->len; i++) {
if ((i % 16) == 0) {
fprintf(stdout, "\n%03x0\t", k);
k++;
}
fprintf(stdout, "%02x ", packet[i]);
}
fprintf(stdout, "\n*******************************************************\n");
u_char ethernet_packet[14];
u_char ip_header[24];
u_char udp_header[8];
int udp_header_start = 34;
int data_length;
for (i = 0; i < 14; i++) {
ethernet_packet[i] = packet[0 + i];
}
fprintf(stdout, "Destination Address\t\t%02X:%02X:%02X:%02X:%02X:%02X\n", ethernet_packet[0], ethernet_packet[1], ethernet_packet[2], ethernet_packet[3], ethernet_packet[4], ethernet_packet[5]);
fprintf(stdout, "Source Address\t\t\t%02X:%02X:%02X:%02X:%02X:%02X\n", ethernet_packet[6], ethernet_packet[7], ethernet_packet[8], ethernet_packet[9], ethernet_packet[10], ethernet_packet[11]);
if (ethernet_packet[12] == 0x08 &&
ethernet_packet[13] == 0x00) {
fprintf(stdout, "Ethertype\t\t\t\tIP Packet\n");
for (i = 0; i < 20; i++) {
ip_header[i] = packet[14 + i];
}
fprintf(stdout, "Version\t\t\t\t\t%d\n", (ip_header[0] >> 4));
fprintf(stdout, "IHL\t\t\t\t\t\t%d\n", (ip_header[0] & 0x0F));
fprintf(stdout, "Type of Service\t\t\t%d\n", ip_header[1]);
fprintf(stdout, "Total Length\t\t\t%d\n", ip_header[2]);
fprintf(stdout, "Identification\t\t\t0x%02x 0x%02x\n", ip_header[3], ip_header[4]);
fprintf(stdout, "Flags\t\t\t\t\t%d\n", ip_header[5] >> 5);
fprintf(stdout, "Fragment Offset\t\t\t%d\n", (((ip_header[5] & 0x1F) << 8) + ip_header[6]));
fprintf(stdout, "Time To Live\t\t\t%d\n", ip_header[7]);
if (ip_header[9] == 0x11) {
fprintf(stdout, "Protocol\t\t\t\tUDP\n");
}
else {
fprintf(stdout, "Protocol\t\t\t\t%d\n", ip_header[9]);
}
fprintf(stdout, "Header Checksum\t\t\t0x%02x 0x%02x\n", ip_header[10], ip_header[11]);
fprintf(stdout, "Source Address\t\t\t%d.%d.%d.%d\n", ip_header[12], ip_header[13], ip_header[14], ip_header[15]);
fprintf(stdout, "Destination Address\t\t%d.%d.%d.%d\n", ip_header[16], ip_header[17], ip_header[18], ip_header[19]);
if ((ip_header[0] & 0x0F) > 5) {
udp_header_start = 48;
fprintf(stdout, "Options\t\t\t\t\t0x%02x 0x%02x 0x%02x 0x%02x\n", ip_header[20], ip_header[21], ip_header[22], ip_header[23]);
}
if (ip_header[9] == 0x11) {
fprintf(stdout, "\t\t\t\tUDP HEADER\n");
for (i = 0; i < 8; i++) {
udp_header[i] = packet[udp_header_start + i];
}
fprintf(stdout, "Source Port\t\t\t\t%d\n", (udp_header[0] << 8) + udp_header[1]);
fprintf(stdout, "Destination Port\t\t%d\n", (udp_header[2] << 8) + udp_header[3]);
fprintf(stdout, "Length\t\t\t\t\t%d\n", (udp_header[4] << 8) + udp_header[5]);
fprintf(stdout, "Checksum\t\t\t\t0x%02x 0x%02x\n", udp_header[6], udp_header[7]);
data_length = pkthdr->len - (udp_header_start + 8);
fprintf(stdout, "Data\n");
for (i = 0; i < data_length; i++) {
fprintf(stdout, "%02x ", packet[udp_header_start + 8 + i]);
}
fprintf(stdout, "\n");
}
}
else {
fprintf(stdout, "Ethertype\t\t\t\tUnknow\n");
}
}
int main(int argc,char **argv) {
char *dev;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* descr;
struct bpf_program fp;
bpf_u_int32 maskp;
bpf_u_int32 netp;
dev = pcap_lookupdev(errbuf);
if(dev == NULL) {
fprintf(stderr,"%s\n",errbuf); exit(1);
}
pcap_lookupnet(dev, &netp, &maskp, errbuf);
descr = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if(descr == NULL) {
printf("pcap_open_live(): %s\n",errbuf);
exit(1);
}
char filter[] = "udp";
if(pcap_compile(descr,&fp, filter,0,netp) == -1) {
fprintf(stderr,"Error calling pcap_compile\n");
exit(1);
}
if(pcap_setfilter(descr,&fp) == -1) {
fprintf(stderr,"Error setting filter\n");
exit(1);
}
pcap_loop(descr,-1,my_callback,NULL);
/* write a packet
//define a new packet and for each position set its values
u_char packet[86];
// Send down the packet
if (pcap_sendpacket(descr, packet, 86) != 0) {
fprintf(stderr,"\nError sending the packet: %s\n", pcap_geterr(descr));
return 2;
}
*/
return 0;
}
아이디어는 우리가 pcap_loop
를 통해 패킷을 선택하는 것이 있고 우리는 우리가 얻을 데이터를 분석 :
필자의 경우 처음에는 이더넷 헤더가 있는데, 나는 위키피디아를 어떻게 사용했는지 이해하기 위해 Ethernet frame을 사용했다. EtherType
은 0x0800로 설정되어 다음 바이트가 IP Header
IPv4 Header임을 나타냅니다. 여기서 은 UDP Packet
UDP Packet Structure입니다.
나는 pcap 라이브러리로 Xcode를 통해 OS X 10.9에서 이것을 컴파일했고, 정상적으로 작동합니다. 유일한 문제는 이것이 실제로 정적이라는 것입니다. 이더넷이 필요하며 IPv4에서만 작동합니다.
즉 컴퓨터의 특정 포트로 전송 된 모든 UDP 패킷을 수신하고 해당 UDP 패킷에 응답하고 싶습니까? 그리고 그 패킷보다 * 다른 * 패킷을 볼 필요가 없습니다. 즉, 다른 컴퓨터로 보내지거나 컴퓨터로 보내지 만 UDP 패킷이 아니거나 UDP 패킷을 보낸 경우입니다. 당신의 기계가 아니라 그 항구가 아니라면, 당신은 그것을 볼 필요가 없습니까? 그렇다면 libpcap을 사용할 필요가 없으며 일반적인 UDP 소켓을 사용할 수 있습니다. –