반응형
//////////////////////////////////////////////////////////////////////////
// Product Date : 2009/09/18 //
// Author : (Last) Lee //
// (First) Hyunbin //
// comment : This Program is expression to Packet architecture~ //
// by used to winpcap library. //
// 인지값 - void //
// 반환값 - void //
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Preprocessor area
#include <pcap.h>
#include <pcap-bpf.h>
#include <protocol.h>
#pragma comment(lib,ws2_)
//////////////////////////////////////////////////////////////////////////
// Define area
#define INPUT // Pointer's direction
#define OUTPUT // Pointer's direction
#define ETH_ALEN 6
#define ETHERTYPE_PUP 0x0200 /* Xerox PUP */
#define ETHERTYPE_IP 0x0800 /* IP */
#define ETHERTYPE_ARP 0x0806 /* Address resolution */
#define ETHERTYPE_REVARP 0x8035 /* Reverse ARP */
//////////////////////////////////////////////////////////////////////////
// Packet structure
typedef struct _Packet
{
const u_char * NProtocol; // Next Protocol
void (*Layer2)(INPUT void*);
void (*Layer3)(INPUT void*);
void (*Layer4)(INPUT void*);
}Packet;
//////////////////////////////////////////////////////////////////////////
// Function Prototype area
void Layer2_Ether(INPUT void * vP);
void Layer3_IP(INPUT void * vP);
void Layer3_ARP(INPUT void * vP);
void Layer3_REVARP(INPUT void * vP);
void Layer3_PUP(INPUT void * vP);
void PrintHexaNAscii(const unsigned char *buffer, int size);
//////////////////////////////////////////////////////////////////////////
// Product Date : 2009/09/18 //
// Author : (Last) Lee //
// (First) Hyunbin //
// comment : This function is main Function. //
// 인지값 - void //
// 반환값 - void //
//////////////////////////////////////////////////////////////////////////
int main()
{
char errbuf[PCAP_ERRBUF_SIZE];
// 함수 원형 : char* pcap_lookupdev
// 함수 설명 : pcap_open_live() 와 pcap_lookupnet() 에서 사용하기 위한 네트웍 디바이스에
// 대한 포인터를 되돌려준다. 성공할 경우 "eth0", "eth1" 과 같은 이름을
// 되돌려주며 실패할경우 0을 되돌려준다.
char * spNetDevName = pcap_lookupdev(errbuf);
int iDataLink;
const u_char* ucData;
struct pcap_pkthdr stPInfo;
Packet stData; // Packet Information
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
int iCnt = 0;
pcap_t *adhandle;
char packet_filter[] = "ip and udp";
// stData구조체를 0으로 초기화
memset(&stData, 0, sizeof(stData));
// 모든 네트워크 디바이스의 정보를 찾아서 3번째 인자에 넘겨준다.
if (-1 == pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf))
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
// 찾은 모든 device의 정보 출력한다.
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
// device를 찾지 못했다면
if(i==0)
{
// 찾지 못했음을 알리고 종료한다.
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return -1;
}
// 원하는 device를 선택한다.
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
// 허용된 범위 이외의 값을 입력하면
if(inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
// device 디스크립터인 alldevs를 해제후 프로그램을 종료한다.
pcap_freealldevs(alldevs);
return -1;
}
// 선택한 device로 이동한다.
for(d=alldevs, iCnt=0; iCnt< inum-1 ;d=d->next, iCnt++);
// 선택한 device를 open한다.
if ( NULL == (adhandle= pcap_open(d->name, // name of the device
65536, // portion of the packet to capture.
// 65536 grants that the whole packet~
// will be captured on all the MACs.
PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
1000, // read timeout
NULL, // remote authentication
errbuf // error buffer
)
)
)
// 장치를 찾지 못했다면
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n");
// device를 free시킨다.
pcap_freealldevs(alldevs);
return -1;
}
// 마찬가지로 장치를 찾지 못했다면
if(0 == adhandle)
{
printf("Error : [%s]\n", errbuf);
return 101;
}
// 장치를 찾았다면 데이터 링크의 정보를 iDataLink에 입력시킨다.
else
{
// 함수 원형 : int pcap_datalink(pcap_t *p)
// 함수 설명 : link layer 타입을 되돌려준다(DLT_EN10MB 과 같은)
iDataLink = pcap_datalink(adhandle);
}
// Datalink 정보를 출력
if(DLT_EN10MB == iDataLink)
{
printf("2Layter Type : [Ethernet 10Mb]\n");
stData.Layer2 = Layer2_Ether; // Regist Layer 2
}
else
{
// 정보가 없다면 찾지 못했음을 알리고 종료한다.
printf("2Layter Type : Not Ethernet Type...\n");
return 0;
}
printf("======================================================\n");
printf("=============== Packet Capture start! ================\n");
printf("======================================================\n");
// main roop 구문
do{
/* 원형 : u_char * pcap_next (pcap_t *p, struct pcap_pkthdr *h)
* 설명 : 다음 패킷의 포인터를 리턴한다.
* 인자 : pcap_t *p : 패킷 캡쳐 descriptor
* struct pcap_pkthdr *h : 패킷의 정보를 가리키고 있는 포인터
*/
ucData = pcap_next(adhandle, &stPInfo);
printf("Cap length : [%d]\n", stPInfo.caplen);
printf("Length : [%d]\n", stPInfo.len);
// 패킷의 크기가 400이하이면 무시
if(400 > stPInfo.caplen)
continue;
// 입력된 패킷의 정보를 PrintHexaNAscii함수를 사용하여
// 패킷의 크기만큼 출력한다.
PrintHexaNAscii(ucData, stPInfo.caplen);
printf("\n******************************************************\n");
printf("*************** Packet analysis Started **************\n");
printf("******************************************************\n");
stData.NProtocol = ucData;
stData.Layer2(&stData);
}while(stPInfo.caplen<400);
if(0 != stData.Layer3)
{
stData.Layer3(&stData);
}
// 모든 장치를 free시킨다.
pcap_freealldevs(alldevs);
return 0;
}
//////////////////////////////////////////////////////////////////////////
// Product Date : 2009/09/18 //
// Author : (Last) Lee //
// (First) Hyunbin //
// comment : This function is expression to IP Protocol in Layer3. //
// Layer3인 IP의 정보를 출력시는 함수. //
// 인지값 - INPUT(포인터의 방향을 표시) //
// void * vP (현재 패킷을 카리키는 포인터) //
// 반환값 - void //
//////////////////////////////////////////////////////////////////////////
void Layer3_IP(INPUT void * vP)
// vP : Packet struct Start Address
{
struct in_addr addr;
struct IP_HEADER* ihP
= (struct IP_HEADER*)(((Packet *)vP)->NProtocol);
((Packet*)vP)->NProtocol =(const u_char *)(ihP+1); // Next Protocol Address
//u_char* temp = (u_char*)(&(ihP->ip_src));
printf("======================================================\n");
printf("============== Layer 3 : IP Information ==============\n");
printf("======================================================\n");
printf("== Source -> Destination ==\n");
addr.s_addr = ihP->src;
printf("== %15s"
, inet_ntoa(addr)
);
addr.s_addr = ihP->dest;
printf(" -> %15s ==\n"
, inet_ntoa(addr)
);
printf("======================================================\n");
printf("== Version : IPv%1d ==\n",
((ihP->x)>>4));
printf("== Header Langth : %1d ==\n",
((ihP->x)&0x0f));
printf("== Type of service : %-2X ==\n",
ihP->tos);
printf("== Total Length : %-6d ==\n",
ntohs(ihP->length));
printf("== Identification : %-6d ==\n",
ntohs(ihP->identifier));
printf("== Fragment offset filed : %-4X ==\n",
ntohs(ihP->fragment));
printf("== Time to live : %-3d ==\n",
ntohs(ihP->ttl));
printf("== Protocol : %-2d ==\n",
ihP->protocol);
printf("== Checksum : %-8d ==\n",
ntohs(ihP->cksum));
printf("======================================================\n");
return;
}
// not used
void Layer3_ARP(INPUT void * vP)
// vP : Packet struct Start Address
{
return;
}
// not used
void Layer3_REVARP(INPUT void * vP)
// vP : Packet struct Start Address
{
return;
}
// not used
void Layer3_PUP(INPUT void * vP)
// vP : Packet struct Start Address
{
return;
}
//////////////////////////////////////////////////////////////////////////
// Product Date : 2009/09/18 //
// Author : (Last) Lee //
// (First) Hyunbin //
// comment : This function is expression to Ethernet Protocol in Layer2.//
// Layer2인 Ethernet의 정보를 출력시는 함수 //
// 인지값 - INPUT(포인터의 방향을 표시) //
// void * vP (현재 패킷을 카리키는 포인터) //
// 반환값 - void //
//////////////////////////////////////////////////////////////////////////
void Layer2_Ether(INPUT void * vP)
{
struct ETHERNET_FRAME* ehP
= (struct ETHERNET_FRAME*)(((Packet*)vP)->NProtocol);
((Packet*)vP)->NProtocol =(const u_char *)(ehP+1); // Next Protocol Address
printf("======================================================\n");
printf("=========== Layer 2 : Ethernet Information ==========\n");
printf("======================================================\n");
printf("== Source -> Destination ==\n");
printf("== %02X:%02X:%02X:%02X:%02X:%02X "
"-> %02X:%02X:%02X:%02X:%02X:%02X ==\n",
ehP->Source[0],
ehP->Source[1],
ehP->Source[2],
ehP->Source[3],
ehP->Source[4],
ehP->Source[5],
ehP->Destination[0],
ehP->Destination[1],
ehP->Destination[2],
ehP->Destination[3],
ehP->Destination[4],
ehP->Destination[5]
);
switch(ntohs(ehP->FrameType))
{
case ETHERTYPE_IP:
((Packet*)vP)->Layer3 = Layer3_IP;
break;
case ETHERTYPE_ARP:
((Packet*)vP)->Layer3 = Layer3_ARP;
break;
case ETHERTYPE_REVARP:
((Packet*)vP)->Layer3 = Layer3_REVARP;
break;
case ETHERTYPE_PUP:
((Packet*)vP)->Layer3 = Layer3_PUP;
break;
default:
break;
}
printf("======================================================\n");
return;
}
//////////////////////////////////////////////////////////////////////////
// Product Date : 2009/09/18 //
// Author : (Last) Lee //
// (First) Hyunbin //
// comment : This function is printed hexa and ascii code //
// 입력되는 버퍼의 내용을 hexa(16진수)와 //
// 아스키 코드(ascii code)로 출력 시키는 함수 //
// 인지값 - INPUT : 포인터의 방향을 표시, 즉 입력이란 의미 //
// const : 입력된 버퍼의 값은 함수 실행 도중에 변경되지 않음 //
// u_char *buffer : unsigned char pointer 형 변수 buffer //
// 반환값 - void //
//////////////////////////////////////////////////////////////////////////
void PrintHexaNAscii(INPUT const u_char *buffer, int size)
{
int loop_temp = 0;
int counter = 0;
printf("=======================================================================\n");
printf("Address 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D");
printf(" 0E 0F 123456789ABCDEF\n");
printf("=======================================================================\n");
counter = 0;
// 표현되는 크기의 제한
if(1200 < size)
size = 1200;
while(counter < size)
{
printf("0x%04X ",counter);
loop_temp = 0;
while(loop_temp < 16)
{
printf("%02X ", *buffer);
++buffer;
++loop_temp;
}
buffer = buffer -16;
loop_temp = 0;
while(loop_temp < 16)
{
// 아스키 코드로 인식되는 범위 이외의 값은 '.'으로 처리
if(31 > *buffer || 127 <= *buffer)
{
putchar('.');
}
else
{
putchar(*buffer);
}
++buffer;
++loop_temp;
}
counter = counter + loop_temp;
putchar('\n');
}
return;
}
// Product Date : 2009/09/18 //
// Author : (Last) Lee //
// (First) Hyunbin //
// comment : This Program is expression to Packet architecture~ //
// by used to winpcap library. //
// 인지값 - void //
// 반환값 - void //
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Preprocessor area
#include <pcap.h>
#include <pcap-bpf.h>
#include <protocol.h>
#pragma comment(lib,ws2_)
//////////////////////////////////////////////////////////////////////////
// Define area
#define INPUT // Pointer's direction
#define OUTPUT // Pointer's direction
#define ETH_ALEN 6
#define ETHERTYPE_PUP 0x0200 /* Xerox PUP */
#define ETHERTYPE_IP 0x0800 /* IP */
#define ETHERTYPE_ARP 0x0806 /* Address resolution */
#define ETHERTYPE_REVARP 0x8035 /* Reverse ARP */
//////////////////////////////////////////////////////////////////////////
// Packet structure
typedef struct _Packet
{
const u_char * NProtocol; // Next Protocol
void (*Layer2)(INPUT void*);
void (*Layer3)(INPUT void*);
void (*Layer4)(INPUT void*);
}Packet;
//////////////////////////////////////////////////////////////////////////
// Function Prototype area
void Layer2_Ether(INPUT void * vP);
void Layer3_IP(INPUT void * vP);
void Layer3_ARP(INPUT void * vP);
void Layer3_REVARP(INPUT void * vP);
void Layer3_PUP(INPUT void * vP);
void PrintHexaNAscii(const unsigned char *buffer, int size);
//////////////////////////////////////////////////////////////////////////
// Product Date : 2009/09/18 //
// Author : (Last) Lee //
// (First) Hyunbin //
// comment : This function is main Function. //
// 인지값 - void //
// 반환값 - void //
//////////////////////////////////////////////////////////////////////////
int main()
{
char errbuf[PCAP_ERRBUF_SIZE];
// 함수 원형 : char* pcap_lookupdev
// 함수 설명 : pcap_open_live() 와 pcap_lookupnet() 에서 사용하기 위한 네트웍 디바이스에
// 대한 포인터를 되돌려준다. 성공할 경우 "eth0", "eth1" 과 같은 이름을
// 되돌려주며 실패할경우 0을 되돌려준다.
char * spNetDevName = pcap_lookupdev(errbuf);
int iDataLink;
const u_char* ucData;
struct pcap_pkthdr stPInfo;
Packet stData; // Packet Information
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
int iCnt = 0;
pcap_t *adhandle;
char packet_filter[] = "ip and udp";
// stData구조체를 0으로 초기화
memset(&stData, 0, sizeof(stData));
// 모든 네트워크 디바이스의 정보를 찾아서 3번째 인자에 넘겨준다.
if (-1 == pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf))
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
// 찾은 모든 device의 정보 출력한다.
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
// device를 찾지 못했다면
if(i==0)
{
// 찾지 못했음을 알리고 종료한다.
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return -1;
}
// 원하는 device를 선택한다.
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
// 허용된 범위 이외의 값을 입력하면
if(inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
// device 디스크립터인 alldevs를 해제후 프로그램을 종료한다.
pcap_freealldevs(alldevs);
return -1;
}
// 선택한 device로 이동한다.
for(d=alldevs, iCnt=0; iCnt< inum-1 ;d=d->next, iCnt++);
// 선택한 device를 open한다.
if ( NULL == (adhandle= pcap_open(d->name, // name of the device
65536, // portion of the packet to capture.
// 65536 grants that the whole packet~
// will be captured on all the MACs.
PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
1000, // read timeout
NULL, // remote authentication
errbuf // error buffer
)
)
)
// 장치를 찾지 못했다면
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n");
// device를 free시킨다.
pcap_freealldevs(alldevs);
return -1;
}
// 마찬가지로 장치를 찾지 못했다면
if(0 == adhandle)
{
printf("Error : [%s]\n", errbuf);
return 101;
}
// 장치를 찾았다면 데이터 링크의 정보를 iDataLink에 입력시킨다.
else
{
// 함수 원형 : int pcap_datalink(pcap_t *p)
// 함수 설명 : link layer 타입을 되돌려준다(DLT_EN10MB 과 같은)
iDataLink = pcap_datalink(adhandle);
}
// Datalink 정보를 출력
if(DLT_EN10MB == iDataLink)
{
printf("2Layter Type : [Ethernet 10Mb]\n");
stData.Layer2 = Layer2_Ether; // Regist Layer 2
}
else
{
// 정보가 없다면 찾지 못했음을 알리고 종료한다.
printf("2Layter Type : Not Ethernet Type...\n");
return 0;
}
printf("======================================================\n");
printf("=============== Packet Capture start! ================\n");
printf("======================================================\n");
// main roop 구문
do{
/* 원형 : u_char * pcap_next (pcap_t *p, struct pcap_pkthdr *h)
* 설명 : 다음 패킷의 포인터를 리턴한다.
* 인자 : pcap_t *p : 패킷 캡쳐 descriptor
* struct pcap_pkthdr *h : 패킷의 정보를 가리키고 있는 포인터
*/
ucData = pcap_next(adhandle, &stPInfo);
printf("Cap length : [%d]\n", stPInfo.caplen);
printf("Length : [%d]\n", stPInfo.len);
// 패킷의 크기가 400이하이면 무시
if(400 > stPInfo.caplen)
continue;
// 입력된 패킷의 정보를 PrintHexaNAscii함수를 사용하여
// 패킷의 크기만큼 출력한다.
PrintHexaNAscii(ucData, stPInfo.caplen);
printf("\n******************************************************\n");
printf("*************** Packet analysis Started **************\n");
printf("******************************************************\n");
stData.NProtocol = ucData;
stData.Layer2(&stData);
}while(stPInfo.caplen<400);
if(0 != stData.Layer3)
{
stData.Layer3(&stData);
}
// 모든 장치를 free시킨다.
pcap_freealldevs(alldevs);
return 0;
}
//////////////////////////////////////////////////////////////////////////
// Product Date : 2009/09/18 //
// Author : (Last) Lee //
// (First) Hyunbin //
// comment : This function is expression to IP Protocol in Layer3. //
// Layer3인 IP의 정보를 출력시는 함수. //
// 인지값 - INPUT(포인터의 방향을 표시) //
// void * vP (현재 패킷을 카리키는 포인터) //
// 반환값 - void //
//////////////////////////////////////////////////////////////////////////
void Layer3_IP(INPUT void * vP)
// vP : Packet struct Start Address
{
struct in_addr addr;
struct IP_HEADER* ihP
= (struct IP_HEADER*)(((Packet *)vP)->NProtocol);
((Packet*)vP)->NProtocol =(const u_char *)(ihP+1); // Next Protocol Address
//u_char* temp = (u_char*)(&(ihP->ip_src));
printf("======================================================\n");
printf("============== Layer 3 : IP Information ==============\n");
printf("======================================================\n");
printf("== Source -> Destination ==\n");
addr.s_addr = ihP->src;
printf("== %15s"
, inet_ntoa(addr)
);
addr.s_addr = ihP->dest;
printf(" -> %15s ==\n"
, inet_ntoa(addr)
);
printf("======================================================\n");
printf("== Version : IPv%1d ==\n",
((ihP->x)>>4));
printf("== Header Langth : %1d ==\n",
((ihP->x)&0x0f));
printf("== Type of service : %-2X ==\n",
ihP->tos);
printf("== Total Length : %-6d ==\n",
ntohs(ihP->length));
printf("== Identification : %-6d ==\n",
ntohs(ihP->identifier));
printf("== Fragment offset filed : %-4X ==\n",
ntohs(ihP->fragment));
printf("== Time to live : %-3d ==\n",
ntohs(ihP->ttl));
printf("== Protocol : %-2d ==\n",
ihP->protocol);
printf("== Checksum : %-8d ==\n",
ntohs(ihP->cksum));
printf("======================================================\n");
return;
}
// not used
void Layer3_ARP(INPUT void * vP)
// vP : Packet struct Start Address
{
return;
}
// not used
void Layer3_REVARP(INPUT void * vP)
// vP : Packet struct Start Address
{
return;
}
// not used
void Layer3_PUP(INPUT void * vP)
// vP : Packet struct Start Address
{
return;
}
//////////////////////////////////////////////////////////////////////////
// Product Date : 2009/09/18 //
// Author : (Last) Lee //
// (First) Hyunbin //
// comment : This function is expression to Ethernet Protocol in Layer2.//
// Layer2인 Ethernet의 정보를 출력시는 함수 //
// 인지값 - INPUT(포인터의 방향을 표시) //
// void * vP (현재 패킷을 카리키는 포인터) //
// 반환값 - void //
//////////////////////////////////////////////////////////////////////////
void Layer2_Ether(INPUT void * vP)
{
struct ETHERNET_FRAME* ehP
= (struct ETHERNET_FRAME*)(((Packet*)vP)->NProtocol);
((Packet*)vP)->NProtocol =(const u_char *)(ehP+1); // Next Protocol Address
printf("======================================================\n");
printf("=========== Layer 2 : Ethernet Information ==========\n");
printf("======================================================\n");
printf("== Source -> Destination ==\n");
printf("== %02X:%02X:%02X:%02X:%02X:%02X "
"-> %02X:%02X:%02X:%02X:%02X:%02X ==\n",
ehP->Source[0],
ehP->Source[1],
ehP->Source[2],
ehP->Source[3],
ehP->Source[4],
ehP->Source[5],
ehP->Destination[0],
ehP->Destination[1],
ehP->Destination[2],
ehP->Destination[3],
ehP->Destination[4],
ehP->Destination[5]
);
switch(ntohs(ehP->FrameType))
{
case ETHERTYPE_IP:
((Packet*)vP)->Layer3 = Layer3_IP;
break;
case ETHERTYPE_ARP:
((Packet*)vP)->Layer3 = Layer3_ARP;
break;
case ETHERTYPE_REVARP:
((Packet*)vP)->Layer3 = Layer3_REVARP;
break;
case ETHERTYPE_PUP:
((Packet*)vP)->Layer3 = Layer3_PUP;
break;
default:
break;
}
printf("======================================================\n");
return;
}
//////////////////////////////////////////////////////////////////////////
// Product Date : 2009/09/18 //
// Author : (Last) Lee //
// (First) Hyunbin //
// comment : This function is printed hexa and ascii code //
// 입력되는 버퍼의 내용을 hexa(16진수)와 //
// 아스키 코드(ascii code)로 출력 시키는 함수 //
// 인지값 - INPUT : 포인터의 방향을 표시, 즉 입력이란 의미 //
// const : 입력된 버퍼의 값은 함수 실행 도중에 변경되지 않음 //
// u_char *buffer : unsigned char pointer 형 변수 buffer //
// 반환값 - void //
//////////////////////////////////////////////////////////////////////////
void PrintHexaNAscii(INPUT const u_char *buffer, int size)
{
int loop_temp = 0;
int counter = 0;
printf("=======================================================================\n");
printf("Address 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D");
printf(" 0E 0F 123456789ABCDEF\n");
printf("=======================================================================\n");
counter = 0;
// 표현되는 크기의 제한
if(1200 < size)
size = 1200;
while(counter < size)
{
printf("0x%04X ",counter);
loop_temp = 0;
while(loop_temp < 16)
{
printf("%02X ", *buffer);
++buffer;
++loop_temp;
}
buffer = buffer -16;
loop_temp = 0;
while(loop_temp < 16)
{
// 아스키 코드로 인식되는 범위 이외의 값은 '.'으로 처리
if(31 > *buffer || 127 <= *buffer)
{
putchar('.');
}
else
{
putchar(*buffer);
}
++buffer;
++loop_temp;
}
counter = counter + loop_temp;
putchar('\n');
}
return;
}
반응형