'Network'에 해당되는 글 24건

  1. 2011.10.14 08. UDP header
  2. 2011.10.07 07. TCP Header
  3. 2011.10.06 06. ICMP header
  4. 2011.10.06 05. ARP header(수정중)
  5. 2011.10.05 04. IP header (2)
  6. 2011.10.05 03. ethernet header 분석
  7. 2011.10.05 02. pcap 라이브러리
  8. 2011.10.05 01. Hexaview(수정중)
  9. 2011.10.05 00. Packet Analyzer
  10. 2011.07.25 06. 멀티플렉싱(multiplexing)과 select()함수 (1)

UDP header

TCP Header에 비하여 UDP는 간단합니다 4가지 정보만 검출하면 되는데 내용은 아래와같습니다

.Source Port

송신 측 호스트의 포트번호

.Destination Port

수신 측 호스트의 포트번호

.Length

UDP Packet의 옥텟 단위 길이

-UDP Header와 그 데이터를 포함

-field의 최소값 : 8 -> 0크기의 데이타 크리

.Checksum

UDP Header data를 포함한 세그먼트 전체에 대하여 계산한 값 즉 오류 검출

.흔히 사용되는 UDP Port Name, Port Number

Port Name

Port Number

 

Port Name

Port Number

 

Port Name

Port Number

echo

7

 

bootps

67

 

snmp

161

discard

9

 

bootpc

68

 

snmptrap

162

chargen

19

 

tftp

69

 

biff

512

time

37

 

sunrpc

111

 

syslog

514

nameserver

42

 

ntp

123

 

talk

517

tacasds-ds

49

 

netbios-ns (WINS)

137

 

rip

520

DNS

53

 

netbios-dgm

138

     

결과보기>>

자세히 보시면 UDP가 검출되었습니다

UDP header의 내용을 검출하니 아래 그림과 같이 나왔습니다

위의 표를 보아 Destination port 는 53으로 DNS 임을 알 수 있습니다

소스보기

#include "L3_UDP.h"
const void * L3_UDP(const void * vpData, unsigned int * uipNext)
{
const struct udphdr *stpUDP = vpData;

  printf("\n┌───────────────────────────────────┐");
  printf("\n│                        *UDP Header Information*                      │");
  printf("\n└───────────────────────────────────┘\n");

  printf("Source Port : %u\n",ntohs(stpUDP->source));
  printf("Destination Port : %u\n",ntohs(stpUDP->dest));
  printf("Length : %u\n",ntohs(stpUDP->len));
  printf("Checksum : %u\n",ntohs(stpUDP->check));
return vpData;
}

'Network > Packet Analyzer' 카테고리의 다른 글

08. UDP header  (0) 2011.10.14
07. TCP Header  (0) 2011.10.07
06. ICMP header  (0) 2011.10.06
05. ARP header(수정중)  (0) 2011.10.06
04. IP header  (2) 2011.10.05
03. ethernet header 분석  (0) 2011.10.05
Posted by mantwo

TCP Header 구조>>
 
참고로 TCP는 3계층입니다 함수를 L3_TCP로 지정해 주었습니다


netinet/tcp.h


사용방법
printf("Source Port : %d\n",ntohs(stpTCP->source));
앞에서와 같이 헤더의 내용을 보고 inet_ntoa,ntohs,ntohl으로 하고 구조체 ->포인터를 사용하여 %d %u %X로 찍어주면 됩니다

.SOURCE PORT/DESTINATION PORT
SOURCE PORT : 메시지를 보내는 측의 포트
DESTINATION PORT : 메시지를 받는 측의 포트

.SEQUENCE NUMBER

뒤에서 나올 SYN플래그가 설정되어있다면, SEQUENCE NUMBER는 초기화 된다. SYN이 설정이 되어있지 않다면 초기화된 SEQUENCE NUMBER + 1의 값이 들어간다.다음부터는 순서대로 +1이 되어 대입이 된다. 
초기화된 SEQUENCE NUMBER(ISN)

.ACKNOWLEDGEMENT NUMBER
다음에 받을것으로 예상되는 SEQUENCE NUMBER가 대입이 됩니다

.DATA OFFSET
TCP 헤더의 크기를 나타낸다. 최소 5 words 최대 15 words이다. 여기서 word는 32 bit임
그래서 *4를 하면 byte단위를 알수 있습니다


.RESERVED 사용하지 않습니다


.TCP FLAG
  URG (1 bit) – URGENT POINTER 필드가 유효
  ACK (1 bit) – ACKNOWLEDGMENT필드를 유효
  PSH (1 bit) – 세그먼트 PUSH를 요청
  RST (1 bit) – 즉시 연결을 끊음(비정상적인 종료)
  SYN (1 bit) – sequence numbers 동기화
  FIN   (1 bit) – 정상적인 종료

*3way handshake의 내용을 보면 fin syn ack의 내용을 잘 알수있습니다

. CHECKSUM
전송된 세그먼트가 잘 전송된건지 검사합니다.

. URGANT POINTER
세그먼트가 긴급데이터를 포함한다는것을 의미합니다. 
URG가 설정되어있다면 마지막 긴급한 데이터의 위치에 대한 포인터를 갖습니다.

. OPTION + PADDING
OPTION : 받는 측의 부가정보를 전달하기 위해 사용합니다.
PADDDING : 헤드의 크기를 맞추기 위해 사용합니다.

참고>>

3HAND SHAKING

. 연결(데이터를 주고 받을때, 통신을 종료할때)

1. 클라이언트에서 SYN과 SEQ를 전송합니다.
2. 서버에서 SYN과 클라이언트 SEQ에 대한 ACK, 그리고 자신의 SEQ를 전송합니다.
3. 클라이언트에서 서버 SEQ에 대한 ACK를 전송하여 연결을 시작합니다.

FIN의 경우 데이터를 주고받는 경우에 사용됩니다


클라이언트                        서버
    SYN (k)       --->
                     <---           ACK(k+1), SYN(y)
   ACK(y+1)      --->

텍스트로 그려서 보기가 힘들지만 처음에 클라이언트가 SYN을 보내는 것은 임의의 값이다. 그리고 이를 받은 서버는 '여기까지 데이터를 받았으니 여기서부터 데이터를 보내달라'는 ACK와 임의값의 SYN을 보내게 된다. 다시 클라이언트쪽에서도 '여기까지 데이터를 받았으니 여기서부터 데이터를 보내달라'는 ACK를 보낸다. 그렇기때문에 서버나 클라이언트쪽에서나 ACK값이 받은SYN값의+1이 되어 보내지는것이다.


 

소스보기
#include "L3_TCP.h"

unsigned int uiTCPlen;

const void * L3_TCP(const void * vpData, unsigned int * uipNext)
{
  const struct tcphdr *stpTCP = vpData;
  uiTCPlen = (stpTCP->doff)*4;
  
  printf("\n┌───────────────────────────────────┐");
  printf("\n│                        *TCP Header Information*                      │");
  printf("\n└───────────────────────────────────┘\n");
  
  printf("Source Port : %d\n",ntohs(stpTCP->source));
  printf("Destination Port : %d\n",ntohs(stpTCP->dest));
  printf("Sequence Number : %u\n",ntohl(stpTCP->seq));
  printf("Acknowledgment : %u\n",ntohl(stpTCP->ack_seq));

  printf("Offset : %dbyte\n",(stpTCP->doff)*4);

  printf("<TCP Flag> \n");
  printf("     Fin : %s\n",((stpTCP->fin))?"1":"0");
  printf("     Syn : %s\n",((stpTCP->syn))?"1":"0");
  printf("     Rst : %s\n",((stpTCP->rst))?"1":"0");
  printf("     Psh : %s\n",((stpTCP->psh))?"1":"0");
  printf("     Ack : %s\n",((stpTCP->ack))?"1":"0");
  printf("     Urg : %s\n",((stpTCP->urg))?"1":"0");

  printf("Window : %d\n",ntohs(stpTCP->window));
  printf("Check sum : %d\n",ntohs(stpTCP->check));
  
  *uipNext =  (ntohs(stpTCP->source)< ntohs(stpTCP->dest))?ntohs(stpTCP->source) : ntohs(stpTCP->dest);
  return vpData + ((stpTCP->doff)*4);
}



