블로그 이미지
랜달프

calendar

1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

Notice

    'Programming/C programming'에 해당되는 글 9

    1. 2009.05.29 Singleton Class Pattern (싱글톤)
    2. 2009.03.18 타임서버에서 시간 가져오기
    3. 2009.03.18 RFC 868 (Time Protocol)
    4. 2009.01.07 C 문자열 함수 정리
    5. 2008.04.06 winpcap
    6. 2008.04.06 winpcap/pcap.h 함수 분석
    7. 2008.04.06 각종 Header 정보
    8. 2007.12.04 파일열기 함수 fopen()의 모드
    9. 2007.12.03 달팽이 배열 알고리즘
    2009. 5. 29. 13:32 Programming/C programming
    class CSingleton
    {
    public:
    	CSingleton();
    	static CSingleton* GetInstance();
    private:
    	static CSingleton* m_instance;
    
    };
    
    CSingleton* CSingleton::m_instance = 0;
    
    CSingleton::CSingleton()
    {
    
    }
    CSingleton::GetInstance()
    {
    
    	if( 0 == m_instance )
    	{
    		m_instance = new CSingleton;
    	}
    
    	return m_instance;
    
    }
    
    posted by 랜달프
    2009. 3. 18. 19:20 Programming/C programming

    우리가 흔히 리눅스에서

    rdate -s time.bora.net

    이라는 명령어로 시간을 맞춘다

    즉,     time.bora.net   이라는 타임 서버에서 프로토콜에 맞춰 값을 가져온 후 시스템에 적용 하는 것이다.
    다음은 RFC 868 문서를 보고 만든 것인데 time.bora.net 서버에서 시간을 가져와 출력하는 코드이다.
    #ifdef _WIN32
    #include 
    #else
    #include 
    #include 
    #include 
    #include 
    #endif
    
    #include 
    #include 
    
    
    std::time_t getTime()
    {
    #ifdef _WIN32
    	WSADATA wsaData;
    #endif
    
    	int hSocket;
    	sockaddr_in servAddr;
    	std::time_t	sBuffer;
    	struct hostent* s_HostEntry;    
    	int strLen;
    	
    #ifdef _WIN32
    	if( WSAStartup(MAKEWORD(1,1),&wsaData) != 0 )
    	{
    		std::cout << "Startup Error" << std::endl;
    		return -1;
    	}
    #endif
    
    	hSocket = socket(PF_INET, SOCK_STREAM, 0);
    	
    	if( -1 == hSocket )
    	{
    		std::cout << "Socket Create Error" << std::endl;
    		return -1;
    	}
    
    	memset(&servAddr, 0, sizeof(servAddr));
    	servAddr.sin_family = AF_INET;
    	servAddr.sin_port = htons(37);
    
    	s_HostEntry = gethostbyname("time.bora.net");
    	memcpy((void *)(&servAddr.sin_addr), (void *)(s_HostEntry->h_addr), sizeof(servAddr.sin_addr));
    
    	if ( -1 == connect(hSocket, (sockaddr*)&servAddr, sizeof(servAddr)) )
    	{
    		return -1;
    	}
    
    	strLen = recv(hSocket, (char*)&sBuffer, sizeof(sBuffer), 0);
    	
    
    	if( -1 == strLen )
    	{
    		return -1;
    	}
    
    	sBuffer = ntohl(sBuffer) - 2208988800l;
    
    #ifdef _WIN32
    	closesocket(hSocket);
    	WSACleanup();
    #else
    	close(hSocket);
    #endif
    
    	return sBuffer;
    }
    
    int main()
    {
    	std::time_t currentTime;
    	std::tm* ts;
    	char str_time[80];
    
    	currentTime = getTime();
    	ts = localtime(¤tTime);      // 시스템에 적용된 시간대로 tm 구조체에 저장  (대한민국 표준시 GMT +09:00 )
    	//ts = gmtime(¤tTime);     // GMT  
    
    	strftime(str_time, 80, "%Y년 %m월 %d일 %H:%M:%S  %Z", ts);  // tm 구조체를 문자열로 저장
    
    	std::cout << str_time << std::endl;
    	
    	return 0;
    }
    
    struct tm 구조체
    #include 
    struct tm {
    
    	int tm_sec;   /* 초 */
    	int tm_min;   /* 분 */
    	int tm_hour;  /* 시 (0--23) */
    	int tm_mday;  /* 일 (1--31) */
    	int tm_mon;   /* 월 (0--11) */
    	int tm_year;  /* 년 (+ 1900) */
    	int tm_wday;  /* 요일 (0--6; 일요일 = 0) */
    	int tm_yday;  /* 올해 몇번째 날 (0--365) */
    	int tm_isdst; /* 서머타임 여부 */
    
    };
    

    실행 화면

    posted by 랜달프
    2009. 3. 18. 19:09 Programming/C programming


    RFC 868

    Network Working Group
    Request for Comments: 868

    J. Postel - ISI
    K. Harrenstien - SRI
    May 1983


    Time Protocol

    This RFC specifies a standard for the ARPA Internet community. Hosts on the ARPA Internet that choose to implement a Time Protocol are expected to adopt and implement this standard.
    This protocol provides a site-independent, machine readable date and time. The Time service sends back to the originating source the time in seconds since midnight on January first 1900.
    One motivation arises from the fact that not all systems have a date/time clock, and all are subject to occasional human or machine error. The use of time-servers makes it possible to quickly confirm or correct a system's idea of the time, by making a brief poll of several independent sites on the network.
    This protocol may be used either above the Transmission Control Protocol (TCP) or above the User Datagram Protocol (UDP).
    When used via TCP the time service works as follows:


    S: Listen on port 37 (45 octal).
    U: Connect to port 37.
    S: Send the time as a 32 bit binary number.
    U: Receive the time.
    U: Close the connection.
    S: Close the connection.


    The server listens for a connection on port 37. When the connection is established, the server returns a 32-bit time value and closes the connection. If the server is unable to determine the time at its site, it should either refuse the connection or close it without sending anything.

    When used via UDP the time service works as follows:


    S: Listen on port 37 (45 octal).
    U: Send an empty datagram to port 37.
    S: Receive the empty datagram.
    S: Send a datagram containing the time as a 32 bit binary number.
    U: Receive the time datagram.


    The server listens for a datagram on port 37. When a datagram arrives, the server returns a datagram containing the 32-bit time value. If the server is unable to determine the time at its site, it should discard the arriving datagram and make no reply.

    The Time

    The time is the number of seconds since 00:00 (midnight) 1 January 1900 GMT, such that the time 1 is 12:00:01 am on 1 January 1900 GMT; this base will serve until the year 2036.

    For example:

    the time

    2,208,988,800 corresponds to 00:00 1 Jan 1970 GMT,

    2,398,291,200 corresponds to 00:00 1 Jan 1976 GMT,

    2,524,521,600 corresponds to 00:00 1 Jan 1980 GMT,
     
    2,629,584,000 corresponds to 00:00 1 May 1983 GMT,

    and

    -1,297,728,000 corresponds to 00:00 17 Nov 1858 GMT.

    posted by 랜달프
    2009. 1. 7. 14:04 Programming/C programming

    1. stpcpy
    원형 : char *stpcpy( char *dest, char *src );
    헤더 : string.h
    기능 : 문자열 src를 문자배열 dest로 복사한다. dest 의 길이가 src 보다 작은 경우 dest 뒤의 인접 데이터가 파괴된다.
    리턴 : dest + strlen(src)의 번지를 리턴

    2. strcat
    원형 : char *strcat( char *dest, const char *src );
    헤더 : string.h
    기능 : 문자열끼리 연결한다. dest의 널문자 위치에 src가 붙는다. dest의 길이가 ( dest 문자열 + src 문자열 ) 길이보다 작을 경우 인접 데이터가 파괴된다.
    리턴 : dest의 번지가 리턴

    3. strchr
    원형 : char *strchr( const *src, int c );
    헤더 : string.h
    기능 : 문자열 배열 src 내에 문자 c가 있는지 검사하고 있을 경우 문자 c가 있는 번지를 리턴. 널문자도 문자로 취급하기 때문에 널문자를 넣으면 첫번째 널문자의 번지를 리턴한다.
    리턴 : 문자열 src내에서 발견된 문자 c의 포인터. 발견되지 않을 경우 NULL 리턴

    4. strcmp
    원형 : int strcmp( const char *src1, const char *src2 );
    헤더 : string.h
    기능 : 두 개의 문자열을 대소 비교함. 이 함수를 사용하여 두 개의 문자열이 같은 문자열인지 아닌지를 비교할 수 있다. 같을 경우 0, 다를 경우 양수나 음수의 값을 리턴.
    리턴 : src1 < src2  인 경우 음수 리턴
             src1 = src2  인 경우 0 리턴
             src1 > src2  인 경우 양수 리턴

    5. strcmpi
    원형 : int strcmpi( const char *src1, const char *src2 );
    헤더 : string.h
    기능 : 두 개의 문자열을 대소 비교함. 하지만 대소문자를 구분하지 않는다. 이 함수를 사용하여 두 개의 문자열이 같은 문자열인지 아닌지를 비교할 수 있다. 같을 경우 0, 다를 경우 양수나 음수의 값을 리턴.
    리턴 : src1 < src2  인 경우 음수 리턴
             src1 = src2  인 경우 0 리턴
             src1 > src2  인 경우 양수 리턴

    6. strcoll
    원형 : int strcoll( char *src1, char *src2 );
    헤더 : string.h
    기능 : setlocale 함수에 의해 지정된 비교방식에 따라 두 개의 문자열을 비교
    리턴 : src1 < src2  인 경우 음수 리턴
             src1 = src2  인 경우 0 리턴
             src1 > src2  인 경우 양수 리턴

    7. strcpy
    원형 : char *strcpy( char *dest, const char *src );
    헤더 : string.h
    기능 : 문자열 src를 문자배열 dest로 복사한다. dest 의 길이가 src 보다 작은 경우 dest 뒤의 인접 데이터가 파괴된다.
    리턴 : dest의 번지가 리턴

    8. strcspn
    원형 : size_t strcspn( const char *src1, const char *src2 );
    헤더 : string.h
    기능 : 문자열 src1 중에 문자열 src2에 들어 있지 않은 문자들이 연속해 있는 길이를 구한다. 문자열 s2에 없는 문자들로 구성되어 있는 문자열 s1 내의 세그먼트를 찾아내고 그 세그먼트의 길이를 리턴.
    예를 들어 src1 = "123456" 이고 src2 = "0486" 이라면 src1 내에서 src2 의 문자인 4가 나오기 전까지의 길이인 3을 리턴한다.
    리턴 : 찾아낸 세그먼트의 길이.  만약 0을 리턴한다면 세그먼트가 발견되지 않은 것이다.

    9. strdup
    원형 : char *strdup( const char *src );
    헤더 : string.h
    기능 : 새로운 메모리를 할당하고 문자열 src를 복사한 후 그 포인터를 리턴한다. 종료 시 반드시 복제된 문자열은 메모리를 해제해 주어야 한다.
    리턴 : 복제된 문자열의 포인터를 리턴. 메모리 할당에 실패한 경우 NULL을 리턴.

    10. _strerror
    원형 : char *_strerror( const char *src );
    헤더 : string.h, stdio.h
    기능 : 사용자가 정의하는 에러 메시지를 만든다. src가 NULL일 경우 최근 발생한 에러 메시지만으로 구성된 문자열을 만들고 src가 NULL이 아닌 경우 에러메시지 형식의 문자열을 만든다.
    만약 src 가 "babo" 이면 babo : 최근 에러 메시지 같은 형식으로 문자열을 만든다.
    리턴 : 만들어진 에러 문자열의 포인터를 리턴한다.

    11. strerror
    원형 : char *strerror( int errnum );
    헤더 : stdio.h
    기능 : errnum에 해당하는 에러메시지 문자열을 만든다. 에러메시지 문자열은 모두 \n으로 끝나므로 개행 문자를 첨가해 줄 필요는 없다.( 에러 메시지는 이미 정의되어 있으므로 궁금하면 출력시켜보자)
    리턴 : 에러메시지 문자열의 포인터

    12. stricmp
    원형 : int stricmp( const char *src1, const char *src2 );
    헤더 : string.h
    기능 : 두 개의 문자열을 대소 비교함. 하지만 대소문자를 구분하지 않는다. 이 함수를 사용하여 두 개의 문자열이 같은 문자열인지 아닌지를 비교할 수 있다. 같을 경우 0, 다를 경우 양수나 음수의 값을 리턴. 이 함수를 매크로로 정의해 둔 함수가 strcmpi 이다.
    리턴 : src1 < src2  인 경우 음수 리턴
             src1 = src2  인 경우 0 리턴
             src1 > src2  인 경우 양수 리턴

    13. strlen
    원형 : size_t strlen( const char *src );
    헤더 : string.h
    기능 : 문자열 src 의 길이를 계산한다. 널문자는 길이에 포함되지 않고 널문자 앞에 까지 문자 개수를 리턴한다.
    리턴 : 문자열의 길이

    14. strlwr
    원형 : char *strlwr(char *src);
    헤더 : string.h
    기능 : 문자열 src 내의 대문자(A~Z)를 소문자(a~z)로 변경한다. 영문자 외의 다른 문자는 변경하지 않는다.
    리턴 : 인수로 주어진 src를 그대로 리턴

    15. strncat
    원형 : char *strncat( char *dest, const char *src, size_t maxlen );
    헤더 : string.h
    기능 : dest 의 널문자에 src의 문자열을 붙이는데 maxlen 길이 만큼만 붙인다.
    리턴 : dest의 번지를 리턴

    16. strncmp
    원형 : int strncmp( const char *src1, const char *src2, size_t maxlen );
    헤더 : string.h
    기능 : 두 개의 문자열을 대소 비교한다. 비교시 대소문자를 구분한다. 하지만 문자열 전체를 비교하는 것이 아니라 maxlen 길이 만큼만 비교한다.
    리턴 : src1 < src2  인 경우 음수 리턴
             src1 = src2  인 경우 0 리턴
             src1 > src2  인 경우 양수 리턴

    17. strncmpi
    원형 : int strncmpi( const char *src1, const char *src2, size_t maxlen );
    헤더 : string.h
    기능 : 두 개의 문자열을 대소 비교한다. 비교시 대소문자를 구분하지 않는다. 하지만 문자열 전체를 비교하는 것이 아니라 maxlen 길이 만큼만 비교한다.
    리턴 : src1 < src2  인 경우 음수 리턴
             src1 = src2  인 경우 0 리턴
             src1 > src2  인 경우 양수 리턴

    18. strncpy
    원형 : char *strncpy( char *dest, char *src, size_t maxlen );
    헤더 : string.h
    기능 : 문자열을 정해진 길이만큼 복사한다. 길이만큼만 복사하기 때문에 dest의 뒤에 널문자가 붙지 않는다.
    리턴 : dest의 번지를 리턴

    19. strnicmp
    원형 : int strnicmp( const char *src1, const char *src2, size_t maxlen );
    헤더 : string.h
    기능 : 두 개의 문자열을 대소 비교한다. 비교시 대소문자를 구분하지 않는다. 하지만 문자열 전체를 비교하는 것이 아니라 maxlen 길이 만큼만 비교한다. 이 함수의 매크로 버젼이 strncmpi 이다.
    리턴 : src1 < src2  인 경우 음수 리턴
             src1 = src2  인 경우 0 리턴
             src1 > src2  인 경우 양수 리턴

    20. strset
    원형 : char *strset( char *src, int c );
    헤더 : string.h
    기능 : 문자열을 특정 문자로 채운다. 문자열 중 널문자가 발견될 때가지 문자 c 로 채운다.
    리턴 : src의 번지를 리턴

    21. strpbrk
    원형 : char *strpbrk( const char *src1, const char *src2 );
    헤더 : string.h
    기능 : 문자열 src1 내에 문자열 src2에 있는 문자 중의 하나라도 있는지 검사하고 있을 경우 그 포인터를 리턴.
    리턴 : 문자열 src1 내에 문자열 src2에 있는 문자 중 하나가 발견된 포인터를 리턴. 없을 경우 널을 리턴

    22. strrchr
    원형 : char *strrchr( const cjar *src, int c );
    헤더 : string.h
    기능 : 문자 배열 src내에 문자 c가 있는지 검사하고 있을 경우 문자 c가 있는 번지를 리턴한다. 하지만 앞에서 부터 검사하는 것이 아니라 뒤에서 부터 검사를 진행한다.
    리턴 : 문자열 src에서 발견된 문자 c의 포인터를 리턴. 발견되지 않을 경우 널을 리턴.

    23. strrev
    원형 : char *strrev( char *src );
    헤더 : string.h
    기능 : 문자열의 순서를 바꾼다. 즉 제일 앞에 있는 문자가 제일 뒤로 가고 제일 뒤의 문자가 제일 처음으로 옮겨진다. 널문자는 이동 없음.
    리턴 : 역순으로 바꾼 문자열의 src번지

    24. strspn
    원형 : size_t strspn( const char *src1, const char *src2 );
    헤더 : string.h
    기능 : 문자열 src1 중에서 문자열 src2에 있는 문자들이 연속해 있는 길이를 구한다.
    예를 들어 src1 = "12345678" 이고 src2 = "143290" 이라면 src1에서 src2의 문자들을 찾아보면 1234가 있다. 이 문자열의 길이 4를 리턴한다.
    리턴 : 찾아낸 세그먼트의 길이를 리턴. 만약 0을 리턴하면 세그먼트를 찾지 못한 것이다.

    25. strstr
    원형 : char *strstr( const char *src1, const char *src2 );
    헤더 : string.h
    기능 : 문자열 src1내에서 문자열 src2가 포함되어 있는지 검사하고 있다면 src2와 같은 문자열이 있는 부분을 리턴한다.
    리턴 : 부분문자열의 선두 번지. 없다면 널을 리턴 

    26. strtod
    원형 : double strtod( const char *src1, char **endptr );
    헤더 : stdlib.h
    기능 : 문자열을 double 형 부동 소수점으로 바꾼다. 문자열은 다음과 같은 구조로 이루어져야 한다.
    [공백,탭][부호][숫자][소수점][e]  -> ex) -5.64e+5, -3.6924
    순서를 어기거나 불필요한 문자가 중간에 있을 경우는 변환이 중지.
    endptr 인수는 변환이 중지될 경우 중지된 문자를 가리키므로 에러 검색에 사용
    리턴 : 변환된 double 형 실수를 리턴. overflow 발생시 HUGE_VAL을 리턴

    27. strtok
    원형 : char *strtok( char *src1, char *src2 );
    헤더 : string.h
    기능 : 문자열에서 token을 찾아낸다. ( token 이란 특정한 구분자로 분리되는 문장 구성 요소이다. 구분자가
    "/"라 할때 다음 문자열은 1994와 Feb와 20의 세 개의 token 으로 분리된다. "1994/Feb/20" )
    문자열 src1이 token을 찾아낼 문자열이며 src2가 token 구분자가 들어있는 문자열이다. token 구분자는 여러개가 복수 개 지정될 수 있으며 token 구분자는 strtok 호출 시 마다 바뀔 수 있다.
    리턴 : 찾아낸 token의 포인터를 리턴. token이 더 이상 없을 경우 널 리턴.
    ( 이해가 안가는 분은 winapi에서 예제를 참고)

    28. strtol
    원형 : long strtol( const char *src1, char **endptr, int radix );
    헤더 : stdlib.h
    기능 : 문자열을 long 형 정수로 변환한다.문자열 src1은 다음과 같은 구조로 이루어져야 한다.
    [공백, 탭][부호][숫자]
    만약 이 순서를 어기거나 불필요한 문자가 문자열 내에 있을 경우 변환은 중지되고 중지된 위치가 endptr에 설정된다. endptr은 에러 검색에 사용하면 용이. 그리고 radix은 문자열을 해석할 진법을 지정할 때 사용되는데 범위는 2~36 까지 이고 그 진법에서 사용되는 문자만 인식
    리턴 : 변환된 long 형 정수를 리턴. 변환이 불가능할 경우 0을 리턴

    29. strtoul
    원형 : unsigned long strtoul(const char *src1, char **endptr, int radix );
    헤더 : string.h
    기능 : 문자열을 부호없는 long 형 정수로 바꾼다. 사용법은 strtol 과 동일.
    리턴 : 변환된 unsigned long 형 정수를 리턴. 변환이 불가능할 경우 0을 리턴

    30. strupr
    원형 : char *strupr( char *src );
    헤더 : string.h
    기능 : 문자열 src내의 소문자 (a~z)를 대문자( A~Z)로 변환한다. 영문자 외의 다른 문자는 변경하지 않는다.
    리턴 : src의 번지를 리턴

    참고 사이트
    www.winapi.co.kr
    http://cafe.naver.com/storygp/34

     

    posted by 랜달프
    2008. 4. 6. 16:18 Programming/C programming

    http://www.winpcap.org/docs/docs_40_2/html/group__wpcap__tut3.html

     

    참고로 아래는 공부하려고 정리한 것을 올려놨기 때문에 많은 부분이 틀렸을수도있다.

    아직 내가 이쪽의 전문가도 아니고 공부하는 입장이기 때문에 혹 참조하시는 분들은 참조만할뿐 맹목적으로 믿지는 않았으면 좋겠다. 직접코드를 쳐보고 구현해보자.

     

    Opening an adapter and capturing the packets

    adapter를 열고 그리고 패킷 캡쳐하기

    Now that we've seen how to obtain an adapter to play with, let's start the real job, opening an adapter and capturing some traffic. In this lesson we'll write a program that prints some information about each packet flowing through the adapter.

    The function that opens a capture device is pcap_open(). The parameters, snaplen, flags and to_ms deserve some explanation.

     

    지금까지 우리는 작동하는 adapter를 얻는 방법에 대해 알아 보았다. 이제 실제 adapter을 열고 그리고 약간의 트래픽을 캡쳐하는 작업을 시작해보자.

    이번 장에서는 우리는 adapter를 따라 흐르는 각각의 패킷에 대한 몇몇 정보를 출력해주는 프로그램에 대해서 기술할 것이다.

    capture device를 여는 함수는 pcap_open()함수이다. 이함수의 파라미터 snaplen, flags and to_ms 는 약간의 설명을 할 필요가 있다.

     

    * 참고

    pcap_t* pcap_open ( const char * source,

    int snaplen,

    int flags,

    int read_timeout,

    struct pcap_rmtauth * auth,

    char * errbuf

    )

     

    snaplen specifies the portion of the packet to capture. On some OSes (like xBSD and Win32), the packet driver can be configured to capture only the initial part of any packet: this decreases the amount of data to copy to the application and therefore improves the efficiency of the capture. In this case we use the value 65536 which is higher than the greatest MTU that we could encounter. In this manner we ensure that the application will always receive the whole packet.

     

    snaplen 는 캡쳐하기위한 패킷의 비율(몫)을 명세하고 있다. OSes(xBSD and Win32와 같이)상에서, packet driver는 단지 어떤 패킷의 처음 부분만을 캡쳐하기 위해 구성되어질수 있다.

    즉 packet driver는 application로부터 데이터를 복사하는 양을 줄인다. 그리고 그러한 까닭에 캡쳐의 효율성은 개선된다. 이러한 경우 우리가 직면할수 있는 가장 큰 MTU의 값보다 큰 65536 값을 사용한다. 말하자면 우리는 그 application은 항상 모든(전체)패킷을 받을수있다는 것을 보장한다.

     

    * 패킷에 도착해서 그 패킷을 담을 버퍼의 크기를 정하는 것은 snaplen 변수인데 만약 너무작게하면 패킷의 일부분만을(즉 패킷의 처음부부만) 버퍼에 담게 되어서 나머지 부분은 담을 수없게된다. 그래서 이런 현상을 막기위해 MTU 즉 최대전송단위의 값보다 큰 65536의 값을 설정하게 해주면 application은 패킷 손실없이 모든 패킷을 받을 수있다는 말이다.

     

    * 참고

    MTU (Maximum Transmission Unit) ; 최대 전송 단위

     

    flags: the most important flag is the one that indicates if the adapter will be put in promiscuous mode. In normal operation, an adapter only captures packets from the network that are destined to it; the packets exchanged by other hosts are therefore ignored. Instead, when the adapter is in promiscuous mode it captures all packets whether they are destined to it or not. This means that on shared media (like non-switched Ethernet), WinPcap will be able to capture the packets of other hosts. Promiscuous mode is the default for most capture applications, so we enable it in the following example.

     

    이거 이해 안돼서 꽤걸림~~ 맞는건지 정확한지는 모르겠음 실험을 안해봐서 ㅋ ㅋ ㅋ

     

    플래그: 가장 중요한 플래그는 adapter가 promiscuous mode 설정되어있는지 아닌지 보여주는 것이다. 보통의 경우 단지 adapter는 adapter로 예정되어 있는 패킷을 네트워크로부터 캡쳐한다. 즉 다른 호스트에서 교환되어지는 패킷은 그런 까닭에 무시된다. 대신에 adapter가 promiscuous mode있을 때에는 adapter는 패킷이 자신에게 오는 패킷이던지 혹은 그렇지 않던간에 모든 패킷을 캡쳐한다.(좀 의역했음)

    이것은 shared media (like non-switched Ethernet)에서 winpcap은 다른 호스트에 패킷도 캡쳐할수 있다. Promiscuous mode는 대부분의 캡쳐 어플리케이션에서 디폴트이다. 그래서 우리는 아래에 예제에서 그것을 실행했다.

     

    * 추가 설명

    A ------ B -----C

    만약 B에서 패킷캡쳐를 한다고 가정했을 때 일반 캡쳐는 A가 C로 패킷을 보낸 경우 자신의 네트워크를 따라서 이동하지만 자신의 adapter로 오는 패킷이 아니기 때문에 패킷캡쳐를 실행하지 않는다. 하지만 그렇지 않는 경우 즉 promiscuous mode로 설정되어있는 경우에는 자신을 걸치는 모든 패킷을 캡쳐한다는 내용이다. (제생각은 이런데 님생각은?)

     

     

    to_ms specifies the read timeout, in milliseconds. A read on the adapter (for example, with pcap_dispatch() or pcap_next_ex()) will always return after to_ms milliseconds, even if no packets are available from the network. to_ms also defines the interval between statistical reports if the adapter is in statistical mode (see the lesson "\ref wpcap_tut9" for information about statistical mode). Setting to_ms to 0 means no timeout, a read on the adapter never returns if no packets arrive. A -1 timeout on the other side causes a read on the adapter to always return immediately.

     

    to_ms 는 read timeout(밀리세컨드)를 명시한다. 설령 네트워크로부터 사용할수 있는 패킷이 존재 하지 않을때에도 pcap_dispatch() or pcap_next_ex() 함수로 adapter를 읽을 때에는 항상 to_ms milliseconds, 후에 리턴한다. to_ms는 또한 만약 adapter가 statistical mode에 있다면 statical report 사이의 간격을 정의한다.

    ("\ref wpcap_tut9" lesson 편에 statistical mode에 관한 정보를 볼 수 있다.)

    to_ms를 0으로 세팅한다는 의미는 timeout이 없다는 의미이다. 다시 말하면 만약 패킷이 도착하지 않았다면 adapter를 읽은것에 대해서 결코 반환하지 않겠다라는 것을 의미한다.

    또 다른경우에 timeout를 -1로 세팅하는 경우에는 adapter의 읽기를 항상 바로 반환한다는 걸 뜻한다.

     

    * 내생각

    statistical mode로 설정하면 트래픽을 정보를 보고받게 되는데 이때의 to_ms는 트래픽의 통계 보고(statical report)의 간격을 정할 수 있다라는 의미인것같다. 만약 1000으로 하면 1초마다 통계보고를 얻을 수 있다는 정도로 생각할 수 있다.

    adapater에서 패킷을 읽어 들어올 때 만약 to_ms를 0으로 설정하면 만약 패킷이 들어오지 않는다면 계속 대기 상태로 있을 것이고 만약 -1로 세팅한다면 패킷이 들어오는 즉시 반환한다는 의미인 것 같다. 만약 1000설정하면 1초를 기다린다.

    왜냐하면 밀리세컨드 10-3 * 1000 =1 초 이기 때문이다.

     

     

    Once the adapter is opened, the capture can be started with pcap_dispatch() or pcap_loop(). These two functions are very similar, the difference is that pcap_ dispatch() returns (although not guaranteed) when the timeout expires while pcap_loop() doesn't return until cnt packets have been captured, so it can block for an arbitrary period on an under-utilized network. pcap_loop() is enough for the purpose of this sample, while pcap_dispatch() is normally used in a more complex program.

     

    일단 adapter 열리게 되면 패킷 캡쳐가 pcap_dispatch() or pcap_loop(). 두함수와 함께 시작될수 있다. 이 두함수의 매우 유사하다. 차이점은 pcap_ dispatch()함수는 timeout가 끝났을 때(만료되었을 때) 리턴한다.(비록 보장할 수는 없다.) 하지만 pcap_loop()함수는 cnt packets이 캡쳐가 되지 않았을 때까지 리턴하지 않는다. 그래서 이 함수는 under-utilized network 상에서 임의의 기간 동안 블락될 수도 있다.

    pcap_loop()함수는 이 샘플의 목적에 충분하다. 반대에 pcap_dispatch()는 일반적으로 좀더 복잡한 프로그램에서 사용되어진다.

     

    * 참고

    int pcap_dispatch ( pcap_t * p,

    int cnt,

    pcap_handler callback,

    u_char * user

    )

     

    int pcap_loop ( pcap_t * p,

    int cnt,

    pcap_handler callback,

    u_char * user

    )

     

    -> 내생각 pcap_open() 함수를 호출해서 adapter을 열고 다음에 pcap_dispatch() or pcap_loop() 둘중하나를 호출하게 되면 패킷캡쳐가 가능하다는 말이다. pcap_loop 함수의 경우 cnt의 값만큼 패킷을 얻지 못하면 리턴하지 못하는것이고 pcap_ dispatch함수는 타임아웃이 걸리때까지 대기한다는 것이다.

     

    Both of these functions have a callback parameter, packet_handler, pointing to a function that will receive the packets. This function is invoked by libpcap for every new packet coming from the network and receives a generic status (corresponding to the user parameter of pcap_loop() and pcap_dispatch()), a header with some information on the packet like the timestamp and the length and the actual data of the packet including all the protocol headers. Note that the frame CRC is normally not present, because it is removed by the network adapter after frame validation. Note also that most adapters discard packets with wrong CRCs, therefore WinPcap is normally not able to capture them.

     

    이 두함수 pcap_ dispatch, pcap_loop는 callback 파라미터(패킷을 받을 수 있는 함수를 가리키고있는 packet_handler () )를 가지고 있다. 이 함수는(packet_handler() )는 매번 새로운 패킷이 네트워크로부터 도착하게 되면 libcap에 의해서 깨어지고 그리고 pcap_loop() and pcap_dispatch() 함수의 유저 파라미터와 상응되는 일반적인 상태를 얻는다. 일반적인 상태란 모든 프로토콜헤더를 포함하는 패킷의 timestamp 그리고 길이 그리고 실제 데이터와 같은 패킷의 정보를 가지고 있는 헤더를 말한다. 일반적으로 CRC 존재하지 않는다는 것을 주목해라. 왜냐하면 그것은 frame validation로부터 네트워크 어댑터에 의해서 제거되기 때문이다. 또한 대부분의 어댑터는 잘못된 CRC를 가지고 있는 패킷을 버린다는 것을 주목해라. 그러므로 winpcap는 보통 그것들을 캡쳐 할 수 없다.

    * 참고

    void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)

     

    struct pcap_pkthdr

     

    timeval ts // time stamp

    bpf_u_int32 caplen // length of portion present

    bpf_u_int32 len // length this packet (off wire)

    * 내생각

    pcap_loop함수의 callback 인자(세번째 파라미터) 즉 packet_handler함수는 네트워크카드, 즉 어댑터에 패킷이 도착하게 되면 libcap 에 의해서 일반적인 정보를 받을 것이다. 그중 CRC (오류 체크하는 용도임, 자세한건 찾아 보세요)가 존재하지 않는 이유는 CRC의 유효성을 네트워크 어댑터가 검사하는데 만약 유효하다면 네트워크 단에서 이부분을 제거하기 때문에 우리가 이것을 확인할 수가 없고 만약 문제가 있다면 네트워크 어댑터에서 문제가 있는 패킷을 버리기 때문에 우리는 CRC의 존재를 확인할 수가 없다.

     

     

    The above example extracts the timestamp and the length of every packet from the pcap_pkthdr header and prints them on the screen.

     

    위에 예제는 pcap_pkthdr header의 모든 패킷길이와 timestamp를 추출했다. 그리고 그것을 화면에 출력해준다.

     

    Please note that there may be a drawback using pcap_loop() mainly related to the fact that the handler is called by the packet capture driver; therefore the user application does not have direct control over it. Another approach (and to have more readable programs) is to use the pcap_next_ex() function, which is presented in the next example (Capturing the packets without the callback).

     

    여기에는 패킷캡쳐 드라이버에 의해서 호출된 핸들러와 많은 관련이 있는 pcap_loop() 함수를 사용함으로써 결점이 있을 수 있다는 것에 주목하라, 그러므로 유저 applicationdms 그것을 직접적으로 컨트롤할 수 없다. 또 다른 접근방법( 좀더 가독성이 좋은 프로그램)은 pcap_next_ex()함수를 사용하는 것이다. 이 함수는 다음번에 예제(callback없이 패킷을 캡쳐할 수 있는 예제)에서 볼 수 있다.

    [출처] winpcap 3장|작성자 fox3831

    posted by 랜달프
    2008. 4. 6. 16:14 Programming/C programming
    winpcap/pcap.h 함수 분석
    1. typedef void(*  pcap_handler )(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) 
    [ 기능 ]
    패킷을 받는 콜백 함수의 프로토타입
    [ 파라미터 ]
    u_char *user : pcap_dispatch() pcap_loop()를 호출할 때 전달하는 u_char 포인터
    const struct pcap_pkthdr *pkt_header : 패킷의 정보를 기지고 있는 pcap_pkthdr 구조체
    const u_char *pkt_data : 패킷의 데이터를 가리키고 있는 u_char 포인터
     
    2. pcap_t *pcap_open_live (char *device, int snaplen, int promisc, int to_ms, char *ebuf)
    [ 기능 ]
    네트워크의 패킷들을 보기위해 필요한 packet capture descriptor를 얻기위해 사용된다.
    [ 파라미터 ]
    char *device : 사용할 네트워크 디바이스를 지시하는 스트링 
    int snaplen : 캡쳐할 최대 bytes 
    int promisc : NIC promiscuous mode로 동작할 지 여부 
    int to_ms : millisecond 단위의 read timeout 
    char *ebuf : pcap_open_live()가 실패할 경우에만 에러 메시지가 저장된다. 보통 NULL
    [ 반환 ]
    성공 : 패킷 캡쳐 descriptor
    실패 : NULL
     
    3. pcap_t * pcap_open_dead (int linktype, int snaplen)
    [ 기능 ]
    libpcap의 다른 함수를 호출할 때 pcap_t structure를 생성한다.
     
    4. pcap_t *pcap_open_offline(char *fname, char *ebuf)
    [ 기능 ]
    기존에 저장된 파일에서 패킷을 읽기 위해 사용된다. 
    stdin에서 읽기 위해서는 파일 이름을 "-"으로 한다. 
    [ 파라미터 ]
    char *fname : 오픈할 파일의 이름 
    char *ebuf : 실패할 경우 에러 메시지가 저장된다 .
    [ 리턴 ]
    성공 : descriptor
    실패 : NULL
     
    5. pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname) 
    [ 기능 ]
    캡쳐한 내용을 파일에 저장하기 위해서 파일을 오픈한다. 
    stdout을 지시하려면 파일이름을 "-"를 이용한다.
    [ 파라미터 ]
    pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor 
    char *fname : 오픈할 파일의 이름
    [ 리턴 ]
    성공 : pcap_dumper_t로 패킷 덤프와 관련된 구조체
    실패 : NULL
     
    6. int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
    [ 기능 ]
    블록킹과 논블록킹 모드를 바꾼다.
    [ 파라미터 ]
    pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor 
    int nonblock : non-zero 혹은 zero 값을 지닌다.
    char *errbuf : 실패시 에러 메시지가 채워진다.
    [ 리턴 ]
    성공 : 0
    실패 : -1
     
    7. int  pcap_getnonblock (pcap_t *p, char *errbuf) 
    [ 기능 ]
    인터페이스의 non-blocking 상태를 얻는다.
    [ 파라미터 ]
    pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor 
    char *errbuf : 실패시 에러 메시지가 채워진다.
    [ 리턴 ]
    성공 : 0
    실패 : -1
     
    8. int  pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
    [ 기능 ]
    pcap_open_live()로 열린 네트워크 디바이스의 리스트를 구한다.
    [ 파라미터 ]
    pcap_if_t **alldevsp : 네트워크 다비이스의 리스트 포인터
    char *errbuf : 실패시 에러 메시지가 채워진다.
    [ 반환 ]
    성공 : 0
    실패 : -1
     
    9. void  pcap_freealldevs (pcap_if_t *alldevsp)
    [ 기능 ]
    pcap_findalldevs()에 의해 리턴된 인터페이스 리스트를 해제한다.
    [ 파라미터 ]
    pcap_if_t **alldevsp : 네트워크 다비이스의 리스트 포인터
     
    10. char *  pcap_lookupdev (char *errbuf) 
    [ 기능 ]
    패킷을 캡쳐할 적당한 네트워크 디바이스(NIC : Network Interface Card)를 찾아
    그 디바이스를 지칭하는 스트링을 리턴한다. 
    네트워크 디바이스를 지칭하는 스트링은 각 운영체제 별로 표현되는 별명(alias) 
    말하며 Linux의 경우 "eth0", "eth1" 식으로 표현되고 BSD 계열은 각 네트워크 
    디바이스 벤더별로 별도로 명명된다.
    [ 파라미터 ]
    char *errbuf : 실패시 에러 메시지가 채워진다.
    [ 리턴 ]
    성공 : 네트워크 디바이스의 별명(alias)
    실패 : NULL
     
    11. int  pcap_lookupnet (char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf)
    [ 기능 ]
    네트워크 디바이스의 네트워크 주소와 netmask 정보를 가져오기위해 사용된다. 
    [ 파라미터 ]
    char *device : 네트워크 디바이스의 별명(alias) 
    bpf_u_int32 *netp : 네트워크 디바이스의 네트워크 주소가 저장될 주소 
    bpf_u_int32 *maskp : 네트워크 디바이스의 netmask가 저장될 주소 
    char *errbuf : 에러 발생시 에러 메시지 저장
    [ 리턴 ]
    성공 : 0
    실패 : -1
     
    12. int  pcap_dispatch (pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    [ 기능 ]
    프로세스 패킷을 구성할 때 사용된다.
    [ 파라미터 ]
    pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor 
    int cnt : 읽을 패킷의 갯수
    pcap_handler callback : 패킷을 처리할 루틴
    u_char *user : 패킷 데이타 포인터
    [ 리턴 ]
    성공 : 읽은 패킷의 수
    실패 : -1
     
    13. int  pcap_loop (pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    [ 기능 ]
    패킷의 그룹을 모은다.
    [ 파라미터 ]
    pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor 
    int cnt : 읽을 패킷의 갯수
    pcap_handler callback : 패킷을 처리할 루틴
    u_char *user : 패킷 데이타 포인터
    [ 리턴 ]
    성공 : 읽은 패킷의 수
    실패 : -1
     
    14 void  pcap_dump (u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
    [ 기능 ]
    pcap_dump_open()을 통해 저장할 파일을 결정했다면 이 함수로 실제 저장이 이루어진다. 
    callback 루틴을 호출할 때와 같은 파라미터를 가진다.
    [ 파라미터 ]
    u_char *user : 사용자 데이터 
    struct pcap_pkthdr *h : 패킷의 정보를 가리키고 있는 포인터 
    u_char *sp : 패킷의 데이터를 가리키고 있는 u_char 포인터
     
    15. int  pcap_compile (pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)
    [ 기능 ]
    스트링 형태의 필터링 룰을 해석해 bpf_program 구조체에 저장한다.
    [ 파라미터 ]
    pcap_t *p : 패킷 캡쳐 descriptor 
    struct bpf_program *fp : 필터링 룰에 따라 결정될 구조체 
    char *str : 스트링 형태의 필터링 룰 
    int optimize : 결과 코드를 수행할 때 최적화 여부 
    bpf_u_int32 netmask : 네트워크의 mask
     
    16. int  pcap_compile_nopcap (int snaplen_arg, int linktype_arg, struct bpf_program *program, char *buf, int optimize, bpf_u_int32 mask)
    [ 기능 ]
    어댑터를 열지 않고 패킷 필터를 컴파일한다.
    커널레벨의 필터링룰에 의해 인터프리트될 수 있는 프로그램에서
    높은레벨의 필터링표현을 변환한다.
    [ 파라미터 ]
    int snaplen_arg : 
    int linktype_arg :
    struct bpf_program *program : 필터링 룰에 따라 결정될 구조체
    char *buf : 스트링 형태의 필터링 룰
    int optimize : 결과 코드를 수행할 때 최적화를 물어본다
    bpf_u_int32 mask : mask
    [ 리턴 ]
    성공 :
    실패 : -1
     
    17. int  pcap_setfilter (pcap_t *p, struct bpf_program *fp)
    [ 기능 ]
    pcap_compile()을 통해 결정된 bpf_program 구조체를 적용할 때 사용된다. 
    [ 파라미터 ]
    pcap_t *p : 패킷 캡쳐 descriptor 
    struct bpf_program *fp : 보통 pcap_compile()에서 결과 
    [ 리턴 ]
    성공 : 0
    실패 : -1
     
    18. void  pcap_freecode (struct bpf_program *fp)
    [ 기능 ]
    필터를 해제한다.
    [ 파라미터 ]
    struct bpf_program *fp : 보통 pcap_compile()에서 결과
     
    19. u_char *  pcap_next (pcap_t *p, struct pcap_pkthdr *h)
    [ 기능 ]
    다음 패킷의 포인터를 리턴한다. 내부적으로 pcap_dispatch()를 호출한다.
    [ 파라미터 ]
    pcap_t *p : 패킷 캡쳐 descriptor 
    struct pcap_pkthdr *h : 패킷의 정보를 가리키고 있는 포인터
    [ 리턴 ]
    성공 : 패킷을 가리키는 포인터
    실패 : NULL
     
    20. int  pcap_datalink (pcap_t *p)
    [ 기능 ]
    link type을 리턴한다.
    pcap_t의 멤버 중 linktype.
    linke type bpf.h에 정의되어 있다. 
    [ 파라미터 ]
    pcap_t *p : 패킷 캡쳐 descriptor 
    [ 리턴 ]
    성공 : link type
     
    21. int  pcap_snapshot (pcap_t *p)
    [ 기능 ]
    pcap_open_live()가 호출될 때 지정된 길이인 snapshot length를 리턴한다.
    pcap_t의 멤버 중 snapshot
    [ 파라미터 ]
    pcap_t *p : 패킷 캡쳐 descriptor
    [ 리턴 ]
    성공 : snapshot length
    실패 :
     
    22. int  pcap_is_swapped (pcap_t *p)
    [ 기능 ]
    사용하고 있는 저장 파일과 사용하는 시스템이 같은 byte order를 사용하는지 여부를
    알 수 있다. 
    [ 파라미터 ]
    pcap_t *p : 패킷 캡쳐 descriptor 
    [ 리턴 ]
    0 : 같은 byte order를 사용할 경우 
    1 : 다른 byte order를 사용할 경우
     
    23. int pcap_major_version(pcap_t *p)
    [ 기능 ]
    저장 파일에 사용된 pcap의 메이저 버전을 리턴한다.
    [ 파라미터 ]
    pcap_t *p : 패킷 캡쳐 descriptor 
    [ 리턴 ]
    성공 : pcap의 메이저 버전
     
    24. int pcap_minor_version(pcap_t *p)
    [ 기능 ]
    저장 파일에 사용된 pcap의 마이너 버전을 리턴한다.
    [ 파라미터 ]
    pcap_t *p : 패킷 캡쳐 descriptor 
    [ 리턴 ]
    성공 : pcap의 마이너 버전
     
    25. int pcap_stats(pcap_t *p, struct pcap_stat *ps) 
    [ 기능 ]
    패킷 캡쳐에 관한 상태 정보를 ps에 저장한다. 송수신된 패킷의 갯수나 에러 발생 정보 등의 통계 정보를 알 수 있다.
    [ 파라미터 ]
    pcap_t *p : 패킷 캡쳐 descriptor 
    struct pcap_stat *ps : 패킷 캡쳐 상태 정보 구조체
    [ 리턴 ]
    성공 : 0
    실패 : -1
     
    26. FILE *pcap_file(pcap_t *p) 
    [ 기능 ]
    p가 가리키는 패킷 캡쳐에서 사용하는 저장 파일의 FILE 포인터를 넘겨준다.
    [ 파라미터 ]
    pcap_t *p : 패킷 캡쳐 descriptor 
    [ 리턴 ]
    성공 : 파일 포인터
     
    27. int pcap_fileno(pcap_t *p) 
    [ 기능 ]
    p가 가리키는 패킷 캡쳐에서 사용하는 저장 파일의 descriptor를 넘겨준다.
    [ 파라미터 ]
    pcap_t *p : 패킷 캡쳐 descriptor 
    [ 리턴 ]
    성공 : file descriptor
     
     
    28. void pcap_perror(pcap_t *p, char *prefix) 
    [ 기능 ]
    최근에 발생한 에러에 대해 에러메시지를 stderr에 출력한다.
    [ 파라미터 ]
    pcap_t *p : 패킷 캡쳐 descriptor 
    char *prefix : 메시지를 출력할 때 앞에 추가할 내용 
     
    29. char *pcap_geterr(pcap_t *p) 
    [ 기능 ]
    최근에 발생한 에러에 대한 메시지를 리턴한다. 
    [ 파라미터 ]
    pcap_t *p : 패킷 캡쳐 descriptor 
    [ 리턴 ]
    성공 : 최근 발생한 에러 메시지
     
    30. char *pcap_strerror(int error)
    [ 기능 ] 
    strerror(1)이 없을 경우를 위해 제공된다.
    [ 파라미터 ] 
    int error : error number 
    [ 리턴 ]
    성공 : error 메시지
     
    31. void  pcap_close (pcap_t *p)
    [ 기능 ]
    패킷을 닫고 메모리 해제
    [ 파라미터 ]
    pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor
     
    32. void pcap_dump_close(pcap_dumper_t *p)
    [ 기능 ]
    저장 파일을 닫는다.
    [ 파라미터 ]
    pcap_dumper_t *p : 패킷 덤프 descriptor
     
    33. int  pcap_setbuff (pcap_t *p, int dim)
    [ 기능 ]
    어댑터와 연결된 커널 버퍼의 크기를 지정한다.
    [ 파라미터 ]
    pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor
    int dim : 버퍼의 사이즈
    [ 리턴 ]
    성공 : 0
    실패 : -1
     
    34. int  pcap_setmode (pcap_t *p, int mode)
    [ 기능 ]
    인터페이스 p의 모드를 지정한다.
    [ 파라미터 ]
    pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor
    int mode : 모드(MODE_CAPT : 기본캡춰모드, MODE_STAT : 통계모드)
     
    35. int  pcap_sendpacket (pcap_t *p, u_char *buf, int size) 
    [ 기능 ]
    로우 패킷을 보낸다.
    [ 파라미터 ]
    pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor
    u_char *buf : 보내어진 패킷의 데이터
    int size : 버퍼 크기
    [ 리턴 ]
    성공 : 0
    실패 : -1
     
    36. int  pcap_setmintocopy (pcap_t *p, int size)
    [ 기능 ]
    싱글 호출에서 커널에 의해 받아진 데이터의 최소 크기를 지정한다.
    [ 파라미터 ]
    pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor
    int size : 사이즈
    [ 리턴 ]
    성공 : 0
    실패 : -1
     
    37. HANDLE  pcap_getevent (pcap_t *p)
    [ 기능 ]
    인터페이스 p와 연결된 이벤트의 핸들을 구한다.
    [ 파라미터 ]
    pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor
    [ 리턴 ]
    성공 : 핸들
     
    pcap_send_queue *  pcap_sendqueue_alloc (u_int memsize)
    [ 기능 ]
    send queue를 할당한다.
    [ 파라미터 ]
    u_int memsize : 큐의 최소 사이즈
     
    38. void pcap_sendqueue_destroy  (  pcap_send_queue *queue  )   
    [ 기능 ]
    send queue를 해제한다.
    [ 파라미터 ]
    pcap_send_queue *queue : 큐 포인터
     
    39. int  pcap_sendqueue_queue (pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
    [ 기능 ]
    send queue의 끝에 패킷을 추가한다.
    [ 파라미터 ]
    pcap_send_queue *queue :
    const struct pcap_pkthdr *pkt_header : 패킷의 헤더와 길이를 포함하는 pcap_pkthdr 자료구조의 포인터
    const u_char *pkt_data : 패킷의 데이터를 포함하는 버퍼의 포인터
     
    40. u_int  pcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, int sync)
    [ 기능 ]
    로우 패킷의 큐를 네트워크로 보낸다.
    [ 파라미터 ]
    pcap_t *p : 보내어진 패킷을 가진 어댑터의 포인터
    pcap_send_queue *queue : 보내기 위한 패킷을 포함하는 pcap_send_queue 자료구조의 포인터
    int sync : 동기화, 비동기화의 여부로 non-zero(TRUE)일 경우 동기화가 된다.
    [ 리턴 ]
    성공 : 실제 보내어진 바이트 수
     
    41. int  pcap_next_ex (pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data)
    [ 기능 ]
    오프라인 캡처로부터 혹은 인터페이스로부터 패킷을 읽는다.
    [ 파라미터 ]
    pcap_t *p : 보내어진 패킷을 가진 어댑터의 포인터
    struct pcap_pkthdr **pkt_header :
    u_char **pkt_data :
     
    [ 리턴 ]
    1 : 성공
    0 : timeout이 만기될 경우
    -1 : 에러 발생
    -2 : EOF
     
    42. int  pcap_live_dump (pcap_t *p, char *filename, int maxsize, int maxpacks) 
    [ 기능 ]
    인터페이스로부터 네트워크 트래픽 덤프를 파일로 저장한다.
    [ 파라미터 ]
    pcap_t *p : 어댑터의 포인터
    char *filename : 파일 이름
    int maxsize : 최대 사이즈
    int maxpacks : 최대 패킷
    [ 리턴 ]
    성공 : 1
    실패 : 0
     
    43. int  pcap_live_dump_ended (pcap_t *p, int sync)
    [ 기능 ]
    커널 덤프 프로세스의 상태를 구한다.
    [ 파라미터 ]
    pcap_t *p : 어댑터의 포인터
    int sync : nonzero면 덤프가 끝날때까지 함수는 블록킹 된다.
    [ 리턴 ]
    성공 : 1
    실패 : -1
     
    44. pcap_stat *  pcap_stats_ex (pcap_t *p, int *pcap_stat_size)
    [ 기능 ]
    현재 캡춰한 통계를 보여준다.
    [ 파라미터 ]
    pcap_t *p : 어댑터의 포인터
    int *pcap_stat_size : pcap_stat 자료구조의 사이트를 포함한다.
    [ 리턴 ]
    성공 : pcap_stat 포인터로 현재 디바이스의 통계를 저장
    실패 : NULL
     
    char* pcap_strerror  (  int    error  )   
    [ 기능 ]
    strerror()가 이용가능하지 않을때 제공된다.
    [ 파라미터 ]
    int error : 에러
    [ 리턴 ]
    성공 : 에러 메시지

    출처 : Tong - ssabro님의 Network Programming통

    posted by 랜달프
    2008. 4. 6. 15:53 Programming/C programming

    IP Header 정 보

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

    Header Length (4bit) : IP헤더의 길이, 일반적인 IP헤더는 20바이트(32bit *5)이며, 그림과 같이 32bit단위로 나타낸다.
           
    Type of Service (8bit) : 데이터그램의 성격을 명시하여, 라우터나, 호스트 등에서 우선순위 서비스(Qos : Quality of Service)를 제공하기 위하여 제공된 필드(RFC 791참조)
                                   
    Total Length (16bit) : IP헤더와 데이터를 포함한 전체 IP패킷의 길이의 바이트 단위 필드
           
    Identification (16bit) : 분열된 데이터를 재배열하기 위해서 송신자가 데이터그램의 조각들에 부여한 일련번호(동일IP데이터그램에서 분열된 IP패킷들은 같은 일련번호)
           
    Flags (3bit) : 3개의 비트를 이용한 분열의 상태 정보를 제공하는 필드

    - bit 0 : 나중에 사용하려고 예약. 반드시 0이여야 함.
    - bit 1 : 0 = 분열 허용 / 1 = 분열 허용안됨
    - bit 2 : 0 = 현재데이터가 마지막 분열 / 1 = 뒤에 분열된 데이터가 있음

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

    Time to live(8bit) : IP패킷이 네트워크에서 얼마나 오래 존재할 수 있는가를 나타내느 필드(0-255) 라우터를 하나 거칠때마다 1씩 감사하고 0이 되면 라우터에서 소멸시킴.
            
    Protocol (8bit) : IP데이터그램의 데이터 부분이 어떤 상위계층에 해당하는가를 나타내는 필드 (ex : TCP 6 / UDP 17 / ICMP 1 / IP 0 /IGMP 등)
           
    Header Checksum (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 단위가 되도록 만드는데 사용.


    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) : 에러 메시지에 대한 추가 정보를 제공하기 위한 부분. 거의 사용되지 않음.
    Internet Header + 64 bits of Original Data Datagram (60 Bytes + 60bit)
                            : 문제가 생긴 원래 IP 데이터그램의 헤더와 데이터의 일부를 보내어 송신 호스트가 어떤 데이터그램이 실패했는지 판단하게 한다.
           

    TCP Header 정 보   

    Source Port (16bit) : 데이터를 전송하는 출발지의 포트 번호를 나타냄.

    Destination Port (16bit) : 데이터를 전송하는 목적지의 포트 번호를 나타냄.

    Sequence Number (32bit) : 전송되는 데이터의 일련번호를 나타냄.

    Acknowledgment Number (32bit) : 수신 데이터의 일련번호 + 전송된 데이터의 합을 나타냄.

    Data Offset (4bit) : TCP 헤더의 길이를 나타냄.(단위 : 32bit words. 보통 5)

    Reserved (6bit) : 예약된 6bit 이므로 항상 0이어야 한다.

    Control Bits(6bit) : URG, ACK, PSH, RST, SYN, FIN등의 회선 제어 정보를 담고 있다.

    Urgent Pointer : 최고 수준의 우선 순위, 가장 먼저 전송된다.

    Valid ACK : ACK필드의 숫자가 유효할때 1로 설정된다.

    Push Session : 우선순위가 좀 떨어지더라도 최대한 빨리 전송을 요구한다.

    Reset Session : 현재의 세션을 재시작 하려할때 사용된다.

    Sync Sequence Number : 1로 설정되어 있으면 목적지의 호스트에게 Sequence Number를 송신측의 Number와 동기화를 요구한다.

    Final Data : 목적지 호스트에게 데이터전송이 끝났음을 통보한다.

    Window (16bit) : 수신 시스템에서 처리할 수 있는 수신 버퍼의 크기를 나타낸다.

    Checksum (16bit) : TCP 세그먼트 전체의 체크섬을 저장한다.

    Urgent Pointer (16bit) : 급히 처리되어야 할 데이터의 마지막 바이트를 나타낸다.

    Options (필요할 경우) : 기본 크기는 0bit이며, 최대 40byte까지 생성할 수 있다.

    Padding (Options에 따라 가변 길이) : Options에 따라 32bit형태를 만들기 위한 영역.


    UDP Header 정 보   

    Source Port (16bit) : 데이터를 전송하는 출발지의 포트번호를 나타낸다.

    Destination Port (16bit) : 데이터를 전송하는 목적지의 포트번호를 나타낸다.

    Length (16bit) : UDP 헤더와 데이터 부분을 포함한 메시지 전체의 길이를 나타낸다.

    Checksum (16bit) : UDP 메시지의 손상여부를 검사하는 항목으로, 간단한 합으로 계산결과를 판단.

    [출처] TCP/IP Header 설명|작성자 핵폭

    posted by 랜달프
    2007. 12. 4. 04:03 Programming/C programming

    파일 열기 함수 fopen()의 모드

    1. r : 읽기(read) 모드로 파일을 연다. 파일이 없으면 에러가 발생한다.

    2. w : 쓰기(write) 모드로 파일을 연다. 파일이 없으면 새로 만들고, 기존의 파일이 있으면 그 이전의 내용은 없어지고 파일의 처음부터 쓴다. 이 모드로는 파일의 내용을 읽을 수 없다.

    3. a : 추가쓰기(append) 모드로 파일을 연다. 파일이 없으면 새로 만들고, 기존의 파일이 있으면 그 파일의 가장 뒤부터 파일에 추가한다.

    4. r+ : 읽기(read)와 쓰기(write) 모드로 파일을 연다. 파일이 없으면 에러가 발생한다.

    5. w+ : 읽기(read)와 쓰기(write) 모드로 파일을 연다. 파일이 없으면 새로 만들고, 기존의 파일이 있으면 그 이전의 내용은 없어지고 파일의 처음부터 쓴다.

    6. a+ : 추가쓰기(append) 모드로 파일은 연다. 파일이 없으면 새로 만들고, 기존의 파일이 있으면 그 파일의 가장 뒤부터 파일에 추가한다. 파일의 어느 곳이나 읽기는 가능하나 쓰기는 파일 끝에 추가적으로만 가능하다.

    posted by 랜달프
    2007. 12. 3. 22:50 Programming/C programming

    #include<stdio.h>

    void main(void){
     int ar[100][100];
     int x1 =0 , x2, y1 =0, y2 ; //벽
     int vx=1,vy=0; //백터
     int x=-1,y=0;    //배열에 들어갈 현재 값.
     int n ;  // 배열의 크기
     int i,j,su=0;
     scanf("%d",&n);
     //n=5;

     y2 = n-1;
     x2 = n-1;

     for(i=0;i<n;i++){
      for(j=0;j<n;j++)ar[i][j]=0;
     }

     printf("  su  x   y  vx  vy  x1  x2  y1  y2 \n");
     
     while(su<n*n){   ///n*n){
      x+=vx;
      y+=vy;
      ar[y][x] = ++su;
      printf("%3d %3d %3d %3d %3d %3d %3d %3d %3d  \n",su,x,y,vx,vy,x1,x2,y1,y2);
      if(x==x2 && vy==0 && vx==1  ){ //하로  (우일때)
      //printf("하\n");
      vx=0;
      vy=1;
      y1+=1; //윗벽을 없앰.
      }
      if(y==y2 && vy==1 && vx==0 ){//좌로 (후일때)
       //printf("좌\n");
       vx=-1;
       vy=0;
       x2-=1; //오른쪽 벽을 없앰.
      }
      if(x==x1 && vy==0 && vx==-1 ){ //위로  (좌일때)
       //printf("상\n");
       vx=0;
       vy=-1;
       y2-=1; //아래벽을 없앰..
      }
      if(y==y1 && vy==-1 && vx==0  ){//우로  (상일때)
       //printf("우\n");
       vx=1;
       vy=0;
       x1+=1; //왼쪽벽을 없앰..
      }
     
     }

     for(i=0;i<n;i++){
      for(j=0;j<n;j++)printf("%3d",ar[i][j]);
      printf("\n");
     }
     
    }

    사용자 삽입 이미지

    출력결과



    posted by 랜달프
    prev 1 next