일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- kmip
- git
- 애플
- SWIFT
- WebAuthn
- fido
- 앱리소스
- albumbook
- OTP
- Android
- otpkey
- css
- FIDO2
- Xcode
- apple
- MYSQL
- MFA
- 앨범북
- MSYS2
- SwiftUI
- SSL
- 2FA
- 인증
- openssl
- Nodejs
- 안드로이드
- SSH
- OSX
- 앱스토어
- appres
Archives
- Today
- Total
인디노트
ICMP ping 구현의 C 코드 본문
#include <stdio.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <string>
#define TIME_LOOP_WAIT 200000 // 200ms
#define COUNT_CHECK_LOOP 5
#define SIZE_ICMP_PACKET 64
using namespace std;
struct ICMP_PACKET {
struct icmphdr hdr;
char msg[SIZE_ICMP_PACKET - sizeof(struct icmphdr)];
} typedef ICMP_PACKET_t;
/* functions */
unsigned short checksum(void* _data, int _length) {
unsigned short* p_data;
unsigned short result;
unsigned int sum = 0;
p_data = (unsigned short*)_data;
for (sum = 0; _length > 1; _length -= 2) {
sum += *p_data++;
}
if( _length == 1 ) {
sum += *(unsigned char*)p_data;
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
result = ~sum;
return result;
}
bool icmp(string _address) {
const int sock_value = 255;
int socket_fd;
int num_sequence = 1;
int pid = getpid();
int idx;
struct sockaddr_in r_addr;
struct hostent *hname;
struct sockaddr_in addr_ping,*addr;
ICMP_PACKET_t pckt;
int size_packet_msg = sizeof(pckt.msg);
struct protoent *t_proto = NULL;
socklen_t len;
t_proto = getprotobyname("ICMP");
hname = gethostbyname(_address.c_str());
bzero(&addr_ping, sizeof(addr_ping));
addr_ping.sin_family = hname->h_addrtype;
addr_ping.sin_port = 0;
addr_ping.sin_addr.s_addr = *(long*)hname->h_addr;
addr = &addr_ping;
if( (socket_fd = socket(PF_INET, SOCK_RAW, t_proto->p_proto)) < 0 ) {
printf("icmp() socket open failed : [%02d] %s\n", errno, strerror(errno));
return false;
}
if( setsockopt(socket_fd, SOL_IP, IP_TTL, &sock_value, sizeof(sock_value)) != 0) {
printf("icmp() set TTL option failed : [%02d] %s\n", errno, strerror(errno));
return false;
}
if ( fcntl(socket_fd, F_SETFL, O_NONBLOCK) != 0 ) {
printf("icmp() request nonblocking I/O failed : [%02d] %s\n", errno, strerror(errno));
return false;
}
for( int loop_cnt = 0 ; loop_cnt < COUNT_CHECK_LOOP ; loop_cnt++ ) {
len = sizeof(r_addr);
if( recvfrom(socket_fd, &pckt, sizeof(pckt), 0x00, (struct sockaddr*)&r_addr, &len) > 0 ) {
close(socket_fd);
return true;
}
bzero(&pckt, sizeof(pckt));
pckt.hdr.type = ICMP_ECHO;
pckt.hdr.un.echo.id = pid;
for( idx = 0; idx < size_packet_msg - 1 ; idx++ ) {
pckt.msg[idx] = idx + '0';
}
pckt.msg[idx] = 0;
pckt.hdr.un.echo.sequence = num_sequence++;
pckt.hdr.checksum = checksum(&pckt, sizeof(pckt));
if( sendto(socket_fd, &pckt, sizeof(pckt), 0, (struct sockaddr*)addr, sizeof(*addr)) <= 0 ) {
printf("icmp() sendto failed : [%02d] %s\n", errno, strerror(errno));
}
usleep(TIME_LOOP_WAIT);
}
close(socket_fd);
return false;
}
/* main function */
int main(int _argc, char *_argv[]) {
// target: google DNS
if( icmp("8.8.8.8") ) {
printf("icmp() status : [success]\n");
} else {
printf("icmp() status : [failed]\n");
}
return 0;
}
반응형
'개발 플랫폼 및 언어 > 네트워크 기술' 카테고리의 다른 글
ethhdr 의 src 및 dst 를 변경하는 C 코드 (0) | 2023.04.13 |
---|---|
iphdr 를 이용해서 tcphdr 를 찾는 C 코드 (0) | 2023.04.13 |
TCP 전송의 C 코드 (0) | 2023.04.12 |
sendto 로 UDP 데이터 전송 C 코드 (0) | 2023.04.12 |
NIC 맥주소 가져오는 C 코드 (0) | 2023.04.11 |
Comments