결과보기


네이버나 구글이 접속 되어 있는 상태에서 패킷을 캡쳐할 경우 DEST가 80이 나옵니다



'Network > Packet Analyzer' 카테고리의 다른 글

08. UDP header  (0) 2011.10.14
07. TCP Header  (0) 2011.10.07
06. ICMP header  (0) 2011.10.06
05. ARP header(수정중)  (0) 2011.10.06
04. IP header  (2) 2011.10.05
03. ethernet header 분석  (0) 2011.10.05
Posted by mantwo



ICMP는?
호스트 서버와 인터넷 게이트웨이 사이에서 메시지를 제어하고 에러를 알려주는 프로토콜로서 RFC 792에 정의되어있다. ICMP는 IP 데이터그램을 사용하지만, 메시지는 TCP/IP 소프트웨어에 의해 처리되며, 응용프로그램 사용자에게 직접 분명하게 보이지는 않는다. 일례로서, ping 명령어는 인터넷 접속을 테스트하기 위해 ICMP를 사용한다.

내용

1)Type(8bit) : ICMP의 타입을 정의한다.

표 1. ICMP Type 필드 유형

0 icmp echo replay icmp 요청에 대한 icmp 응답
3 Destination Unreachable Message 수신지까지 메시지가 도착할수 없음
4 Source Quench Message 송신지 억제
5 Redirect Message 재지시
8 icmp echo request 목적지 호스트에 ICMP 응답을 요청한다
11 Time Exceeded Message 데이타그램 시간초과(TTL 초과)
12 Parameter Problem Message 데이타그램에서의 파라메타 문제
13,14 Timestamp or Timestamp Reply Message 13:시간기록요청, 14:시간기록응답

                     Type 0 : Echo reply.

                     Type 3: Destination unreachable.

                     Type 8: Echo request.

                     가장 많이 쓰이는 3가지만 알아보았다. 더 많은 정보를 보고 싶다면
                      

                     http://www.networksorcery.com/enp/default1101.htm 에서 확인하면 됩니다

 

2)Code(8bit) : Type에 따라 분류된 내용을 정의합니다.

case ICMP_UNREACH:
      printf(" dest unreachable, codes : ");
      switch(stpICMP->icmp_code)
      {
        case ICMP_UNREACH_NET:
          printf(" bad net \n");
          break;
        case ICMP_UNREACH_HOST:

에서 볼수 있듯이 unreach의 type 아래에 이에 해당하는 code들을 나열하면 됩니다


3)Checksum(16bit) : ICMP 패킷의 무결성을 검사한다.


3가지의 항상 들어가는 구조 이외에
http://www.networksorcery.com/enp/default1101.htm 로 가면
type에 따라 약간씩 다르다는것을 알수 있습니다

echo request


redirect


먼저 헤더를 위치를 확인합니다 위치는

netinet/ip_icmp.h에 있습니다



위로 부터 type과 code 그리고 union공용에 앞에서 그림으로 보았던 바뀌는 부분인 identifier sequence ipaddress등등 이 있습니다

소스보기

#include "L3_ICMP.h"


const void * L3_ICMP(const void * vpData, unsigned int * uipNext)
{
  const struct  icmp *stpICMP = vpData;

  printf("\n┌───────────────────────────────────┐");
  printf("\n│                        *ICMP Header Information*                     │");
  printf("\n└───────────────────────────────────┘\n");

  printf("Type/Code :");

  switch(stpICMP->icmp_type)
  {
    case ICMP_ECHOREPLY:
      printf(" Echo Reply\n");
      printf("Checksum : 0X%04X\n",(ntohs(stpICMP->icmp_cksum)));
      printf("Identfier : 0X%04X\n",(ntohs(stpICMP->icmp_hun.ih_idseq.icd_id)));
      printf("Sequence Number : 0X%04X\n",(ntohs(stpICMP->icmp_hun.ih_idseq.icd_seq)));
      break;
    case ICMP_UNREACH:
      printf(" dest unreachable, codes : ");
      switch(stpICMP->icmp_code)
      {
        case ICMP_UNREACH_NET:
          printf(" bad net \n");
          break;
        case ICMP_UNREACH_HOST:
          printf(" bad host \n");
          break;
        case ICMP_UNREACH_PROTOCOL:
          printf(" bad protocol \n");
          break;
        case ICMP_UNREACH_PORT:
          printf(" bad port \n");
          break;
        case ICMP_UNREACH_NEEDFRAG:
          printf(" IP_DF caused drop \n");
          break;
        case ICMP_UNREACH_SRCFAIL:
          printf(" src route failed \n");
          break;
        case ICMP_UNREACH_NET_UNKNOWN :
          printf(" unknown net \n");
          break;
        case ICMP_UNREACH_HOST_UNKNOWN:
          printf(" unknown host \n");
          break;
        case ICMP_UNREACH_ISOLATED:
          printf(" src host isolated \n");
          break;
        case ICMP_UNREACH_NET_PROHIB:
          printf(" net denied \n");
          break;
        case ICMP_UNREACH_HOST_PROHIB:
          printf(" host denied \n");
          break;
        case ICMP_UNREACH_TOSNET:
          printf(" bad tos for net \n");
          break;
        case ICMP_UNREACH_TOSHOST:
          printf(" bad tos for host \n");
          break;
        case ICMP_UNREACH_FILTER_PROHIB:
          printf(" admin prohib \n");
          break;
        case ICMP_UNREACH_HOST_PRECEDENCE:
          printf(" host prec vio. \n");
          break;
        case ICMP_UNREACH_PRECEDENCE_CUTOFF:
          printf(" prec cutoff \n");
          break;        
      }
      printf("Checksum : 0X%04X\n",(ntohs(stpICMP->icmp_cksum)));
      printf("Unused : 0X%04X\n",(ntohs(stpICMP->icmp_hun.ih_pmtu.ipm_void)));
      printf("Next Hop Mtu : 0X%04X\n",(ntohs(stpICMP->icmp_hun.ih_pmtu.ipm_nextmtu)));
      printf("Data length: %d byte\n",sizeof(stpICMP->icmp_dun.id_ip.idi_ip));
      break;
    case ICMP_SOURCEQUENCH:
      printf("Checksum : 0X%04X\n",(ntohs(stpICMP->icmp_cksum)));
      printf("packet lost, slow down \n");
      printf("Unused : 0X%04X\n",(ntohs(stpICMP->icmp_hun.ih_pmtu.ipm_void)));
      break;
    case ICMP_REDIRECT:
      printf(" Redirect (change route) : ");
      switch(stpICMP->icmp_code)
      {
        case ICMP_REDIRECT_NET:
          printf(" for network \n");
          break;
        case ICMP_REDIRECT_HOST:
          printf(" for host \n");
          break;
        case ICMP_REDIRECT_TOSNET:
          printf(" for tos and net \n");
          break;
        case ICMP_REDIRECT_TOSHOST:
          printf(" for tos and host \n");
          break;
      }
      printf("Checksum : 0X%04X\n",(ntohs(stpICMP->icmp_cksum)));
      printf("Gateway address : %s\n",(inet_ntoa(stpICMP->icmp_hun.ih_gwaddr)));
      break;
    
    case ICMP_ECHO:
      printf(" Echo Request      \n");
      printf("Checksum : 0X%04X\n",(ntohs(stpICMP->icmp_cksum)));
      printf("Identfier : 0X%04X\n",(ntohs(stpICMP->icmp_hun.ih_idseq.icd_id)));
      printf("Sequence Number : 0X%04X\n",(ntohs(stpICMP->icmp_hun.ih_idseq.icd_seq)));
      break;
    case ICMP_TIMXCEED:
      printf(" time exceeded, code: \n");
      switch(stpICMP->icmp_code)
      {      
        case ICMP_TIMXCEED_INTRANS:
          printf(" ttl==0 in transit \n");
          break;
        case ICMP_TIMXCEED_REASS:
          printf(" ttl==0 in reass \n");
          break;
      }
      printf("Checksum : 0X%04X\n",(ntohs(stpICMP->icmp_cksum)));
      printf("Unused : 0X%04X\n",(ntohs(stpICMP->icmp_hun.ih_pmtu.ipm_void)));
      break;
    default:
      printf("unknown\n");
      break;
  }
   
  *uipNext = stpICMP->icmp_type;
  
  return vpData;
}


