두번째로, 제작했던 프로그램입니다 .
소켓 프로그래밍 배우면서, C 언어로 제작한 단순한 패킷 덤프 입니다 !
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/ethernet.h> /* ether_header */
#include <netinet/ip.h> /* iphdr */
#include <netinet/tcp.h> /* tcphdr */
#include "practical.h"
/* promiscuous mode header */
#include <sys/ioctl.h>
#include <net/if.h>
#include <time.h>
int main (int argc, char *argv[])
{
/* RAW 소켓 생성 */
int sock = socket (PF_PACKET,SOCK_RAW,htons(ETH_P_IP));
if(sock == -1)
error_handling(" sock error");
/* Promiscuous mode */
struct ifreq ifr;
strncpy(ifr.ifr_name,"eth0",4);
ifr.ifr_flags |= IFF_PROMISC;
ioctl(sock,SIOCSIFFLAGS,&ifr);
while (1)
{
/* 패킷을 수신(recv) */
uint8_t buf[ETH_FRAME_LEN];
ssize_t numBytesRcvd = recv (sock, buf, ETH_FRAME_LEN, 0);
if (numBytesRcvd == -1)
error_handling ("recv() error");
/* Ether Header 구조체 선언부 */
struct ether_header *pEh;
pEh = (struct ether_header *)buf;
/* IP 구조체 선언부 */
struct sockaddr_in source,dest;
/* IP HEADER 구조체 선언부 */
struct iphdr *pIh;
pIh = (struct iphdr *)(buf + sizeof (struct ether_header));
source.sin_addr.s_addr = pIh->saddr;
dest.sin_addr.s_addr=pIh->daddr;
/* TCP HEADER 구조체 선언부 */
struct tcphdr *pth;
pth= (struct tcphdr *)(buf + sizeof(struct ether_header)+ sizeof(struct iphdr));
/* 스니핑 시작 */
printf(" # # # # # # # # | 스니핑이 시작 되었습니다. |# # # # # # # # # # # # # \n");
printf ("1.Total Received %d Bytes.\n", numBytesRcvd);
printf ("2. Ether Mac | IP | Port \n");
/* 맥 어드레스 아이피 포트 출력 */
printf ("DMAC - %02X:%02X:%02X:%02X:%02X:%02X | DIP -%s | Dport%d\n",
pEh->ether_dhost[0], pEh->ether_dhost[1],
pEh->ether_dhost[2], pEh->ether_dhost[3],
pEh->ether_dhost[4], pEh->ether_dhost[5],
inet_ntoa(source.sin_addr),ntohs(pth->dest));
printf ("SMAC - %02X:%02X:%02X:%02X:%02X:%02X | SIP -%s | Sport %d\n",
pEh->ether_shost[0], pEh->ether_shost[1],
pEh->ether_shost[2], pEh->ether_shost[3],
pEh->ether_shost[4], pEh->ether_shost[5],
inet_ntoa(dest.sin_addr),ntohs(pth->source));
printf ("EthType = 0x%04X\n", ntohs (pEh->ether_type));
/* 아이피 헤더 정보 */
printf ("3. Ip Header Data\n");
printf ("IP Ver : %d | IP Header Length : %d | Time-to-Live : %d \n",pIh->version,pIh->ihl*4,pIh->ttl);
switch(pIh->protocol)
{
case 1: //icmp
printf("IP Protocol : Icmp\n");
break;
case 2: //igmp
printf("IP Protocol : Igmp\n");
break;
case 6: // TCP
printf("IP Protocol : TCP\n");
break;
case 17: // UDP
printf("IP Protocol : UDP\n");
break;
default:
printf(" protocol Default ");
break;
}
/* TCP 헤더 정보 */
printf("4. TCP Header Data \n");
printf("Seq - %u | Ack - %u | window - %d | Checksum - %d | Urp - %d \n",ntohl(pth->seq),ntohl(pth->ack_seq),pth->window,pth->check,pth->urg_ptr);
printf("Flag : URG = %d | ACK = %d | PSH = %d | RST = %d | SYN = %d | FIN = %d \n ",pth->urg,pth->ack,pth->psh,pth->rst,pth->syn,pth->fin);
/* 버퍼에 담긴 모든 데이터 출력 */
printf("5. Received Data \n");
int i,t;
for(i=0;i<numBytesRcvd;i++)
{
printf("%02X ",buf[i]);
t++;
if(t>13)
{
t=0;
printf("\n");
}
}
/* Day Time 함수 선언부 */
time_t now;
struct tm *date;
now = time(NULL);
date=localtime(&now);
/* Day Time 함수 출력부 */
fputc('\n',stdout);
printf(" # # # # # # # # | 현재시간 : %d 시 %d 분 %d 초 |# # # # # # # # # # # # # \n",date->tm_hour,date->tm_min,date->tm_sec);
}
return 0;
}