리눅스 명령어
su - 아이디 $ 로 바꿔줌
su 아이디 현재설정유지 하면서 $로 바꿔줌
ctrl + D $ 상태에서 # 으로 바꿔준다
usr/include pcab 헤더 있는곳
usr/inlcude/linux if_ether.h , ethernet.h 있는곳
1. 개요
Ethernet Protocol Type 이란 이더넷 패킷내의 데이터부분에서 캡슐화된 데이터가 어느 프로토콜에 해당하는지를 나타내고자, 13~14번째 바이트에 이를 표시하는 영역을 말한다.
2. 이더넷 프레임의 통상적인 형식 : IEEE 802.3 또는 DIX 2.0
- Preamble(10101...) 및 SFD(10101011) : 10101......10101011
- D A : Destination Address, S A : Source Address ☞ MAC 주소
- Len/Type : 0x 600 이상이면 Type (DIX 2.0), 이하이면 Length (802.3) 로 해석
. Length : 길이(3~1500 바이트)를 나타냄 ☞ MTU
. Type : Data에 담겨있는 상위 프로토콜 ☞ Ethertype
- Type의 대표적인 값들 (0x600 이상의 값 만이 가능함)
0600h Xerox XNS IDP
0800h IP
0805 X.25
0806h ARP
0835h RARP
6003h DEC DECnet Phase Ⅳ
8137h Novell Netware IPX
8191h NetBIOS
8847h MPLS
8863h PPPoE Discovery Stage
8864h PPPoE PPP Session Stage
4. 각 프레임의 형태
5. 참고사항
ㅇ 위 프레임들 간의 주요한 차이는,
MAC 부계층 바로 상위계층인 LLC 부계층 관련 부분(3 바이트)의 포함 여부에 있
다. (DIX Ethernet frame : 미포함, IEEE 802.3 frame : 포함)
ㅇ 각 바이트별 비트들의 송신 순서
- 이더넷 프레임의 각 바이트의 비트들은 FCS를 제외하고, 모두 LSB 부터 송신된다.
이더넷 프로토콜 타입에 대한 정보가 패킷내에 존재한다. 이것은 아래의 그림과 같은 모습의 구조를 띄고 있다.
위의 소스를 실제로 돌려봤을 때 다음과 같은 화면을 볼 수 있다. (리눅스에서 구동한 것이다.)
위의 프레임 구조에서 봤듯이 붉은 본홍색으로 표시된 부분은 도착지의 MAC address이며,
녹색으로 표시된 부분은 출발지의 MAC address이다.
이를 ifconfig 명령어로 확인해보면 출발지의 값이 다음과 같이 동일하다는 것을 알 수 있다.
도착지 다음의 2바이트는 이더넷 타입을 나타내는 0x0800은 IP를 뜻한다.
소스는 다음과 같다.
#include <stdio.h>
#include <pcap/pcap.h>
char errbuf[PCAP_ERRBUF_SIZE];
void HexaView(const void *,int );
#pragma pack(1)
#pragma pack 이란?!
/*
실제 데이타와 구조체 사이즈를 비교해 보면 구조체 사이즈가 크다.
음 언급했듯이 운영체재의 환경에 따라 packing 되어 있는 크기가 있기 때문이었다. 만약 운영체재에서 packing 된 값이 4 Byte 라고 한다면, char 자료형도 1 Byte가 아닌 4 Byte를 잡고 들어간다. 3 Byte 만큼이 더 커진 것이다. 물론 int 자료형이면, 4 Byte 값이 들어가겠지만, 특정 자료형이 5 Byte 면. 우선 4 Byte 크기를 잡고 나머지 1 Byte 를 잡아주기 위해서 4 Byte 다시 잡아준다.
그래서 5 Byte 자료형은 8 Byte 만큼의 크기를 갖게 되는 것이다.
이런 문제를 막아주기 위해서 #pragma pack(push, 1) 또는 #pragma pack(1) 를 사용하면 운영체재에서 packing 되어진 값이 아닌 1 Byte 씩 자르기 때문에 char 자료형은 4 Byte 가 아닌 1 Byte 가 되고, 5 Byte 형 자료형도 8 Byte 가 아닌 5 Byte 가 된다.
*/
struct ether_header
{
unsigned char ether_dhost[6]; /* destination eth addr */
//u_int8_t => 1바이트 ,[ETH_ALEN]=6 그러므로 1*6=총 6바이트
unsigned char ether_shost[6]; /* source ether addr */
//u_int8_t => 1바이트 ,[ETH_ALEN]=6 그러므로 1*6=총 6바이트
unsigned short ether_type; /* packet type ID field */
//u_int16_t => 총 2바이트
};
int main()
{
char *nicName;
pcap_t *stpHandle;
const u_char *ucData;
struct pcap_pkthdr stInfo;
//패킷을 건져 올리 때의 시간 같은 정보를 StInfo로 넘겨준다.
struct ether_header *stpEth;
nicName=pcap_lookupdev(errbuf);
// char * pcap_lookupdev(char * errbuf);
// pcap_lookupdev : 장치를 찾아 장치명알아낸다
// 현재 연결된 네트워크 장비를 찾아 해당 장비의 장비명을 리턴하며 인자로 에러를 처리할 버퍼의
// 주소를 넘긴 다. 위 함수를 통해 얻은 장치명은 pcap_open_live 함수를 통해서 장치로부터 오는
// 패킷을 캡쳐할수 있다
printf("%s\n",nicName);
if(0==nicName)
{
printf("[%s] 네트워크 디바이스를 찾을수가 없습니다",errbuf);
return 0;
}
stpHandle=pcap_open_live(nicName, 1500,1,0, errbuf);
// pcap_t * pcap_open_live(char * device,int snaplen,int promisc,int to_ms, char * ebuf);
// 장치읽기위해 열 때 사용하는 함수,
// 열린 장치는 pcap_close()함수를 이용해서 반드시 닫아 주어야 한다..
// 첫 번째 인자는 읽어올 장치의 장치명이며 pcap_lookupdev함수를 통해 얻은 값을 넣어준다.
// 두 번째 인자는 읽어들일 패킷의 최대 크기
// 세 번째 인자는 패킷을 읽어들일 방식을 설정하는 값이며 1로 설정하게되면
// 조건없이 모든 패킷을 읽어들인다.
// 네 번째 인자는 패킷이 오기 까지의 대기시간을 나타내고 0으로 주면 패킷을 올때까지 무기한 기다린다.
// 마지막 인자는 에러를 처리할 버퍼의 주소이다
if(0==stpHandle)
{
printf("[%s] 네트워크 디바이스를 열 수가 없습니다",errbuf);
return 0;
}
ucData=pcap_next(stpHandle,&stInfo);
// 열린 장치로부터 패킷을 읽어 들일 때 사용하는 함수는 다음과 같다.
// 패킷을 건져 올린다.
// 패킷 시작점의 주소가 UcData로 넘겨준다.
// pcap_next 함수는 pcap_open_live 함수를 통해 리턴된 장치ID인 p를 넘겨 캡쳐한
// 패킷의 기본정보를 h 에 담아주고 해당 패킷의 데이터를 리턴하게된다.
// 열린 장치로 부터 패킷이 오길 기다리다 패킷이 도착하면 캡쳐한다.
// (대기 시간및 캡처 방식은 장치를 열대 설정)
// u_char * pcap_next(pcap_t * p,struct pcap_pkthdr * h)
HexaView(ucData,stInfo.len);
stpEth=(ether_header*)ucData;
printf("Destination: %02X %02X %02X %02X %02X %02X \n",stpEth->ether_dhost[0],stpEth->ether_dhost[1],stpEth->ether_dhost[2],stpEth->ether_dhost[3],stpEth->ether_dhost[4],stpEth->ether_dhost[5]);
printf("Source: %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]);
char *j;
j=(char*)&stpEth->ether_type; // 하나하나의 주소를 찍기 위해서 포인터 j 선언 하였다
printf("Protocol: %02X %02X\n",*j,*(j+1)); // 08 00 찍힘!
pcap_close(stpHandle);
return 0;
}
#pragma pack(4)
실행 화면이다 . 실행하고 인터넷을 켜게 되면 다음과 같이 나온다
C++에서의 문자열과 +오퍼랜드의 재정의
인라인 함수와 함수포인터 예제
A P I
컨트롤
컨트롤 : 사용자와의 인터페이스를 이루는 도구이고 하나의 윈도우 라고 한다. 곧 입출력 도구를 뜻한다.
표준 컨트롤 : 버튼, 에디트 ,리스트 박스, 콤보 박스, 스크롤 바, 스태틱
① 버 튼
LRESULT OnCreate(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
CreateWindow(TEXT("button"),TEXT("Clik_Me"),WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,20,20,100,25,hWnd,(HMENU)0,g_hInst,NULL);
// WS_CHILD | WS_VISIBLE -> 버튼은 child이고 화면에 출력하겠다 => 공통적으로 들어 가는 옵션
// BS_PUSHBUTTON -> 푸시 버튼
// 20,20,100,25 ->윈도우의 위치와 크기 => 좌상단 (20,20)에 위치 하며 폭은 100, 높이는 25 픽셀이다.
// hWnd ->컨트롤의 부모 윈도우 지정 => 메인 윈도우의 핸들(hWnd)
// (HMENU)0 -> 윈도우에서 사용할 메뉴의 핸들
// g_hInst -> 윈도우를 만드는 인스턴스 핸들
// NULL -> 사용자 정의 데이터 => CHILD 컨트롤을 만들 때에는 이 인수를 사용하지 않는다.
CreateWindow(TEXT("button"),TEXT("Me Two"),WS_CHILD | WS_VISIBLE | S_PUSHBUTTON,20,50,100,25,hWnd,(HMENU)1,g_hInst,NULL);
CreateWindow(TEXT("button"),TEXT("Exit"),WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,20,80,100,25,hWnd,
(HMENU)2,g_hInst,NULL);
return 0;
}
LRESULT OnCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
switch(LOWORD(wParam))
{
case 0:
MessageBox(hWnd,TEXT("First Button Clicked"),TEXT("Button"),MB_OK);
break;
case 1:
MessageBox(hWnd,TEXT("Second Button Clicked"),TEXT("Button"),MB_OK);
break;
case 2:
DestroyWindow(hWnd);
break;
// 윈도우를 종료시킨다
}
return 0;
}
LRESULT OnLButtonDown(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
return 0;
}
LRESULT OnPaint(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
hdc=BeginPaint(hWnd, &ps);
EndPaint(hWnd,&ps);
return 0;
}
LRESULT OnDestroy(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
PostQuitMessage(0);
return 0;
}
실 행 화 면 이 다.
② 체 크 박 스
푸쉬버튼은 사용자로부터 명령을 받아들이기 위해 사용하는데 비해 체크박스는 참, 거짓의
진위적인 선택을 입력받을 때 주로 사용된다.
옵션의 개수에 따라 두 가지 상태로 나뉜다.
BS_CHECKBOX : 두 가지 상태를 가진다. (선택 / 비선택)
BS_3STATE : 세 가지 상태를 가진다. (선택 / 비선택 / Greayed[알수 없음])
동작 방법에 따라 두가지로 나뉜다.
자동 체크 박스 : 스스로 체크 상태를 바꾼다
상태를 조사하기만 하면 될 경우 사용
수동 체크 박스 : 선택 / 비선택 상태를 부모 윈도우가 직접 바꾸어야 한다.
체크 박스의 상태가 변경될 때마다 어떤 처리를해야 하고 체크 조건이 복잡한 경우 사용
체크 박스 소스는 다음과 같다
#include "MsgProc.h"
HDC hdc;
PAINTSTRUCT ps;
static HWND c1,c2,c3,c4;
static BOOL bEllipse = FALSE;
LRESULT OnCreate(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
c1=CreateWindow(TEXT("button"),TEXT("Draw Ellipse?"),WS_CHILD | WS_VISIBLE | BS_CHECKBOX,20,20,160,25,hWnd,(HMENU)0,g_hInst,NULL);
c2=CreateWindow(TEXT("button"),TEXT("Good Bye Message?"),WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,20,50,160,25,hWnd,(HMENU)1,g_hInst,NULL);
c3=CreateWindow(TEXT("button"),TEXT("3State"),WS_CHILD | WS_VISIBLE | BS_3STATE,20,80,160,25,hWnd,(HMENU)2,g_hInst,NULL);
c4=CreateWindow(TEXT("button"),TEXT("Auto 3State"),WS_CHILD | WS_VISIBLE | BS_AUTO3STATE,20,110,160,25,hWnd,(HMENU)3,g_hInst,NULL);
return 0;
}
LRESULT OnCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
switch(LOWORD(wParam))
{
case 0:
if(SendMessage(c1,BM_GETCHECK,0,0)==BST_UNCHECKED)
// BM_GETCHECK(함수 실행 함으로써 현재 체크 상태를 알려달라고 한다),
// 0(wParam),0(lParam)
// 그 체크 상태가 체크가안되어 있을때
{
SendMessage(c1,BM_SETCHECK,BST_CHECKED,0);
// wParam에 BST_CHECKED 를 넣어 보낸다.
// 즉 체크 해달라고 명령한다.
bEllipse = TRUE;
// 원을 그리위한 조건식 선언
}
else
{
SendMessage(c1,BM_SETCHECK,BST_UNCHECKED,0);
// 이 조건식에 들어 왔다는건 지금 현재 체크박스가 체크가 되어 있기 때문에
// 체크 박스에 wParam에 BST_UNCHECKED 넣어 주어 체크를 풀게 명령한다.
bEllipse = FALSE;
// 사각형을 그리위한 조건식 선언
}
InvalidateRect(hWnd,NULL,TRUE);
//WM_PAINT 함수 발생
break;
case 2:
if(SendMessage(c3,BM_GETCHECK,0,0)==BST_UNCHECKED)
{
SendMessage(c3,BM_SETCHECK,BST_CHECKED,0);
}
// 3STATE 값이 체크가 안되어 있을 때
// 부모윈도우는 BM_GETCHECK 함수를 이용하여 체크 상태를 질문하고
// BM_SETCHECK 함수를 이용하여 체크 상태로 변경하라고 명령한다.
else if(SendMessage(c3,BM_GETCHECK,0,0)==BST_INDETERMINATE)
{
SendMessage(c3,BM_SETCHECK,BST_UNCHECKED,0);
}
// 3STATE 값이 체크가 Grayed 값을 가질때
// 체크를 풀라고 명령한다.
else
{
SendMessage(c3,BM_SETCHECK,BST_INDETERMINATE,0);
}
// 그렇지 않을 때의 값은 현재 체크가 되어 있는 상태이므로
// Grayed 값으로 변경 하라고 명령한다.
break;
}
return 0;
}
LRESULT OnLButtonDown(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
return 0;
}
LRESULT OnPaint(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
hdc=BeginPaint(hWnd, &ps);
if(bEllipse == TRUE)
{
Ellipse(hdc,200,100,400,200);
}
else
{
Rectangle(hdc,200,100,400,200);
}
EndPaint(hWnd,&ps);
return 0;
}
LRESULT OnDestroy(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
if(SendMessage(c2,BM_GETCHECK,0,0)==BST_CHECKED)
{
MessageBox(hWnd,TEXT("Good Bye"),TEXT("Check"),MB_OK);
}
// c2 는 오토 체크 박스 이다.
// 오토 체크 박스에 체크가 되어 있을시 마지막에 마칠 때 메시지 박스를 열어
// Good Bye를 출력하고 OK 버튼을 눌렀을 때 종료한다.
PostQuitMessage(0);
return 0;
}
실 행 화 면 은 다 음 과 같 다.
'코스웨어 > 10년 시스템제어' 카테고리의 다른 글
[일일보고서] 5월24일(월) - 9번 노현용 (0) | 2010.05.25 |
---|---|
아트메가 프로젝트 (0) | 2010.05.21 |
일일 보고서 (8번 남민호) (0) | 2010.05.20 |
시스템 제어 일일 보고서 - 김진웅 (7번) (1) | 2010.05.19 |
WinVi 편집기(윈도우에서 사용가능한 vi편집기) 및 몇가지 자주사용하는 명령어. (3) | 2010.05.19 |
시스템 제어 일일 보고서 - 8조 김민철(4번) (1) | 2010.05.18 |
시스템제어 - 헥사뷰어 실습 파일입니다. (0) | 2010.05.18 |
5월 14일 보고서 (3번 김락영) (2) | 2010.05.16 |