결과확인
ping yahoo.com을 하여 결과를 확인 하여 보았습니다

먼저 echo request가 나왔습니다


그리고 echo reply도 나왔습니다

헥사뷰 두번째 라인 04부터 값들이 정의 되어 있는 것을 확인 할 수 있습니다









'Network > Packet Analyzer' 카테고리의 다른 글

08. UDP header  (0) 2011.10.14
07. TCP Header  (0) 2011.10.07
06. ICMP header  (0) 2011.10.06
05. ARP header(수정중)  (0) 2011.10.06
04. IP header  (2) 2011.10.05
03. ethernet header 분석  (0) 2011.10.05
Posted by mantwo

Packet Analyzer ARP header

위 그림의 바이트를 계산하면 총 28 btye를 갖는 것을 알 수 있습니다

두개의 if헤더 파일안에는 apr에 관련된 구조체가 아래 그림과 같이 정의되어 있습니다

원하는 값을 stpARP->구조체 형태로 볼 수 있습니다

if_arp.h

if_ether.h

1.Hardware type : Mac주소의 타입을 정의 함 (2 byte)

0 = NETROM

1 = Ethernet v2

2 = EETHER

3 = AX25..등등 알 수 있습니다

2.Protocol type : 맵핑될 프로토콜 타입을 정의 한다. (2 byte)

0X0800 : IPv4

Ethernet head 타입과 일치

>>헥사뷰에 먼저 값이 08 00 으로 800임을 확인 하였습니다

그리고 ethernet.c 에서 사용되었던 타입과 들어오는 값이 일치하는 것을 확인하였습니다

3.Hardware address size : 하드웨어 주소의 크기 MAC이라서 6바이트임 48bit (1 byte)

4.Protocol address size : 변환될 프로토콜의 크기 4바이트 32bit (1 byte)

5.Opcode : ARP에는 두가지 타입이 있다. 그 타입을 나타낸다. (2 byte)

0X0001 = ARP Request

0X0002 = ARP Reply

0X0003 = RARP request

0X0004 = RARP reply] 등등.....

6.Sender MAC address : 송신지 MAC 주소 ( 6 byte)

7.Sender IP address : 송신지 IP 주소 (4 byte)

8.Target MAC address : 수신지 MAC 주소 (6 byte)

9.Target IP address : 수신지 IP 주소 (4 byte)

 

<ETH_LEN의 길이 헤더파일 보기>

결과보기

소스코드

#include "L2_ARP.h"

const void * L2_ARP(const void * vpData,unsigned int * uipNext )
{
  const struct ether_arp *stpARP = vpData;

  printf("\n┌───────────────────────────────────┐");
  printf("\n│                        *ARP Hader Information*                       │");
  printf("\n└───────────────────────────────────┘\n");

  /*Hardware Type*/
  printf("Hardware Type : ");

  switch(ntohs(stpARP->arp_hrd))
  {
    /*ARP protocol HARDWARE identifiers.0~23*/
    case ARPHRD_NETROM:
      printf("From KA9Q: NET/ROM pseudo. \n");
      break;
    case ARPHRD_ETHER:
      printf("Ethernet 10/100Mbps.\n");
      break;
    case ARPHRD_EETHER:
      printf(" Experimental Ethernet.\n");
      break;
    case ARPHRD_AX25:
      printf(" AX.25 Level 2.\n");
      break;
    case ARPHRD_PRONET:
      printf("PROnet token ring.\n");
      break;
    case ARPHRD_CHAOS:  
      printf("Chaosnet.\n");
      break;
    case ARPHRD_IEEE802:
      printf("IEEE 802.2 Ethernet/TR/TB.\n");
      break;
    case ARPHRD_ARCNET:
      printf(" ARCnet. \n");
      break;
    case ARPHRD_APPLETLK:  
      printf("APPLEtalk.\n");
      break;
    case ARPHRD_DLCI:
      printf(" Frame Relay DLCI.\n");
      break;
    case ARPHRD_ATM:
      printf("ATM.\n");
      break;
    case ARPHRD_METRICOM:
      printf("Metricom STRIP (new IANA id).\n");
      break;
    /* Dummy types for non ARP hardware 256~801*/
    case ARPHRD_SLIP:
      printf("ARPHRD_SLIP\n");
      break;
    case ARPHRD_CSLIP:
      printf("ARPHRD_CSLIP\n");
      break;
    case ARPHRD_SLIP6:
      printf("ARPHRD_SLIP6\n");
      break;
    case ARPHRD_CSLIP6:
      printf("ARPHRD_CSLIP6\n");
      break;
    case ARPHRD_RSRVD:
      printf("Notional KISS type.\n");
      break;
    case ARPHRD_ADAPT:
      printf("ARPHRD_ADAPT\n");
      break;
    case ARPHRD_ROSE:
      printf("ARPHRD_ROSE\n");
      break;
    case ARPHRD_X25:
      printf("CCITT X.25.\n");
      break;
    case ARPHDR_HWX25:
      printf("Boards with X.25 in firmware.\n");
      break;
    case ARPHRD_PPP:
      printf("ARPHRD_PPP\n");
      break;
    case ARPHRD_CISCO:
      printf("Cisco HDLC.\n");
      break;
    //case ARPHRD_HDLC:
    //  printf("ARPHRD_HDLC\n");
    //  break;
    case ARPHRD_LAPB:
      printf(" LAPB.  \n");
      break;
    case ARPHRD_DDCMP:
      printf("Digital's DDCMP.\n");
      break;
    case  ARPHRD_RAWHDLC:
      printf("Raw HDLC. \n");
      break;

    case ARPHRD_TUNNEL:
      printf(" IPIP tunnel. \n");
      break;
    case ARPHRD_TUNNEL6:
      printf(" IPIP6 tunnel. \n");
      break;
    case ARPHRD_FRAD:
      printf("Frame Relay Access Device.\n");
      break;
    case ARPHRD_SKIP:
      printf("SKIP vif. \n");
      break;
    case ARPHRD_LOOPBACK:
      printf("Loopback device.  \n");
      break;
    case ARPHRD_LOCALTLK:
      printf("Localtalk device.\n");
      break;
    case ARPHRD_FDDI:
      printf(" Fiber Distributed Data Interface.\n");
      break;
    case ARPHRD_BIF:
      printf("AP1000 BIF.\n");
      break;
    case ARPHRD_SIT:
      printf("sit0 device - IPv6-in-IPv4.\n");
      break;
    case ARPHRD_IPDDP:
      printf(" IP-in-DDP tunnel. \n");
      break;
    case ARPHRD_IPGRE:
      printf("GRE over IP. \n");
      break;
    case ARPHRD_PIMREG:
      printf("PIMSM register interface.\n");
      break;
    case ARPHRD_HIPPI:
      printf("High Performance Parallel I'face.\n");
      break;
    case ARPHRD_ASH:
      printf("(Nexus Electronics) Ash.  \n");
      break;
    case ARPHRD_ECONET:
      printf(" Acorn Econet. \n");
      break;
    case ARPHRD_IRDA:
      printf("Linux-IrDA.\n");
      break;
    case ARPHRD_FCPP:
      printf("Point to point fibrechanel.\n");
      break;
    case ARPHRD_FCAL:
      printf("Fibrechanel arbitrated loop.  \n");
      break;
    case ARPHRD_FCPL:
      printf("Fibrechanel public loop.\n");
      break;
    case ARPHRD_FCPFABRIC:
      printf("Fibrechanel fabric.  \n");
      break;
    case ARPHRD_IEEE802_TR:
      printf("Magic type ident for TR. \n");
      break;
    case ARPHRD_IEEE80211:
      printf("IEEE 802.11. \n");
      break;      
    default:
      printf("unknown\n");
      break;

  }

  /* Protocol Type */
  printf("Protocol Type : ");
  switch(ntohs(stpARP->arp_pro))
  {
    case ETHERTYPE_PUP:
      printf("Xerox PUP\n");    
      break;

    case ETHERTYPE_IP:
      printf("IP\n");
      break;
    case ETHERTYPE_ARP:
      printf("ARP \n");
      break;
    case ETHERTYPE_REVARP:
      printf("Address redolution \n");
      break;
    default :
      printf("unknown\n");
      break;
  }
  /* Hardware Adress Lengrth */
  printf("Hardware Adress Lengrth : %dbyte\n",(stpARP->arp_hln));
  /*Protocol Adress Lengrth */
  printf("Protocol Adress Lengrth : %dbyte\n",(stpARP->arp_pln));
  /*  opcodes. */
  printf("OP code : ");
  switch(ntohs(stpARP->arp_op))
  {
  /* ARP protocol opcodes. */
    case ARPOP_REQUEST:
      printf(" ARP request. \n");
      break;
    case ARPOP_REPLY:
      printf(" ARP reply. \n");
      break;
    case ARPOP_RREQUEST:
      printf(" RARP request.\n");
      break;
    case ARPOP_RREPLY:
      printf(" RARP reply.\n");
      break;
    case ARPOP_InREQUEST:
      printf(" InARP request. \n");
      break;
    case ARPOP_InREPLY:
      printf(" InARP reply.\n");
      break;
    case ARPOP_NAK:
      printf(" (ATM)ARP NAK.\n");
      break;

    default:
      printf("unknown\n");
      break;
  }
  /* Sender hardware address */
  printf("Sender hardware address : ");
  printf("[%02X:%02X:%02X:%02X:%02X:%02X]\n"
    
    ,stpARP->arp_sha[0]
    ,stpARP->arp_sha[1]
    ,stpARP->arp_sha[2]
    ,stpARP->arp_sha[3]
    ,stpARP->arp_sha[4]
    ,stpARP->arp_sha[5]);  
  /* Sender Protocol address */
  printf("Sender Protocol address : %s\n", inet_ntoa(stpARP->arp_spa));
  /*Target hardware address  */
  printf("Target hardware address : ");
  printf("[%02X:%02X:%02X:%02X:%02X:%02X]\n"
    
    ,stpARP->arp_tha[0]
    ,stpARP->arp_tha[1]
    ,stpARP->arp_tha[2]
    ,stpARP->arp_tha[3]
    ,stpARP->arp_tha[4]
    ,stpARP->arp_tha[5]);  
  /* Target Protocol address */
  printf("Target Protocol address : %s\n", inet_ntoa(stpARP->arp_tpa));

  printf("----------------------------------------------------------------------------\n");
  
  return vpData;
}

 

