본문 바로가기

C 프로젝트/Row Packet Dump ( Sniffer )

모던한 Row Packet Dump in C

두번째로, 제작했던 프로그램입니다 .

소켓 프로그래밍 배우면서, 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;
}