'Network > Packet Analyzer' 카테고리의 다른 글

07. TCP Header  (0) 2011.10.07
06. ICMP header  (0) 2011.10.06
05. ARP header(수정중)  (0) 2011.10.06
04. IP header  (2) 2011.10.05
03. ethernet header 분석  (0) 2011.10.05
02. pcap 라이브러리  (0) 2011.10.05
Posted by mantwo

iphdr보기


netinet\ip.h


구조체 설명>>
Version (4bit) : 데이터 통신에 사용된 IP 프로토콜의 버전, 현재는 IPv4

Header Length (4bit) : IP헤더의 길이, 일반적인 IP헤더는 20바이트(32bit*5)이며, 그림과 같이32bit단위로 나타낸다.

Type of Service (8bit)(TOS) : 데이터 그램의 성격을 명시하여, 라우터나, 호스트등에서 우선 순위 서비스(Qos : Quality of Service)를 제공하기 위하여 제공된 필드?

Total Length (16bit) :IP헤더와 데이터를 포함한 전체 IP패킷의

Total Length = 16bit = 64k = 65536

MTU 최대 전송 단위 (MTU, Maximum Transmission Unit) = 1500

65536 과 1500은 차이가 있습니다 그래서 1500에 맞추게 됩니다

Identification(16bit):분열된 데이터를 재배열하기 위해서 송신자가데이터그램의 조각들에 부여한 일련번호(동일IP데이터그램에서분열된 IP패킷들은 같은 일련번호)

Flags (3bit) : 3개의 비트를 이용한 분열의 상태 정보를 제공하는 필드
- bit 0 : 예약. 반드시 0이여야 함.
- bit 1 : 0 = 분열 허용 / 1 = 분열 허용안됨
-bit 2 : 0 = 현재데이터가 마지막 분열 / 1 = 뒤에 분열된 데이터가 있음

Fragment offset (13bit) : 데이터가 전체데이터그램의 어느부분에 속하는지 나타내는 Byte

Timeto live(8bit) : IP패킷이 네트워크에서 얼마나 오래 존재할 수 있는가를 나타낸다(0-255) 라우터를 하나 거칠때마다 1씩 감사하고0이 되면 라우터에서 소멸시킴.

Protocol(8bit) : IP데이터그램의 데이터 부분이 어떤 상위계층에 해당하는가를 나타내는 필드 (ex : TCP 6 / UDP 17 /ICMP 1 / IP 0 /IGMP 등)
HeaderChecksum (16bit) :

IP헤더의 헤더 비트의 합을 저장하는 필드로 네트워크를통과 하며 변경된 TTL, 또는 분열의숫자 등에 의해 변경된 IP 헤더 비트의 합이 Header Checksum과 비교하여일치 여부를 확인, 불일치 할 경우 손상된것으로 판단하여 소멸

Source IP address (32bit) : IP 데이터그램을 전송한 호스트의 32비트 IP주소 필드

Destination IP address (32bit) : IP 데이터그램을 수신할 목적지 호스트의 32비트 IP주소 필드

options(필요할 경우) :

대부분 IP 데이터그램에는 포함되어 있지 않은 필드. 필요할 경우 40byte까지 생성가능. (ex :Security Options, Record Route, Strict Source Routing, Timestamp등)

Padding( Options에 따른 가변 길이 ) :

IP헤더는 32비트 단위로 저장을 하는데, Options 부분이 32bit 단위가 되도록 만드는데사용.



결과보기

참고>>L2와 L1

학원에서 버스를 타고 영도에 간다고 한다면 한번에 가는 버스가 없으므로 2~3번 갈아타야하지만 결국엔 영도에 도착하게 됩니다

L1 L2도 이와 비슷한데 아래 그림을 보면

PC –> ㅁ –> ㅁ -> PC

pc에서 pc로 이동한다는 목적은 L2에 해당되며

그 사이 패킷의 이동 방법은 L1에 해당됩니다

쉽게 말해 결국은 pc에 도착하게 되지만 그사이에는 여러가지 과정이 있다는 것입니다

참고>>ntohs (수정중) 

 

소스보기

main.c
ucpData=L1_Ethernet(ucpData,&uiNext);


#include "L2_IP.h"


const void * L2_IP(const void * vpData, unsigned int * uipNext)
{
  const struct ip *stpIP = vpData;
  //unsigned int a = 0x00FF00FF;

  printf("\n┌───────────────────────────────────┐");
  printf("\n│                        *IP Hader Information*                        │");
  printf("\n└───────────────────────────────────┘\n");


  printf("IP version : IPv%d\n", stpIP->ip_v);
  printf("IP header length : %d byte\n", (stpIP->ip_hl)*4);

  printf("Type of Service : ");
  switch(IPTOS_TOS(stpIP->ip_tos))
  {
    case IPTOS_LOWDELAY:
      printf("LOWDELAY\n");
      break;
    case IPTOS_THROUGHPUT:
      printf("THROUGHPUT\n");
      break;
    case IPTOS_RELIABILITY:
      printf("RELIABILITY\n");
      break;
    case IPTOS_LOWCOST:
      printf("LOWCOST\n");
      break;
    default:
      printf("unknown\n");
      break;
  }
  /*Total Length*/
  printf("Total Length : %04d bytes\n",(ntohs(stpIP->ip_len)));
  /*Identification*/
  printf("ID(Identification) : %d\n",(ntohs(stpIP->ip_id)));
  /*fragment flag  DF MF*/
  printf("DF(Dont fragment flag) : %s\n",(ntohs(stpIP->ip_off)&IP_DF)?"YES":"NO");
  printf("MF(More fragment flag) : %s\n",(ntohs(stpIP->ip_off)&IP_MF)?"YES":"NO");
  /*Time to Live*/
   printf("TTL(Time to Live): %d sec\n",(ntohs(stpIP->ip_ttl)));

  /*Protocol*/
  printf("Protocol : ");
  switch(stpIP->ip_p)
  {
    case IPPROTO_IP:
      printf("Dummy protocol for TCP\n");
      break;

    //case IPPROTO_HOPOPTS:
      //printf("IPv6 Hop-by-Hop options.\n ");
    //  break;          
    case IPPROTO_ICMP:
      printf("Internet Control Message Protocol.\n");
      break;
    case IPPROTO_IGMP:
      printf("Internet Group Management Protocol.\n");  
      break;
    case IPPROTO_IPIP:
      printf("IPIP tunnels (older KA9Q tunnels use 94).\n");  
      break;
    case IPPROTO_TCP:
       printf("TCP(Transmission Control Protocol.)\n");  
      break;
    case IPPROTO_EGP:
      printf("Exterior Gateway Protocol.\n");  
      break;
    case IPPROTO_PUP:
      printf("PUP protocol.\n");  
      break;
    case IPPROTO_UDP:
      printf("UDP(User Datagram Protocol.)\n");  
      break;
    case IPPROTO_IDP:
      printf("XNS IDP protocol.\n");  
      break;
    case IPPROTO_TP:
      printf(" SO Transport Protocol Class 4.\n");  
      break;
    case IPPROTO_IPV6:
      printf("IPv6 header.\n");  
      break;
    case IPPROTO_ROUTING:
      printf("IPv6 routing header.\n");  
      break;
    case IPPROTO_FRAGMENT:
       printf("IPv6 fragmentation header.\n");  
      break;
    case IPPROTO_RSVP:
      printf("Reservation Protocol.\n ");  
      break;
    case IPPROTO_GRE:
      printf("General Routing Encapsulation.\n");  
      break;
    case IPPROTO_ESP:
      printf("encapsulating security payload.\n");  
      break;
    case IPPROTO_AH:
      printf(" authentication header.\n");  
      break;
    case IPPROTO_ICMPV6:
      printf("ICMPv6.\n");  
      break;
    case IPPROTO_NONE:
      printf("IPv6 no next header.\n");  
      break;
    case IPPROTO_DSTOPTS:
      printf("IPv6 destination options. \n");  
      break;
    case IPPROTO_MTP:
      printf("Multicast Transport Protocol.\n");  
      break;
    case IPPROTO_ENCAP:
      printf("Encapsulation Header.\n");  
      break;
    case IPPROTO_PIM:  
      printf("Protocol Independent Multicast.\n");  
      break;
    case IPPROTO_COMP:
      printf("Compression Header Protocol.\n");  
      break;
    case IPPROTO_RAW:
      printf("Raw IP packets.\n");  
      break;
    case IPPROTO_MAX:
      printf("MAX.\n");  
      break;

    default:
      printf("unknown\n");
      break;
        
  }
  *uipNext = stpIP->ip_p;
  
  /*Header Checksum*/
  printf("Header Checksum : %d\n",(ntohs(stpIP->ip_sum)));
  /*Source Address*/
  printf("Source Address : %s\n",(inet_ntoa(stpIP->ip_src)));
  /*Destination Address*/
  printf("Destination Address : %s\n",(inet_ntoa(stpIP->ip_dst)));


  printf("----------------------------------------------------------------------------\n");

  //printf("test IP : %s\n",inet_ntoa(a));
  
  //printf("test IP : %s\n",inet_ntoa(*((struct in_addr*)&a)));
  return vpData = (unsigned char*)vpData + ((stpIP->ip_hl)*4);
}



참고>>ICMP Header 정 보

Type (8bit) : 에러메시지의 형태를 나타냄.
Type 3 : Destination Unreachable

목적지호스트로 가는 경로, 포트를 확인할 수 없을 때
Type 4 : Source Quench

송신시스템이 너무 많은 데이터를 전송하여 수신호스트가 처리하지 못하여 분실 가능성을 알릴 때 사용.

Type 5 : Rediret

더 짧은 경로를 알고 있는 게이트웨이로의 정보를 알려주는 경우.
Type 11 : Time Exceeded

TTL값이 0으로 소멸 or 재배열작업이 오래 걸려 패킷이 소멸될 경우.
Type 12 : Parameter Problem

IP 데이터그램 중 사용되어지는 옵션이 잘못 되었을 경우.

Code (8bit) : Type에 나타난 에러 메시지의 하위 형태.
Checksum (16bit) : ICMP메시지의 손상여부를 검사하는 간단한 합으로 계산하여 판단한다.
Unused(32bit) : 에러 메시지에 대한 추가 정보를 제공하기 위한 부분. unused

Internet Header +64 bits of Original Data Datagram (60 Bytes + 60bit)
: 문제가 생긴 원래 IP 데이터그램의 헤더와 데이터의 일부를 보내어 송신 호스트가 어떤 데이터그램이 실패했는지 판단하게 한다.

'Network > Packet Analyzer' 카테고리의 다른 글

06. ICMP header  (0) 2011.10.06
05. ARP header(수정중)  (0) 2011.10.06
04. IP header  (2) 2011.10.05
03. ethernet header 분석  (0) 2011.10.05
02. pcap 라이브러리  (0) 2011.10.05
01. Hexaview(수정중)  (0) 2011.10.05
Posted by mantwo

도서추천!! 강컴닷컴에서 스티븐스 검색

clip_image002

 

vi /usr/include/net/ethernet.h

clip_image003

구조체의 내용은 이렇습니다

destination – dhost 1바이트 * 6개

source –shost 1바이트 *6개

type – 2바이트

합하면 6 + 6 + 2= 14

 

브로드케스팅이란?

8PC - 공유기 - 7PC 사이에 전기적 신호와 페킷을 교환하는데

부팅시에나 처음에는 맥어드레스를 몰라서 아무나 받으라는 의미에서 FFFFFFFFFF를 보내는것을 보로드 케스팅이라고 합니다

clip_image004

 

makefile정리

:packet analyzer분석시 자주 컴파일을 하게 되는데 ethernet.c뿐만 아니라

더 많은 프로그램을 붙혀서 만듭니다 그렇게 되면 컴파일 옵션이 복잡해져서 실수를 하기 쉽습니다

그래서 컴파일 옵션을 make명령어로 정리해 두었습니다 

vi makefile

CCFLAGS = -lpcap

CC = gcc

OBJ = test.o hexaview.o L1_Ethernet.o

all : $(OBJ)

$(CC) -o main $(OBJ) $(CCFLAGS)

clean :

rm -rf $(OBJ)

rm -rf main

run : all

./main

실행>>

make clean //초기화

make run //컴파일 및 실행

MAC address 출력

: 어제 활용한 소스에서 ucpData에 읽어드린 패킷의 정보가 있습니다 패킷의 정보를 읽어드려 헤더상단에 있는 mac address를 출력하는 소스입니다

 

소스파일 보기

#include "L1_Ethernet.h"
void L1_Ethernet(const void * vpData )
{
const struct ether_header * stpEth = vpData ;
  printf("[%02X:%02X:%02X:%02X:%02X:%02X]->"
"[%02X:%02X:%02X:%02X:%02X:%02X]\n"
    ,stpEth->ether_shost[0]
    ,stpEth->ether_shost[1]
    ,stpEth->ether_shost[2]
    ,stpEth->ether_shost[3]
    ,stpEth->ether_shost[4]
    ,stpEth->ether_shost[5]
    ,stpEth->ether_dhost[0]
    ,stpEth->ether_dhost[1]
    ,stpEth->ether_dhost[2]
    ,stpEth->ether_dhost[3]
    ,stpEth->ether_dhost[4]
    ,stpEth->ether_dhost[5]); 

return;
}

결과보기 mac address가 출력 되었습니다

clip_image005

'Network > Packet Analyzer' 카테고리의 다른 글

05. ARP header(수정중)  (0) 2011.10.06
04. IP header  (2) 2011.10.05
03. ethernet header 분석  (0) 2011.10.05
02. pcap 라이브러리  (0) 2011.10.05
01. Hexaview(수정중)  (0) 2011.10.05
00. Packet Analyzer  (0) 2011.10.05
Posted by mantwo

pcap라이브러리을 사용하여 장치를 열고 장치의 이름을 출력하고 장치를 닫는 것이 목표입니다

리눅스로 작업을 했기에 리눅스 관련 참고사항도 설명하였습니다

전체소스 보기

clip_image001

소스분석하기

네트워크 디바이스 열기

man pcap의 내용

clip_image002

 

pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)

pcap_t *stpNIC

pcap_open_live(cpNIC_name,1500,1,0,errbuf);

 

인자값 설명

1)char * device : cpNIC_name

– device 인자에 디바이스 이름(예, eth0, hme())을 지정

2)int snaplen : 1500세팅

- snaplen은 캡쳐할 크기

TCP TCP 헤더를 헤더를 캡쳐할 캡쳐할 경우경우 : : 이더넷 이더넷 헤더헤더+IP +IP 헤더헤더+TCP +TCP 헤더헤더

3)int promisc : 1세팅

– promisc

0 : 목적지가 자신인 패킷, 브로드캐스트 패킷, 멀티캐스트 패킷을 캡쳐

1 : promiscous 1 : promiscous 모드로 모드로 설정되어 설정되어 전송되는 전송되는 모든모든 패킷패킷((모든모든 이더넷 이더넷 프레임 프레임))

을 캡쳐

4)int to_ms : 0세팅

– to_ms는 ms 단위의 시간인데 네트워크 디바이스에 패킷이 도착했을

때때 커널이 커널이 이를이를 즉시즉시 읽지읽지 않고않고 잠시잠시 기다리는 기다리는 타임아웃 타임아웃 시간을 시간을 지정지정

커널이 한번의 읽기로 많은 패킷을 가져오게 한다

0이면 충분한 패킷이 도착할 때까지 대기한다.

5)char *ebuf : errbuf

– ebb fuf는는 에러발생시 에러발생시 에러에러 원인을 원인을 저장저장

– 성공하면 디바이스 디스크립터를 리턴하고, 실패하면 NULL을 리턴

네트워크 디바이스 닫기

pcap_close(stpNIC)

열었던 장치 eth0을 닫습니다

네트워크 정보 읽어오기

ucpData = pcap_next(stpNIC, &stInfo);

pcap pcap next() _next() 함수는 함수는 자동으로 자동으로 콜백콜백 함수를 함수를 호출하지않고 호출하지않고 캡쳐한 패킷 자체를 u_char 타입의 포인터로 리턴한다

이제 컴파일을 하겠습니다

gcc o test test.c MSDFunction.o lpcap

 

참고>>

-lpcap의 의미는

-l : 라이브러리를 추가시켜라 그건 pcap이야~~라는 의미입니다

BUT warning이 발생하였습니다!!!

clip_image003

헤더파일에 type이 일치하지 않는 것을 확인하기 위해

vi /usr/include/pcap/pcap.h를 해서 해더파일을 열었습니다

clip_image004

const가 있는 것을 확인 할 수 있습니다

다시 수정하고 실행하니 정상적으로 출력하였습니다

SUCCESS!!

자 이제 수업시간에 좀 해매었던 부분입니다

루트계정에서의 컨트롤

cd /home/ 계정확인

clip_image005

uec를 확인 하였습니다 이제 uec로 복사를 합니다

LINUX 명령어 복습

cp 대상파일 대상디렉토리

cp test / (test를 루트에 복사하라)

복사를 하고 루트로 이동후

su – uec합니다 그럼 $표시가 보이는 것을 확인 할 수 있습니다

sudo와 su의 차이

sudo를 사용하면 패스워드 노출을 막을수 있습니다.

sudo

root 권한을 필요로 하는 프로그램을 실행하였을 때, sudo 는 여러분의 일반 사용자 패스워드를 입력할 수 있도록 물어볼 것입니다. 이 것은 악의적인 프로그램이 시스템을 손상시킬 수 없도록 확인하고, 여러분이 주의가 필요한 관리적인 동작을수행하는 것에 대하여 상기하도록 도와 줍니다. 명령어 줄을 사용할 때 sudo 를 사용하려면, 실행할 명령어 앞에 "sudo" 라고 간단히 입력하십시오. sudo 는 여러분의 패스워드를 묻게 될 것입니다.

많은 사람들이 su가 ‘super user'를 의미하는 말로 생각하지만, 사실 ’substitute user'를 의미합니다 계정을 전환한다는 의미에 가깝습니다 uec계정으로 전환하면서 $로 전환된것을 확인 할 수 있습니다

ls –al

clip_image006

-rwx------일 경우 chmod 777 test로 속성값을 변경하여 줍니다

chmod 그것이 알고싶다!!!!

사용방법 chmod [옵션] 파일이름
7 rwx 읽기,쓰기,실행
5 r-x 읽기,실행
4 rw- 읽기,쓰기
3 -wx 쓰기,실행
2 -w- 쓰기
1 --x 실행
r (read :읽기) -파일내용을 볼 수 있음
w (write :쓰기) -파일을 변경 or 삭제할 수 있음
x (excute:실행) -파일을 프로그램으로 실행할 수 있음
권한을 부여할 때 '751'과 같이 8진수를 이용할 수 도 있는데 이 때 첫 번째 숫자인 7은 소유권자의 권한 두번째 숫자인 5는 사용자가 속한 그룹의 권한, 세 번째 숫자인 1은 다른 사용자에 대한 권한을 의미합니다. 'chmod 777 test'를 입력하면 사용자(소유자), 그룹, 다른 사용자에게 모두 읽기, 쓰기, 실행 권한을 주어집니다

실행결과

clip_image007

장비를 함부러 열수 없다 아뉘 에러~~!!!!우웩~~

$을 해제하고 싶을때는 ?

su – root

-lpcap없이 컴파일

clip_image008

의미 설명

gcc컴파일러가 컴파일시 tmp에 ccduVPov.o파일을 생성하면 컴파일을 하는데 해당.o파일에 pcap라이브러리가 정의되어 있지 않아서 나타나는 에러입니다 pcap자체가 기본적인 내장 라이브러리가 아닌 추가 라이브러리이기 때문에 lpcap로 알려주어야 합니다 ccduVPov.o임임의 파일이 이름이 각자 다른이름을 가지는 것은 멀티유저가 동시 컴파일시 구분을 할 수 없기 때문에 tmp에 임의적으로 파일을 생성하는 것입니다

password capture

ftp접속 => id : test / pass : ********()아직모름 => ./test 실행후 pass입력

 

결과확인

clip_image009

pass가 1234578로 확인 되었습니다

연속으로 실행해 보았습니다

clip_image010

 

위의 헥사뷰를 살펴 보겠습니다 제일윗줄을 보시면

clip_image011

HWaddr = machine address = mac address입니다

분석을 하면 아래 그림과 같습니다

clip_image013

clip_image015

'Network > Packet Analyzer' 카테고리의 다른 글

05. ARP header(수정중)  (0) 2011.10.06
04. IP header  (2) 2011.10.05
03. ethernet header 분석  (0) 2011.10.05
02. pcap 라이브러리  (0) 2011.10.05
01. Hexaview(수정중)  (0) 2011.10.05
00. Packet Analyzer  (0) 2011.10.05
Posted by mantwo

Hexaview

:파일의 내용을 16진수로 볼 수 있는 뷰어 입니다 패킷 분석기를 시작하기 전에 헥사뷰어가 준비 되어 있지 않다면 패킷의 내용을 볼 수가 없습니다

 

Hexaview.c와 Hexaview.h로 구성하면

main.c에서 #include 할 수 있도록 만들었습니다

 

원하는 데이터와 길이를 입력하여 볼 수 있도록 인자값을 넣었습니다

 

hexaview.c

#include "hexaview.h"

void hexaview(const void *vt, unsigned int size)
{
  const unsigned char * buffer = vt;
  unsigned int  i;
  unsigned int  j;
  printf("----------------------------------------------------------------------------\n");
  printf("Address     ");
  for(i=0; i<16; i++)
  {
    printf("0%X ", i);
  }
  for(i=0; i<16;i++)
  {
    printf("%X", i);
  }
  printf("\n");
  printf("----------------------------------------------------------------------------\n");
 

  for(i=0;i<(size*16);i=i+16) //line단위로 읽을
  {
    printf("0x%08X  ", i);
    for(j=0; j<16; j++)
    {
      printf("%02X ", *(buffer+i+j));
    }
    for(j=0; j<16; j++)
    {
      if(*(buffer+i+j) >= 0x21 && *(buffer+i+j) <= 0x7E)
      {
        printf("%c", *(buffer+i+j));
      }
      else printf(".");
    }
    printf("\n");
  }  return ;
}

결과보기

'Network > Packet Analyzer' 카테고리의 다른 글

05. ARP header(수정중)  (0) 2011.10.06
04. IP header  (2) 2011.10.05
03. ethernet header 분석  (0) 2011.10.05
02. pcap 라이브러리  (0) 2011.10.05
01. Hexaview(수정중)  (0) 2011.10.05
00. Packet Analyzer  (0) 2011.10.05
Posted by mantwo

Packet Analyzer 서론

Packet Analyzer란?

패킷 애널라이저(packet analyzer/network analyzer) 또는 패킷 스니퍼(packet sniffer/network sniffer)는 네트워크의 일부나 디지털 네트워크를 통하는 트래픽의 내용을 저장하거나 가로채는 컴퓨터 소프트웨어컴퓨터 하드웨어이다. 패킷 분석기, 프로토콜 분석기로도 불리며, 특정한 종류의 네트워크에서는 '이더넷 스니퍼'(ethernet sniffer) 또는 와이어리스 스니퍼(wireless sniffer)라고 불린다. 데이터 스트림은 네트워크를 통해 흐르며, 스니퍼는 각 패킷을 잡아 내서 디코딩하여, 적절한 RFC나 다른 규격에 따라 내용을 분석한다.

 

Network 용어정리


PROTOCOL

: 하나의 규약이며 강제성이 없다라는 의미인데

<컴퓨터> 컴퓨터컴퓨터 사이, 또는 다른 장치 사이에서 데이터원활히 주고받기 위하여 약속한 여러 가지 규약(規約). 규약에는 신호 송신순서,데이터표현법, 오류 검출 따위가 있다. [비슷한 말] 통신 규약.


시리얼통신

: 전기 통신전산학 분야에서 직렬 통신은 연속적으로 통신 채널이나 컴퓨터 버스를 거쳐 한 번에 하나의 비트 단위로 데이터를 전송하는 과정을 말한다. 이 용어는 여러 개의 병렬 채널을 갖춘 링크 위에서 동시에 여러 개의 비트로 보내는 병렬 통신과 대조된다.

twi방식 : 시리얼 한선에 여러비트 전송

spi방식(직렬) : 여러선에 대량의 비트 전송

tail head

네트워크 프로토콜

LAN(local area network) => 데이터를 공유하기 위한 일종의 망

 

Packet Analyzer의 기본은 패킷을 건져올리는(캡쳐) 것입니다 그 첫번째 작업으로 pcap함수의 사용이 아주 중요합니다

Pcap : packet capture 패킷을 캡쳐하여 안에 내용을 확인 할 수 있는 라이브러리 입니다

 

man pcap의 내용

 

여기서 변수 errbuf를 선언하고

pcap_lookupdev를 사용해보도록 하겠습니다

컴파일을 해보도록 하겠습니다

gcc –o test.exe test.c MSDFunction.o –lpcap

./test.exe

eth0가 errbuf에 담겨 있는 것을 확인 할 수 있습니다

eth0는 Device Name을 뜻합니다

'Network > Packet Analyzer' 카테고리의 다른 글

05. ARP header(수정중)  (0) 2011.10.06
04. IP header  (2) 2011.10.05
03. ethernet header 분석  (0) 2011.10.05
02. pcap 라이브러리  (0) 2011.10.05
01. Hexaview(수정중)  (0) 2011.10.05
00. Packet Analyzer  (0) 2011.10.05
Posted by mantwo

멀티플렉싱(multiplexing)>>> 통신분야에서는 (다중화기)

: 지금까지 작성했던 프로그램들은 모두 하나의 단일 채널에서 일어는 입/출력만을 다루었습니다 즉 이전의 모든 버전의 에코 서버는 한번에 하나의 클라이언트 연결만을 처리 하였습니다 하지만 응용프로그램은 여러 채널의 입/출력을 동시에 처리하는 능력을 요구할 때가 자주 있습니다. 예를 들어 동시에 여러 포트를 열어서 에코서버를 할때 서버가 각 소켓을 생성하고 이를 각 포트에 바인딩 한 후 무슨 일이 일어날까를 생각해 봅시다. 기존방식에는 문제점이 발견되는데 서버는 연결을 accept할 준비가 되어있습니다 하지만 어떤 소켓을 선택해야 할지 선택을 하지 못합니다. 아무 서버나 연결하게 된다면 기존의 대기하고 있는 소켓역시 대기가 되어버리는 불편한 상황이 발생합니다. 물론 이러한 문제는 non-bloaking소켓을 이용하여 해결이 가능하지만 그것보다는 특정 소켓의 입/출력이 준비가 될때까지 서버를 bloacking을 하는 것이 좋습니다

 

하지만 단점도 있습니다 정리하자면

: 프로세스 생성에 많은 양의 연산, 메모리 공간 요구. IPC (inner process communcation) 방법도 복잡합니다

 


이런한 일련의 과정들은 가능하게 하는 것이
linux상에서 다시 말하면 unix상에서 제공해주는 select를 사용하면 됩니다 select는 입/출력이 예상되는 소켓의 식별자를 리스트로 명시하고 리스트의 식별자중 준비되어진 식별자를 준비가 되었는지를 반환하여 알리고 blocking이 되지 않을 것이라는 것을 확신하고 진행하게 됩니다

 

 

전반적인 순서는 아래와 같습니다

- 하나의 서버에 여러개의 클라이언트 제어
-
서비스 품질은 멀티프로세스보다 더 떨어지는것 같아보입니다
-
실질적으로 서버와 클라이언트의 통신에서 데이타 송수신은 매우 작다
-
그렇기 때문에 많은 클라이언트에게 서비스 할 수 있습니다.

- 하나의 프로세스가 해당 클라이언트n개 즉...파일 디스크립터를 묶어서
-
관리를 합니다
  
※ 즉 fd_set으로 묶어서 파일 디스크립터정보를 담습니다

 





select()함수>>>
select
함수를 사용하기 위해서 간단한 순서를 확인해보자

참고>>그림


----- select 함수 사용 순서 -------

1. 디스크립터 설정

2. 검사 범위 설정

3. 타임 아웃 설정

4. select 함수 호출

5. 결과 확인

------------------------------

 

 
 

1. 디스크립터 설정


1)
파일 디스크립트 설정

 

fd_set 수형;

0

1

0

1

.........

fd0  fd1  fd2  fd3

 

fd0 : stdin    fd1 : stdout    fd2 : stderr    fd3 : socket

 

변화를 확인할 파일 디스크립터들을 한 묶음으로 모아둔다

 

fd_set 자료형 관련함수

  FD_ZERO(fd_set * fdset);        //fd_set 초기화 함수

  FD_SET(int fd, fd_set * fdset);   //해당 파일디스크립터  fd  1로 셋

  FD_CLR(int fd, fd_set * fdset);   //해당 파일디스크립터  fd  0으로 셋

  FD_ISSET(int fd, fd_set * fdset);  //해당 파일디스크립터  fd  1인지 확인

 

사용방법 예제


2)
검사할 파일 디스크립터의 범위 지정

 - 검사해야할 파일 디스크립터의 개수를 전달

 - 가장 큰 파일 디스크립터 값에 1을 더함(파일 디스크립터 값이 0부터 시작하므로)

 

3)타임 아웃 설정

 - select함수가 blocking 되는 것을 피하기 위해 타임 아웃을 설정함

 

2. select함수 호출

 
헤더파일

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>


원형

int select(int n fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

                                                                                                  리턴값 : 성공시 0  이상... 오류 발생시 -1 리턴
                                                                                 0을 리턴하는 경우에는 타임아웃에 의해 리턴되었음을 의미
                                                                                 0 보다 큰경우는 변경된 파일 디스크립터의 수를 의미한다. 

인자 값 분석>>


n :
검색 대상이 되는 파일 디스크립터의 수

 

readfds : "입력스트림에 변화가 발생했는지" 확인하고자 하는 소켓들의 정보를 전달합니다. 여기서 입력 스트림에 변화가 발생했다는 것은 수신할 데이터가 있다는 뜻

 

writefds : "데이터 전송 시, 블로킹되지 않고 바로 전송이 가능한지" 확인하고자 하는 소켓들의 정보를 전달
 

excepfds : "예외가 발생했는지" 확인하고자 하는 소켓들의 정보를 전달
 

timeout : 함수 호출 후, 무한 대기 상태에 빠지지 않도록 타임-아웃(time-out)을 설정하기 위해 인자를 전달

 

예제>>

select(1,&reads,0,0,5)

<감지>5초동안 감지 수신에 변화가 없는지 감지하고 나와라 리턴값 = 1-

검사 디스크립트 수는 1


위 예제의 select같이 동작하는 프로그램을 작성합니다
 

select.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>

#define BUFSIZE 30

int main(int argc, char *argv[])
{
  fd_set reads, temps;
  int result;

  char message[BUFSIZE];
  int str_len;
  struct timeval timeout;

  FD_ZERO(&reads); //0
으로 초기화
  FD_SET(0,&reads); //
파일 디스크립터 0(stdin) 설정

  /*
  timeout.tv_sec 
= 5;
  timeout.tv_usec 
= 100000;
  */
  //
잘못된 timeout 설정(구조체 내에서만 업데이트된다)
  
  while(1)
  {
    temps = reads;
    
    timeout.tv_sec = 5//
실행후 다시 재설정해야한다
    timeout.tv_usec = 0;
    
    result = select(1&temps, 00&timeout);
    if(result == -1)
    {
      puts("select(): 
오류발생");
      exit(1);
    }
    else if(result == 0)
    {
      puts("select():
시간이 초과 되었습니다. ");
    }
    else
    {
      if(FD_ISSET(0,&temps))
      {
        str_len = read(0, message, BUFSIZE);
        message[str_len] = 0;
        fputs(message, stdout);
      }
    }
  }
  return 0;
}

 

결과>> 5초간 입력이 없을 경우 시간이 초과되었다는 경고 메시지가 출력됩니다

 

분석해보기>>
 
1)FD_ZERO(&reads); //0으로 초기화
    FD_SET(0,&reads); //
파일 디스크립터 0(stdin) 설정

1

0

0

0

.........

 

마지막 파일 디스크립터에 +1되게 되어있다?

 

1

0

0

1

.........

 

result = select(1&temps, 00&timeout);

수신데이터가 있는지 확인합니다 <5초설정>

확인할 파일디스크립트는 1개입니다

입력이 되었다면 result = 1



2)else
 if(result == 0) 5
초간 아무 변화가 없을때

 

0

0

0

0

.........


3)temps 
= reads;
원본값으로 초기화 시켜주질 않을 경우

 while문을 한바퀴 돌고나면

1

0

0

0

.........

에서

0

0

0

0

.........

으로 변화되고 이후로는 계속 0인 상태가 됩니다

 

select사용시에는 원본을 저장 할 수 있는 변수를 써야 합니다


3. 결과 확인


참고>>
select()함수의 인자를 보면 이 중 n은 검사가 필요없는 가장 작은 식별자값으로써 최대 식별자  값보다 1이 작다 위에서 보면 소켓셋에 담을 수 있는 소켓 디스크립터의 최대갯수는 시스템 정의 상수인 FD_SETSIZE로 정의 되어 있지만 그 수가 상당히 크므로 매번 그 크기만큼 검사하면 비효율적이므로 이를 효율적으로 검사하기 위해서 정수 n을 전달하여 그 크기+1까지만 검사한다

 그 다음에는 각 소켓셋(읽기셋, 쓰기셋, 예외셋)이 파라미터로 들어가며 만약 NULL이 들어가면 그 소켓셋은 대상 리스트에 대한 입/출력 감시를 하지 않는다
 마지막 파라미터인 timeout은 NULL로 설정하면 읽기셋, 쓰기셋, 예외셋에 삽입한 소켓 중에 변화가 생길 때까지 대기하고 있다가 변화가 발생한 소켓의 수를 리턴하게 된다.

timeout을 양수로 설정한 경우에는 변화가 발생한 소켓이 생길 때까지 대기하고 있다가 설정한 시간이 되면 변화가 발생한 소켓이 없더라도 대기상태를 해제하게 된다.


 이때 변화가 발생한 소켓이 없다면 0을 리턴하게 된다. 그리고 timeout 값이 0으로 설정되면 대기시간 없이 바로 리턴하게 된다


Posted by mantwo