'Programming/Network'에 해당되는 글 14건
- 2011/03/08 조재혁 Wake on LAN (WOL)에 대한 예제
- 2011/01/27 조재혁 [예제] CGI에서의 Query string 환경변수의 name과 value를 분리하기
- 2008/09/09 조재혁 [C/Network/ICMP(v6)] ping 구현 예제 #2 - 20080909 (3)
- 2008/09/01 조재혁 [Network기초] IPv4 구조 (4)
- 2008/09/01 조재혁 [Network기초] Ethenet frame
- 2008/09/01 조재혁 [Network기초] OSI 7계층모델
- 2007/05/25 조재혁 TCP socket - epoll 사용예제
- 2007/05/09 조재혁 ping (ICMP/RAW socket) 예제 (1)
- 2007/05/08 조재혁 멀티캐스트(Multicast) 송/수신 예제
- 2007/05/08 조재혁 비동기 수신 (ASync read)
- 2007/05/08 조재혁 "rdate" 명령과 흡사하게 구현하기
- 2007/05/08 조재혁 간단히 구현한 ifconfig 예제
- 2007/05/07 조재혁 안걸리는 스텔스 포트 스캔 소스코드
- 2007/05/05 조재혁 Non-blocking connection (비블럭 연결)
Wake on LAN (WOL)에 대한 예제를 만들어 봤습니다.
최신 소스는 "http://www.hwport.com/wiki.php/WakeOnLAN"에서 보실수 있습니다.
/*
Copyright (C) JAEHYUK CHO
All rights reserved.
Code by JaeHyuk Cho <mailto:minzkn@minzkn.com>
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(int s_argc, char **s_argv);
int main(int s_argc, char **s_argv)
{
static const unsigned char s_target_mac[6] = {
0x44u, 0x87u, 0xfcu, 0x8fu, 0xbbu, 0xb4u
};
int s_socket;
struct sockaddr_in s_sockaddr_in;
unsigned char s_magic_packet[ 6 + (6 * 16) ];
int s_repeat;
ssize_t s_send_bytes;
int s_value;
/* UDP socket open */
s_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(s_socket == (-1)) {
perror("socket");
return(EXIT_FAILURE);
}
/* bind */
(void)memset((void *)(&s_sockaddr_in), 0, sizeof(s_sockaddr_in));
s_sockaddr_in.sin_family = AF_INET;
s_sockaddr_in.sin_addr.s_addr = htonl(INADDR_ANY);
s_sockaddr_in.sin_port = htons(0);
if(bind(s_socket, (const struct sockaddr *)(&s_sockaddr_in), (socklen_t)sizeof(s_sockaddr_in)) == (-1)) {
perror("bind");
(void)close(s_socket);
return(EXIT_FAILURE);
}
/* broadcast socket option enable */
s_value = 1;
(void)setsockopt(s_socket, SOL_SOCKET, SO_BROADCAST, (const void *)(&s_value), (socklen_t)sizeof(s_value));
/* WOL packet build (repeat 6) */
(void)memset((void *)(&s_magic_packet[0]), 0xff, (size_t)6u);
for(s_repeat = 0;s_repeat < 16;s_repeat++) {
(void)memcpy((void *)(&s_magic_packet[6 + (s_repeat * 6)]), (const void *)(&s_target_mac[0]), sizeof(s_target_mac));
}
/* broadcast socket address structure set */
(void)memset((void *)(&s_sockaddr_in), 0, sizeof(s_sockaddr_in));
s_sockaddr_in.sin_family = AF_INET;
(void)inet_pton(s_sockaddr_in.sin_family, "255.255.255.255", (void *)(&s_sockaddr_in.sin_addr));
s_sockaddr_in.sin_port = htons(2304); /* any port ... */
/* send */
s_send_bytes = sendto(
s_socket,
(const void *)(&s_magic_packet[0]),
sizeof(s_magic_packet),
0,
(const struct sockaddr *)(&s_sockaddr_in),
(socklen_t)sizeof(s_sockaddr_in)
);
if(s_send_bytes == ((ssize_t)(-1))) {
perror("sendto");
(void)close(s_socket);
return(EXIT_FAILURE);
}
(void)fprintf(stdout,
"WOL packet : %ld bytes (Target %02X:%02X:%02X:%02X:%02X:%02X)\n",
(long)s_send_bytes,
(unsigned int)s_target_mac[0], (unsigned int)s_target_mac[1], (unsigned int)s_target_mac[2],
(unsigned int)s_target_mac[3], (unsigned int)s_target_mac[4], (unsigned int)s_target_mac[5]
);
/* socket close */
(void)close(s_socket);
return(EXIT_SUCCESS);
}
/* vim: set expandtab: */
/* End of source */
댓글+트랙백 RSS :: http://blog.hwport.com/rss/response/613
댓글+트랙백 ATOM :: http://blog.hwport.com/atom/response/613
구현외에 고려할게 더 있지만 이정도면 무난히 사용할수 있는 코드라이브러리일듯...
/*
Copyright (C) HWPORT.COM
All rights reserved.
Code by JaeHyuk Cho <mailto:minzkn@minzkn.com>
*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/select.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
char *decode_percent_string(char *s_string);
int main(int s_argc, char **s_argv);
char *decode_percent_string(char *s_string)
{
size_t s_from_offset;
size_t s_to_offset;
int s_byte;
s_from_offset = (size_t)0u;
s_to_offset = (size_t)0u;
for(;;) {
if(s_string[s_from_offset] == '\0') {
s_string[s_to_offset] = '\0';
break;
}
if(s_string[s_from_offset] == '%') {
if(sscanf(&s_string[++s_from_offset], "%02x", &s_byte) == 1) {
s_from_offset += (size_t)2u;
s_string[s_to_offset++] = s_byte;
continue;
}
s_string[s_to_offset++] = '%';
}
/* copy */
s_string[s_to_offset++] = s_string[s_from_offset++];
}
return(s_string);
}
int main(int s_argc, char **s_argv)
{
/* echo -e "&tPost=5678" | QUERY_STRING="tGet=1234" ./a.out */
size_t s_buffer_size;
char *s_buffer;
ssize_t s_read_bytes;
fd_set s_fd_rx;
struct timeval s_timeval;
char *s_string, *s_save_string;
char *s_string2, *s_save_string2;
char *s_name, *s_value;
const char *s_env;
#if 1L
s_buffer_size = (size_t)(64 << 10); /* 64KBytes */
#else
s_buffer_size = (size_t)(16 << 20); /* 16MBytes */
#endif
s_buffer = malloc(s_buffer_size);
if(s_buffer == NULL) {
return(EXIT_FAILURE);
}
/* ---- read POST ---- */
/* SELECT */
FD_ZERO(&s_fd_rx);
FD_SET(STDIN_FILENO, &s_fd_rx);
s_timeval.tv_sec = 0;
s_timeval.tv_usec = 0;
s_read_bytes = 0;
if(select(STDIN_FILENO + 1, &s_fd_rx, NULL, NULL, &s_timeval) == 1) {
if(FD_ISSET(STDIN_FILENO, &s_fd_rx) != 0) {
s_read_bytes = read(STDIN_FILENO, s_buffer, s_buffer_size - 1);
}
}
/* READ */
if(s_read_bytes > ((ssize_t)0)) {
while(s_read_bytes > 0) {
--s_read_bytes;
if((s_buffer[s_read_bytes] != '\r') && (s_buffer[s_read_bytes] != '\n')) {
s_buffer[s_read_bytes] = '\0';
break;
}
}
s_buffer[s_read_bytes] = '\0';
}
else {
s_buffer[0] = '\0';
}
s_env = getenv("QUERY_STRING");
/* ---- read GET ---- */
if(s_env != ((const char *)0)) {
if(strlen(s_buffer) > 0) {
strncat(s_buffer, "&", s_buffer_size);
}
strncat(s_buffer, s_env, s_buffer_size);
}
s_buffer[ s_buffer_size - 1 ] = '\0';
/* ---- do parse ---- */
s_string = s_save_string = /* ... */ s_buffer;
for(;;) {
s_string = strtok_r(s_string, "&", &s_save_string);
if(s_string == NULL) {
break;
}
(void)fprintf(stdout, "[%s]\n", s_string);
s_string2 = s_save_string2 = s_string;
s_name = strtok_r(s_string2, "=", &s_save_string2);
s_value = decode_percent_string(s_save_string2);
(void)fprintf(stdout, "\t[%s]=[%s]\n", s_name, s_value);
s_string = s_save_string;
}
free(s_buffer);
return(0);
}
/* End of source */
댓글+트랙백 RSS :: http://blog.hwport.com/rss/response/606
댓글+트랙백 ATOM :: http://blog.hwport.com/atom/response/606
이것은 ICMP 및 ICMPv6를 사용한 ping구현에 대한 예제성격의 소스입니다.
옛날에도 제가 ping 을 간략하게 구현한바 있었죠.
이번에 올리는것은 그때버젼보다는 좀더 완성도가 있는 버젼이라고 말할수 있겠습니다.
게다가 IPv6를 고려한 ICMPv6를 구현한 부분도 추가되었습니다.
물론 아직도 완전한 버젼은 아니고 다음에 또 기회가 되면 좀더 완성해서 올려볼까 합니다.
테스트 하실때는 당연히 RAW socket을 사용하기 때문에 root 권한으로 실행하셔야 합니다.
/*
Copyright (C) INFOEQ co.,LTD.
All rights reserved.
Author: JaeHyuk Cho <minzkn@infoeq.com>Tiny ping example source
*//* need for "struct addrinfo" */
#if 1L && (!defined(_POSIX_SOURCE))
# define _POSIX_SOURCE (1L)
#endif#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>#define def_mzping_icmp_optimize (1)
#define def_mzping_icmp_min_packet_size (1 + 1 + 2 + 2 + 2) /* type(1) + code(1) + checksum(2) + identifier(2) + sequence_number(2) */
static unsigned int mzping_icmp_checksum(const void *s_data, size_t s_size);
static unsigned int mzping_ts32_us(void);
static int mzping_icmp_v4(int s_socket, const char *s_hostname, const char *s_address_string, struct addrinfo *s_addrinfo, int s_sequence_number, int s_timeout);
static int mzping_icmp_v6(int s_socket, const char *s_hostname, const char *s_address_string, struct addrinfo *s_addrinfo, int s_sequence_number, int s_timeout);int mzping(const char *s_hostname, int s_count);
int main(int s_argc, char **s_argv);
static unsigned int mzping_icmp_checksum(const void *s_data, size_t s_size)
{
register unsigned int s_result = 0u;while(s_size > ((size_t)1)) {
#if def_mzping_icmp_optimize == (0)
s_result += (unsigned int)(ntohs(*((const unsigned short int *)s_data)));
#else
s_result += (unsigned int)(*((const unsigned short int *)s_data));
#endif
s_data = ((const unsigned short int *)s_data) + ((size_t)1);
s_size -= (size_t)2;
}
if(s_size > ((size_t)0)) {
s_result += (unsigned int)(*((const unsigned char *)s_data));
}#if def_mzping_icmp_optimize == (0)
while(s_result > 0xffffu) {
s_result = (s_result >> 16) + (s_result & 0xffffu);
}
#else
s_result = (s_result >> 16) + (s_result & 0xffffu);
s_result += s_result >> 16;
#endif#if def_mzping_icmp_optimize == (0)
return(htons((~s_result) & 0xffffu));
#else
return((~s_result) & 0xffffu);
#endif
}static unsigned int mzping_ts32_us(void)
{
struct timeval s_timeval;
(void)gettimeofday((struct timeval *)(&s_timeval), (void *)0);
return((s_timeval.tv_sec * 1000000u) + s_timeval.tv_usec);
}static int mzping_icmp_v4(int s_socket, const char *s_hostname, const char *s_address_string, struct addrinfo *s_addrinfo, int s_sequence_number, int s_timeout)
{
int s_result, s_check, s_myid;
unsigned char s_packet[ (20 + 40) + (def_mzping_icmp_min_packet_size + 4) ];
size_t s_packet_size;
ssize_t s_send_bytes;
size_t s_ip_header_size;
fd_set s_fd_rx;
struct timeval s_timeval;
ssize_t s_recv_bytes;
socklen_t s_socklen_in;
struct sockaddr_in s_sockaddr_in;s_result = (-1);
s_myid = (int)(getpid() & 0xffff);s_packet_size = (size_t)0;
s_packet[s_packet_size] = 8u; /* ICMP_ECHO */
s_packet_size += (size_t)1;
s_packet[s_packet_size] = 0u; /* code */
s_packet_size += (size_t)1;
*((unsigned short int *)(&s_packet[s_packet_size])) = 0u; /* checksum */
s_packet_size += (size_t)2;
*((unsigned short int *)(&s_packet[s_packet_size])) = htons(s_myid); /* identifier */
s_packet_size += (size_t)2;
*((unsigned short int *)(&s_packet[s_packet_size])) = htons(s_sequence_number); /* sequence number */
s_packet_size += (size_t)2;
#if def_mzping_icmp_optimize == (0)
*((unsigned int *)(&s_packet[8])) = htonl(mzping_ts32_us()); /* optional: time stamp */
#else
*((unsigned int *)(&s_packet[8])) = (unsigned int)mzping_ts32_us(); /* optional: time stamp */
#endif
s_packet_size += (size_t)4;/* do checksum */
*((unsigned short int *)(&s_packet[2])) = mzping_icmp_checksum((const void *)(&s_packet[0]), s_packet_size); /* checksum */
s_send_bytes = sendto(s_socket, (const void *)(&s_packet[0]), s_packet_size, MSG_NOSIGNAL,
(struct sockaddr *)s_addrinfo->ai_addr, s_addrinfo->ai_addrlen);
if(s_send_bytes != ((ssize_t)s_packet_size)) {
(void)fprintf(stderr, "send: can not send %ld/%lu\n", (long)s_send_bytes, (unsigned long)sizeof(s_packet));
return(-1);
}l_need_echoreply:;
FD_ZERO(&s_fd_rx);
FD_SET(s_socket, &s_fd_rx);
s_timeval.tv_sec = s_timeout / 1000;
s_timeval.tv_usec = (s_timeout % 1000) * 1000;
s_check = select(s_socket + 1, (fd_set *)(&s_fd_rx), (fd_set *)0, (fd_set *)0, (struct timeval *)(&s_timeval));
if(s_check == (-1)) {
perror("select");
return(-1);
}
if(s_check == 0) {
(void)fprintf(stderr, "select: timeout\n");
return(-1);
}
if(FD_ISSET(s_socket, &s_fd_rx) == 0) {
(void)fprintf(stderr, "select: is not set\n");
return(-1);
}s_socklen_in = (socklen_t)sizeof(s_sockaddr_in);
s_recv_bytes = recvfrom(s_socket, (void *)(&s_packet[0]), sizeof(s_packet), MSG_NOSIGNAL, (struct sockaddr *)(&s_sockaddr_in), (socklen_t *)(&s_socklen_in));
if(s_recv_bytes == ((ssize_t)(-1))) {
perror("recvfrom");
return(-1);
}
s_ip_header_size = ((size_t)((s_packet[0] >> 0) & 0x0fu)) << 2;
if(s_recv_bytes < (s_ip_header_size + s_packet_size)) {
/* (void)fprintf(stderr, "too small packet\n"); */
goto l_need_echoreply;
}if(ntohs(*((unsigned short int *)(&s_packet[s_ip_header_size + 4]))) != s_myid) {
/* (void)fprintf(stderr, "not my ping\n"); */
goto l_need_echoreply;
}
if(s_packet[s_ip_header_size] == 8u /* ICMP_ECHO */) { /* maybe localhost loopback case */
goto l_need_echoreply;
}if(s_packet[s_ip_header_size] == 0u /* ICMP_ECHOREPLY */) {
unsigned int s_trip_time;
s_result = (int)ntohs(*((unsigned short int *)(&s_packet[s_ip_header_size + 1 + 1 + 2 + 2])));
#if def_mzping_icmp_optimize == (0)
s_trip_time = mzping_ts32_us() - ntohl(*((unsigned int *)(&s_packet[s_ip_header_size + def_mzping_icmp_min_packet_size])));
#else
s_trip_time = mzping_ts32_us() - (*((unsigned int *)(&s_packet[s_ip_header_size + def_mzping_icmp_min_packet_size])));
#endif
(void)fprintf(stdout, "%ld bytes from %s (%s): icmp_seq=%d ttl=%u time=%u.%03u ms;\n",
(unsigned long)(s_recv_bytes - (s_ip_header_size)),
s_hostname,
s_address_string,
s_result,
(unsigned int)s_packet[8],
s_trip_time / 1000u,
s_trip_time % 1000u);
}return(s_result);
}static int mzping_icmp_v6(int s_socket, const char *s_hostname, const char *s_address_string, struct addrinfo *s_addrinfo, int s_sequence_number, int s_timeout)
{
int s_result, s_check, s_myid;
unsigned char s_packet[ (def_mzping_icmp_min_packet_size + 4) ];
size_t s_packet_size;
ssize_t s_send_bytes;fd_set s_fd_rx;
struct timeval s_timeval;
ssize_t s_recv_bytes;
socklen_t s_socklen_in;
struct sockaddr_in s_sockaddr_in;s_result = (-1);
s_myid = (int)(getpid() & 0xffff);s_packet_size = (size_t)0;
s_packet[s_packet_size] = 128u; /* ICMP6_ECHO_REQUEST */
s_packet_size += (size_t)1;
s_packet[s_packet_size] = 0u; /* code */
s_packet_size += (size_t)1;
*((unsigned short int *)(&s_packet[s_packet_size])) = 0u; /* checksum */
s_packet_size += (size_t)2;
*((unsigned short int *)(&s_packet[s_packet_size])) = htons(s_myid); /* identifier */
s_packet_size += (size_t)2;
*((unsigned short int *)(&s_packet[s_packet_size])) = htons(s_sequence_number); /* sequence number */
s_packet_size += (size_t)2;
#if def_mzping_icmp_optimize == (0)
*((unsigned int *)(&s_packet[8])) = htonl(mzping_ts32_us()); /* optional: time stamp */
#else
*((unsigned int *)(&s_packet[8])) = (unsigned int)mzping_ts32_us(); /* optional: time stamp */
#endif
s_packet_size += (size_t)4;/* do checksum */
*((unsigned short int *)(&s_packet[2])) = mzping_icmp_checksum((const void *)(&s_packet[0]), s_packet_size); /* checksum */s_send_bytes = sendto(s_socket, (const void *)(&s_packet[0]), s_packet_size, MSG_NOSIGNAL,
(struct sockaddr *)s_addrinfo->ai_addr, s_addrinfo->ai_addrlen);
if(s_send_bytes != ((ssize_t)s_packet_size)) {
(void)fprintf(stderr, "send: can not send %ld/%lu\n", (long)s_send_bytes, (unsigned long)sizeof(s_packet));
return(-1);
}l_need_echoreply:;
FD_ZERO(&s_fd_rx);
FD_SET(s_socket, &s_fd_rx);
s_timeval.tv_sec = s_timeout / 1000;
s_timeval.tv_usec = (s_timeout % 1000) * 1000;
s_check = select(s_socket + 1, (fd_set *)(&s_fd_rx), (fd_set *)0, (fd_set *)0, (struct timeval *)(&s_timeval));
if(s_check == (-1)) {
perror("select");
return(-1);
}
if(s_check == 0) {
(void)fprintf(stderr, "select: timeout\n");
return(-1);
}
if(FD_ISSET(s_socket, &s_fd_rx) == 0) {
(void)fprintf(stderr, "select: is not set\n");
return(-1);
}
s_socklen_in = (socklen_t)sizeof(s_sockaddr_in);
s_recv_bytes = recvfrom(s_socket, (void *)(&s_packet[0]), sizeof(s_packet), MSG_NOSIGNAL, (struct sockaddr *)(&s_sockaddr_in), (socklen_t *)(&s_socklen_in));
if(s_recv_bytes == ((ssize_t)(-1))) {
perror("recvfrom");
return(-1);
}
if(s_recv_bytes < s_packet_size) {
/* (void)fprintf(stderr, "too small packet\n"); */
goto l_need_echoreply;
}
if(ntohs(*((unsigned short int *)(&s_packet[4]))) != s_myid) {
/* (void)fprintf(stderr, "not my ping\n"); */
goto l_need_echoreply;
}if(s_packet[0] == 128u /* ICMP6_ECHO_REQUEST */) {
goto l_need_echoreply;
}
if(s_packet[0] == 129u /* ICMP6_ECHO_REPLY */) {
unsigned int s_trip_time;
s_result = (int)ntohs(*((unsigned short int *)(&s_packet[1 + 1 + 2 + 2])));
#if def_mzping_icmp_optimize == (0)
s_trip_time = mzping_ts32_us() - ntohl(*((unsigned int *)(&s_packet[def_mzping_icmp_min_packet_size])));
#else
s_trip_time = mzping_ts32_us() - (*((unsigned int *)(&s_packet[def_mzping_icmp_min_packet_size])));
#endif
(void)fprintf(stdout, "%ld bytes from %s (%s): icmp_seq=%d ttl=%u time=%u.%03u ms;\n",
(unsigned long)s_recv_bytes,
s_hostname,
s_address_string,
s_result,
(unsigned int)0u /* TODO: Hops limit here */,
s_trip_time / 1000u,
s_trip_time % 1000u);
}return(s_result);
}int mzping(const char *s_hostname, int s_count)
{
int s_sequence_number = 0, s_check, s_socket;
struct addrinfo *s_addrinfo_result;
struct addrinfo s_addrinfo_hints;
struct addrinfo *s_addrinfo;
char s_address_string[ 64 ];
/* resolv name */
(void)memset((void *)(&s_addrinfo_hints), 0, sizeof(s_addrinfo_hints));
s_addrinfo_hints.ai_socktype = SOCK_RAW;
s_addrinfo_hints.ai_family = AF_UNSPEC;
s_check = getaddrinfo(s_hostname, (const char *)0, (const struct addrinfo *)(&s_addrinfo_hints), (struct addrinfo **)(&s_addrinfo_result));
if(s_check != 0) {
(void)fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(s_check));
return(-1);
}do {
s_sequence_number++;for(s_addrinfo = s_addrinfo_result;s_addrinfo != ((struct addrinfo *)0);s_addrinfo = s_addrinfo->ai_next) {
if(s_addrinfo->ai_family == AF_INET) { /* ICMP */
struct sockaddr_in *s_in;s_socket = socket(s_addrinfo->ai_family, SOCK_RAW, IPPROTO_ICMP);
if(s_socket == (-1)) {
perror("socket");
continue;
}s_in = (struct sockaddr_in *)s_addrinfo->ai_addr;
inet_ntop(s_addrinfo->ai_family, (const void *)(&s_in->sin_addr), (char *)(&s_address_string[0]), (socklen_t)sizeof(s_address_string));
s_check = mzping_icmp_v4(s_socket, s_hostname, (const char *)(&s_address_string[0]), s_addrinfo, s_sequence_number, 20000);
close(s_socket);
}
else if(s_addrinfo->ai_family == AF_INET6) { /* ICMPv6 */
struct sockaddr_in6 *s_in6;
s_socket = socket(s_addrinfo->ai_family, SOCK_RAW, IPPROTO_ICMPV6);
if(s_socket == (-1)) {
perror("socket");
continue;
}
s_in6 = (struct sockaddr_in6 *)s_addrinfo->ai_addr;
inet_ntop(s_addrinfo->ai_family, (const void *)(&s_in6->sin6_addr), (char *)(&s_address_string[0]), (socklen_t)sizeof(s_address_string));
s_check = mzping_icmp_v6(s_socket, s_hostname, (const char *)(&s_address_string[0]), s_addrinfo, s_sequence_number, 20000);
close(s_socket);
}
}(void)sleep(1);
}while(s_sequence_number < s_count);freeaddrinfo((struct addrinfo *)s_addrinfo_result);
return(1);
}
int main(int s_argc, char **s_argv)
{
int s_count = 4;
(void)fprintf(stdout, "mzping v0.0.2 - Code by JaeHyuk Cho <minzkn@minzkn.com>\n");if(s_argc <= 1) {
(void)fprintf(stdout, "usage: %s <host> <count>\n", (char *)s_argv[0]);
/* (void)mzping("localhost", s_count); */return(EXIT_SUCCESS);
}if(s_argc >= 3) {
if(sscanf(s_argv[2], "%i", &s_count) != 1) {
perror("count");
return(EXIT_FAILURE);
}
}(void)setuid(getuid());
(void)mzping(s_argv[1], s_count);return(EXIT_SUCCESS);
}/* vim: set expandtab: */
/* End of source */
댓글+트랙백 RSS :: http://blog.hwport.com/rss/response/484
댓글+트랙백 ATOM :: http://blog.hwport.com/atom/response/484
http://www.hwport.com/wiki.php/IPv4 으로 내용이 이동되었습니다.
댓글+트랙백 RSS :: http://blog.hwport.com/rss/response/480
댓글+트랙백 ATOM :: http://blog.hwport.com/atom/response/480
http://www.hwport.com/wiki.php/Ethernet 으로 내용이 이동되었습니다.
댓글+트랙백 RSS :: http://blog.hwport.com/rss/response/479
댓글+트랙백 ATOM :: http://blog.hwport.com/atom/response/479
http://www.hwport.com/wiki.php/OSI_7LayerModel 으로 내용이 이동되었습니다.
댓글+트랙백 RSS :: http://blog.hwport.com/rss/response/478
댓글+트랙백 ATOM :: http://blog.hwport.com/atom/response/478
epoll 에 대하여 간단히 구현했던 예제입니다.
kernel, libc 가 해당 epoll_create, epoll_wait, epoll_ctl 을 지원해야 합니다. 해당 코드가 실행되지 않거나 컴파일되지 않으면 배포판을 최근것으로 바꾸어 테스트 하세요.
epoll의 장점을 꼽으라고 한다면 속도는 잘 모르겠으나 select 보다는 fd 검사가 필요한만큼만 이루어지므로 약간의 속도향상이 기대됩니다.
하지만 다중 fd 를 활용하지 않는 경우는 poll이 더 좋을거 같습니다. (어디까지나 개인적인 생각입니다.)
| 코드: |
| /* Copyright (C) Information Equipment co.,LTD All rights reserved. Code by JaeHyuk Cho <mailto:minzkn@infoeq.com> CVSTAG="$Header$" */ #include <sys/types.h> #include <sys/socket.h> #include <sys/epoll.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <netdb.h> #include <signal.h> #include <errno.h> int g_break_listen = 0; void (my_signal)(int s_signal) { switch(s_signal) { case SIGINT: case SIGTERM: g_break_listen = 1; (void)signal(s_signal, my_signal); break; case SIGPIPE: (void)fprintf(stdout, "broken pipe\n"); break; case SIGSEGV: g_break_listen = 1; (void)fprintf(stdout, "segment fault\n"); (void)raise(s_signal); break; default: g_break_listen = 1; (void)fprintf(stdout, "unknown signal ! (%08XH)\n", s_signal); break; } } int (main)(int s_argc, char **s_argv) { int s_socket, s_accept_socket, s_epoll_handle, s_count, s_recv_bytes, s_reuse_flag, s_listen_port = 9876, s_socket_count; struct sockaddr_in s_bind_address, s_accept_address; socklen_t s_accept_address_size; size_t s_events_size; struct epoll_event *s_events; unsigned char s_buffer[ 4 << 10 ]; #if 1 /* 0=무자비한 종료, 1=깔끔종료 */ (void)signal(SIGINT, my_signal); (void)signal(SIGTERM, my_signal); (void)signal(SIGPIPE, my_signal); (void)signal(SIGSEGV, my_signal); #endif if(s_argc > 1) { int s_value = 0; if(sscanf(s_argv[1], "%d", &s_value) == 1) { if(s_value > 0)s_listen_port = s_value; } else (void)fprintf(stdout, "invalid argument (listen_port)\n"); } s_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if(s_socket != (-1)) { s_reuse_flag = 1; if(setsockopt(s_socket, SOL_SOCKET, SO_REUSEADDR, (void *)(&s_reuse_flag), sizeof(s_reuse_flag)) == (-1))perror("reuse"); s_bind_address.sin_family = AF_INET; s_bind_address.sin_port = htons(s_listen_port); s_bind_address.sin_addr.s_addr = htonl(INADDR_ANY); (void)memset((void *)(&s_bind_address.sin_zero[0]), 0, sizeof(s_bind_address.sin_zero)); if(bind(s_socket, (struct sockaddr *)(&s_bind_address), (socklen_t)sizeof(s_bind_address)) == 0) { #if defined(SOMAXCONN) /* full listen */ if(listen(s_socket, SOMAXCONN) == 0) #else if(listen(s_socket, 5) == 0) #endif { (void)fprintf(stdout, "ready. (listen_port=%d)\n", s_listen_port); s_events_size = sizeof(struct epoll_event) << 10; /* x1024 */ s_events = (struct epoll_event *)memset(malloc(s_events_size), 0, s_events_size); s_epoll_handle = epoll_create(s_events_size); s_events->events = EPOLLIN; s_events->data.fd = s_socket; epoll_ctl(s_epoll_handle, EPOLL_CTL_ADD, s_socket, s_events); s_socket_count = 0; do { s_count = epoll_wait(s_epoll_handle, s_events, s_events_size, 1000); if(s_count <= 0) { if(s_count < 0) { perror("epoll"); break; } (void)fprintf(stdout, "wait.\n"); continue; } while(s_count--) { if(s_events[s_count].data.fd == s_socket) { /* listen socket */ s_accept_address_size = (socklen_t)sizeof(s_accept_address); s_accept_socket = accept(s_socket, (struct sockaddr *)(&s_accept_address), (socklen_t *)(&s_accept_address_size)); if(s_accept_socket != (-1)) { (void)fprintf(stdout, "accepted from \"%s:%u\" (fd=%d)\n", (char *)inet_ntoa(s_accept_address.sin_addr), (unsigned int)ntohs(s_accept_address.sin_port), s_accept_socket); s_events->events = EPOLLIN; s_events->data.fd = s_accept_socket; epoll_ctl(s_epoll_handle, EPOLL_CTL_ADD, s_accept_socket, s_events); s_socket_count++; } else perror("accept"); continue; } /* accept socket */ s_recv_bytes = recv(s_events[s_count].data.fd, &s_buffer[0], sizeof(s_buffer), MSG_NOSIGNAL); if(s_recv_bytes > 0)(void)fprintf(stdout, "recv %lu bytes (fd=%d)\n", (unsigned long)s_recv_bytes, s_events[s_count].data.fd); else { epoll_ctl(s_epoll_handle, EPOLL_CTL_DEL, s_events[s_count].data.fd, s_events); (void)close(s_events[s_count].data.fd); (void)fprintf(stdout, "disconnected. (fd=%d)\n", s_events[s_count].data.fd); s_socket_count--; } } }while(g_break_listen == 0); s_events->events = EPOLLIN; s_events->data.fd = s_socket; epoll_ctl(s_epoll_handle, EPOLL_CTL_DEL, s_socket, s_events); free((void *)s_events); (void)fprintf(stdout, "%sneed close : %d\n", s_socket_count > 0 ? "WARNING: " : " ", s_socket_count); } else perror("listen"); } else perror("bind"); (void)close(s_socket); } else perror("socket"); (void)fprintf(stdout, "\nEnd of listen.\n"); return(0); } /* vim: set expandtab: */ /* End of source */ |
댓글+트랙백 RSS :: http://blog.hwport.com/rss/response/131
댓글+트랙백 ATOM :: http://blog.hwport.com/atom/response/131
이것은 sid 가 걸려있거나 root 유저에서 실행가능합니다. 이유는 RAW socket 이기 때문입니다.
| 코드: |
| /*
Copyright (c) Information Equipment co.,LTD. Code by JaeHyuk Cho <mailto:minzkn@infoeq.co.kr> - Simple is best ! (Sequence number check ping) Bugreport : To JaeHyuk Cho */ #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/param.h> #include <sys/time.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <arpa/inet.h> #include <netdb.h> #include <unistd.h> static int __MZ_ICMP_CheckSum__(void *s_Buffer, int s_Size) { int s_Return = 0; if(s_Size & 1)s_Return += (int)((*(unsigned char *)s_Buffer)++); s_Size >>= 1; while(s_Size-- > 0)s_Return += (int)(*(((unsigned short *)s_Buffer)++)); if(s_Size == 1)s_Return += (int)(*(unsigned char *)(s_Buffer)); s_Return = (s_Return >> 16) + (s_Return & 0xFFFF); s_Return += (s_Return >> 16); return((~s_Return) & 0xffff); } int CORE_Ping(const char *s_HostName, unsigned int s_Index, unsigned int s_TimeOut) { int s_Return = (-1), s_Socket, s_SendBytes, s_RecvBytes, s_IsSelect; struct protoent *s_ProtoEntry; struct hostent *s_HostEntry; struct sockaddr_in s_PingAddress, s_FromAddress; socklen_t s_FromAddressLength; struct icmp *s_ICMP; struct iphdr *s_IPHeader; unsigned char s_ICMP_Packet[ 60 + 76 + 56 ]; /* Packet assembly */ fd_set s_FD; struct timeval s_TimeVal; s_HostEntry = gethostbyname(s_HostName); if(s_HostEntry) { memset((void *)(&s_PingAddress), 0, sizeof(s_PingAddress)); s_PingAddress.sin_family = AF_INET; memcpy((void *)(&s_PingAddress.sin_addr), s_HostEntry->h_addr, sizeof(s_PingAddress.sin_addr)); memset((void *)(&s_ICMP_Packet[0]), 0, sizeof(s_ICMP_Packet)); s_ICMP = (struct icmp *)(&s_ICMP_Packet[0]); s_ICMP->icmp_type = ICMP_ECHO; s_ICMP->icmp_seq = s_Index; s_ICMP->icmp_id = getpid() & 0xffff; gettimeofday((struct timeval *)(&s_ICMP_Packet[8]), (void *)0); s_ICMP->icmp_cksum = __MZ_ICMP_CheckSum__((void *)(&s_ICMP_Packet[0]), sizeof(s_ICMP_Packet)); s_ProtoEntry = getprotobyname("icmp"); s_Socket = socket(AF_INET, SOCK_RAW, s_ProtoEntry ? s_ProtoEntry->p_proto : 1); setuid(getuid()); /* Who are you ? */ if(s_Socket >= 0) { s_SendBytes = sendto(s_Socket, (void *)(&s_ICMP_Packet[0]), sizeof(s_ICMP_Packet), MSG_NOSIGNAL, /* Ignore broken pipe */ (struct sockaddr *)(&s_PingAddress), sizeof(s_PingAddress)); if(s_SendBytes == sizeof(s_ICMP_Packet)) { memset((void *)(&s_FromAddress), 0, sizeof(s_FromAddress)); s_FromAddressLength = sizeof(s_FromAddress); memset((void *)(&s_ICMP_Packet[0]), 0, sizeof(s_ICMP_Packet)); s_TimeVal.tv_sec = s_TimeOut, s_TimeVal.tv_usec = 0; FD_ZERO(&s_FD); FD_SET(s_Socket, &s_FD); s_IsSelect = select(s_Socket + 1, &s_FD, (fd_set *)0, (fd_set *)0, &s_TimeVal); if(s_IsSelect > 0 && FD_ISSET(s_Socket, &s_FD) != 0) { s_RecvBytes = recvfrom(s_Socket, (void *)(&s_ICMP_Packet[0]), sizeof(s_ICMP_Packet), MSG_NOSIGNAL, /* Ignore broken pipe */ (struct sockaddr *)(&s_FromAddress), (socklen_t *)(&s_FromAddressLength)); } else s_RecvBytes = 0; if(s_RecvBytes >= 76) { s_IPHeader = (struct iphdr *)(&s_ICMP_Packet[0]); s_ICMP = (struct icmp *)(&s_ICMP_Packet[ s_IPHeader->ihl << 2 ]); if(s_ICMP->icmp_type == ICMP_ECHOREPLY) { /* TODO: Packet check sum need Time compute Duplicate packet check Send packet & Recv packet -> Two thread or alarm */ s_Return = (int)s_ICMP->icmp_seq; } } } close(s_Socket); } } return(s_Return); } int main(int s_Argc, char *s_Argv[]) { int s_Return, s_Check, s_Index, s_ErrorCount, s_IsError, s_Count; fprintf(stdout, "MZ_Ping v0.0.1 - Code by JaeHyuk Cho <minzkn@infoeq.co.kr>\n\n"); if(s_Argc > 1) { s_ErrorCount = 0, s_Index = 1; if(s_Argc > 2)sscanf(s_Argv[2], "%i", &s_Count); else s_Count = 8; do { s_Check = CORE_Ping(s_Argv[1], s_Index /* Request sequence number */, 4u /* Timeout 4 second */); if(s_Check != s_Index)s_ErrorCount++, s_IsError = 1; else s_IsError = 0; fprintf(stdout, "Ping[%s]: %s (Seq %d->%d) - ERR=%d\n", s_Argv[1], s_IsError == 0 ? "OK" : "LOSS", s_Index, s_Check, s_ErrorCount); usleep(10000); }while(s_Index++ < s_Count); fprintf(stdout, "Total %d%% loss.\n", s_ErrorCount * 100 / s_Index); s_Return = s_ErrorCount; } else { fprintf(stdout, "usage: ping <host> <count>\n"); s_Return = 0; } return(s_Return); } /* End of source */ |
댓글+트랙백 RSS :: http://blog.hwport.com/rss/response/106
댓글+트랙백 ATOM :: http://blog.hwport.com/atom/response/106
멀티캐스트의 수신부에서는 Membership join 이라는 작업이 필요하며 drop 의 경우는 굳이 할 필요는 없습니다. (Drop은 Socket이 닫히면 내부적으로 수행됩니다.)
멀티캐스트영역은 a.b.c.d 의 주소구성에서 a가 0xe0 ~ 0xef 의 범위값을 같게 되면 multicast zone 에 해당합니다.
Membership join 시에는 간단한 약식으로 join 해도 큰 문제가 없지만 경우에 따라서는 자신이 가지고 있는 interface를 정확히 scan 하여 적절한 대응으로 join을 할 필요가 있습니다.
Multicast 도 UDP와 비슷한 행동양식을 같게 되므로 높은 전송비트율을 recv 하기 위해서는 Kernel의 기본 제한치인 /proc/sys/net/core/rmem_max 와 실제 제한치를 수정해주는것이 좋습니다. 보통 필자가 생각하기에는 약 4Mbps 를 넘으면 이를 수정해줄 필요가 있는듯 합니다. 대략 커널 내부의 제한치를 2M로 늘리고 rmem_max를 1M로 늘려주면 충분할듯 합니다.
/*
Copyright (C) HWPORT.COM
All rights reserved.
Code by JaeHyuk Cho <mailto:minzkn@minzkn.com>
*/
#if !defined(_ISOC99_SOURCE)
# define _ISOC99_SOURCE (1L)
#endif
#if !defined(_GNU_SOURCE)
# define _GNU_SOURCE (1L)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <netdb.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#define __K__(x) (x * 1000)
#define __M__(x) (x * 1000000)
#define DEF_MULTICAST_PACKETSIZE (32 << 10)
#define DEF_MULTICAST_INDEXMASK (0xffff)
#define DEF_MULTICAST_TTL (2)
#define DEF_MULTICAST_BITRATE (__M__(0) + __K__(512) + 0)
int main(int s_Argc, char *s_Argv[]);
static int MULTICAST_TEST(int s_Argc, char *s_Argv[]);
static void MZ_Delay(int s_msDelay);
static int MULTICAST_TEST_SERVER(const char *s_MulticastZoneIP, int s_MulticastZonePort, int s_Bitrate);
static int MULTICAST_TEST_CLIENT(const char *s_MulticastZoneIP, int s_MulticastZonePort);
static int MULTICAST_DIFF_TIME(const struct timeval *s_Old, const struct timeval *s_New);
int main(int s_Argc, char *s_Argv[])
{
int s_Return;
fprintf(stdout, "multicast v1.0.0 - Copyright (c) HWPORT.COM - %s %s\n"
"Code by JaeHyuk Cho , Application name : multicast test\n\n",
__DATE__, __TIME__);
s_Return = MULTICAST_TEST(s_Argc, s_Argv);
fprintf(stdout, "\nEnd of multicast test (Return code = %d).\n", s_Return);
return(s_Return);
}
static int MULTICAST_TEST(int s_Argc, char *s_Argv[])
{
int s_Return = 0, s_ArgCount;
int s_Mode = (-1);
char *s_MulticastZoneIP = "224.1.1.1";
int s_MulticastZonePort = 5555;
int s_Bitrate = DEF_MULTICAST_BITRATE;
if(s_Argc > 1)
{
for(s_ArgCount = 0;s_ArgCount < s_Argc;s_ArgCount++)
{
if(strcmp(s_Argv[s_ArgCount], "server") == 0)s_Mode = 0;
else if(strcmp(s_Argv[s_ArgCount], "client") == 0)s_Mode = 1;
else if(strstr(s_Argv[s_ArgCount], ".") == 0)s_MulticastZoneIP = s_Argv[s_ArgCount];
else sscanf(s_Argv[s_ArgCount], "%i", &s_MulticastZonePort);
}
}
if(s_Mode != (-1))
{
fprintf(stdout, "Mode : %s\n"
"ZoneIP : %s\n"
"ZonePort : %d\n"
"Bitrate : %dKbps\n",
s_Mode == 0 ? "SERVER" : "CLIENT",
s_MulticastZoneIP,
s_MulticastZonePort,
s_Bitrate / 1000);
}
if(s_Mode == 0)s_Return = MULTICAST_TEST_SERVER(s_MulticastZoneIP, s_MulticastZonePort, s_Bitrate);
else if(s_Mode == 1)s_Return = MULTICAST_TEST_CLIENT(s_MulticastZoneIP, s_MulticastZonePort);
else fprintf(stdout, "Usage: %s <Mode=server|client> <MulticastZoneIP> <MulticastZonePort>\n", s_Argv[0]);
return(s_Return);
}
static void MZ_Delay(int s_msDelay)
{ /* usleep(s_MicroDelay) */
struct timeval s_TimeVal;
s_TimeVal.tv_sec = s_msDelay / 1000;
s_TimeVal.tv_usec = (s_msDelay % 1000) * 1000;
select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &s_TimeVal);
}
static int MULTICAST_DIFF_TIME(const struct timeval *s_Old, const struct timeval *s_New)
{
int s_Return;
unsigned long long s_OldTime, s_NewTime;
s_OldTime = (s_Old->tv_sec * 1000000) + s_Old->tv_usec;
s_NewTime = (s_New->tv_sec * 1000000) + s_New->tv_usec;
s_Return = (int)((unsigned long long)(s_NewTime - s_OldTime) / 1000llu);
return(s_Return); /* ms */
}
static int MULTICAST_TEST_SERVER(const char *s_MulticastZoneIP, int s_MulticastZonePort, int s_Bitrate)
{
int s_Return = 0, s_Socket, s_TTL = DEF_MULTICAST_TTL, s_SendBytes, s_Index, s_msDelay;
unsigned char s_SendBuffer[ DEF_MULTICAST_PACKETSIZE ];
struct sockaddr_in s_BindAddress, s_SendAddress;
socklen_t s_BindAddressLength, s_SendAddressLength;
s_Socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(s_Socket >= 0)
{
s_BindAddress.sin_family = AF_INET;
s_BindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
s_BindAddress.sin_port = htons(0);
s_BindAddressLength = (socklen_t)sizeof(s_BindAddress);
if(bind(s_Socket, (struct sockaddr *)(&s_BindAddress), s_BindAddressLength) == 0)
{
if(setsockopt(s_Socket, IPPROTO_IP, IP_MULTICAST_TTL, (char *)(&s_TTL), sizeof(s_TTL)) == 0)
{
s_Index = 0;
s_msDelay = sizeof(s_SendBuffer) * 8000 / s_Bitrate;
s_SendAddress.sin_family = AF_INET;
s_SendAddress.sin_addr.s_addr = s_MulticastZoneIP ? inet_addr(s_MulticastZoneIP) : htonl(INADDR_ANY);
s_SendAddress.sin_port = htons(s_MulticastZonePort);
s_SendAddressLength = (socklen_t)sizeof(s_SendAddress);
do
{
memcpy((void *)(&s_SendBuffer[sizeof(s_SendBuffer) - sizeof(s_Index)]), &s_Index, sizeof(s_Index));
s_SendBytes = sendto(s_Socket,
(void *)(&s_SendBuffer[0]),
(size_t)sizeof(s_SendBuffer),
MSG_NOSIGNAL,
(struct sockaddr *)(&s_SendAddress),
s_SendAddressLength
);
if(s_SendBytes > 0)
{
fprintf(stdout, "[%5d] Sent %d/%d bytes, Delay=%dms.\n",
s_Index,
(int)s_SendBytes,
(int)sizeof(s_SendBuffer),
s_msDelay);
#if DEF_MULTICAST_INDEXMASK != (0)
s_Index = (s_Index + 1) & DEF_MULTICAST_INDEXMASK;
#else
s_Index++;
#endif
}
else fprintf(stderr, "%s: %s - [ERROR] Can not send index=%d, sent=%d/%d !!!\n", __FILE__, __FUNCTION__, s_Index, (int)s_SendBytes, (int)sizeof(s_SendBuffer));
MZ_Delay(s_msDelay);
}while(1);
}
else fprintf(stderr, "%s: %s - [ERROR] Can not TTL setup !!!\n", __FILE__, __FUNCTION__);
}
else fprintf(stderr, "%s: %s - [ERROR] Can not bind UDP socket !!!\n", __FILE__, __FUNCTION__);
close(s_Socket);
}
else fprintf(stderr, "%s: %s - [ERROR] Can not open UDP socket !!!\n", __FILE__, __FUNCTION__);
return(s_Return);
}
static int MULTICAST_TEST_CLIENT(const char *s_MulticastZoneIP, int s_MulticastZonePort)
{
int s_Return = 0, s_Socket, s_RecvBytes, s_Index, s_CalcIndex, s_IsSelect, s_DiffTime;
unsigned char s_RecvBuffer[ DEF_MULTICAST_PACKETSIZE ];
struct sockaddr_in s_BindAddress, s_RecvAddress;
socklen_t s_BindAddressLength, s_RecvAddressLength;
struct ip_mreq s_RequestIP;
char *s_StatusString;
fd_set s_FD;
struct timeval s_TimeVal, s_TimeVal_Old, s_TimeVal_New;
s_Socket = socket(PF_INET, SOCK_DGRAM, 0);
if(s_Socket >= 0)
{
s_BindAddress.sin_family = AF_INET;
s_BindAddress.sin_addr.s_addr = htonl(INADDR_ANY); /* My speacial interface */
s_BindAddress.sin_port = htons(s_MulticastZonePort);
s_BindAddressLength = sizeof(s_BindAddress);
if(bind(s_Socket, (struct sockaddr *)(&s_BindAddress), s_BindAddressLength) == 0)
{
s_RequestIP.imr_multiaddr.s_addr = s_MulticastZoneIP ? inet_addr(s_MulticastZoneIP) : htonl(INADDR_ANY);
s_RequestIP.imr_interface.s_addr = s_BindAddress.sin_addr.s_addr;
if(setsockopt(s_Socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &s_RequestIP, sizeof(s_RequestIP)) == 0)
{
s_Index = 0;
gettimeofday(&s_TimeVal_Old, (struct timezone *)0);
do
{
FD_ZERO(&s_FD);
FD_SET(s_Socket, &s_FD);
s_TimeVal.tv_sec = 1, s_TimeVal.tv_usec = 0;
s_IsSelect = select(s_Socket + 1, (fd_set *)(&s_FD), (fd_set *)0, (fd_set *)0, &s_TimeVal);
if(s_IsSelect > 0)
{
if(FD_ISSET(s_Socket, &s_FD))s_IsSelect = 1;
else s_IsSelect = 0;
}
if(s_IsSelect <= 0)
{
fprintf(stdout, "Wait packet . . .\n");
continue;
}
s_RecvBytes = recvfrom(s_Socket,
(void *)(&s_RecvBuffer[0]),
(size_t)sizeof(s_RecvBuffer),
MSG_NOSIGNAL,
(struct sockaddr *)(&s_RecvAddress),
(socklen_t *)(&s_RecvAddressLength)
);
if(s_RecvBytes > 0)
{
memcpy((void *)(&s_CalcIndex), (void *)(&s_RecvBuffer[sizeof(s_RecvBuffer) - sizeof(s_CalcIndex)]), sizeof(s_CalcIndex));
if(s_CalcIndex == s_Index)s_StatusString = "PASS";
else s_StatusString = "MISSMATCH";
gettimeofday(&s_TimeVal_New, (struct timezone *)0);
s_DiffTime = MULTICAST_DIFF_TIME(&s_TimeVal_Old, &s_TimeVal_New);
memcpy((void *)(&s_TimeVal_Old), (void *)(&s_TimeVal_New), sizeof(struct timeval));
fprintf(stdout, "[%5d] Recv %d/%d, DiffTime=%dms - %dKbps <%s>\n",
s_CalcIndex,
(int)s_RecvBytes,
(int)sizeof(s_RecvBuffer),
s_DiffTime,
(int)(((s_RecvBytes << 3) * 1000) / s_DiffTime / 1000),
s_StatusString);
#if DEF_MULTICAST_INDEXMASK != (0)
s_Index = (s_CalcIndex + 1) & DEF_MULTICAST_INDEXMASK;
#else
s_Index = s_CalcIndex + 1;
#endif
}
else fprintf(stderr, "%s: %s - [ERROR] Can not recv index=%d, recv=%d/%d !!!\n", __FILE__, __FUNCTION__, s_Index, (int)s_RecvBytes, (int)sizeof(s_RecvBuffer));
}while(1);
}
else fprintf(stderr, "%s: %s - [ERROR] Can not join interface !!!\n", __FILE__, __FUNCTION__);
}
else fprintf(stderr, "%s: %s - [ERROR] Can not bind MULTICAST socket !!!\n", __FILE__, __FUNCTION__);
close(s_Socket);
}
else fprintf(stderr, "%s: %s - [ERROR] Can not open DGRAM socket !!!\n", __FILE__, __FUNCTION__);
return(s_Return);
}
/* End of source */
댓글+트랙백 RSS :: http://blog.hwport.com/rss/response/92
댓글+트랙백 ATOM :: http://blog.hwport.com/atom/response/92
Copyright (C) Information Equipment co.,LTD
All rights reserved.
Code by JaeHyuk Cho <mailto:minzkn@infoeq.com>
CVSTAG="$Header$"
*/
#include <sys/param.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#ifndef __USE_GNU
#define __USE_GNU __USE_GNU
#endif
#include <fcntl.h>
void DoSignalIO(int s_Signal)
{ fprintf(stdout, "%s : s_Signal = %d\n", __FUNCTION__, s_Signal); }
int main(void)
{
int s_Handle;
s_Handle = open("/dev/stdin", O_RDONLY);
s_Handle = s_Handle == (-1) ? 0 : s_Handle;
if(s_Handle != (-1))
{
struct siginfo s_SignalInfo;
sigset_t s_SignalSet;
struct sigaction s_SignalAction;
int s_Check, s_ReadBytes, s_Index, s_IsContinue, s_Prompt, s_CursorIndex;
unsigned char s_Buffer[ 32 << 10 ];
char s_Cursor[] = {'-', '/', '|', '\\'};
/* Handler 준비 */
sigemptyset(&s_SignalSet);
sigaddset(&s_SignalSet, SIGRTMIN);
sigprocmask(SIG_BLOCK, &s_SignalSet, (sigset_t *)0);
sigemptyset(&s_SignalAction.sa_mask);
s_SignalAction.sa_flags = SA_SIGINFO;
s_SignalAction.sa_restorer = NULL;
s_SignalAction.sa_handler = DoSignalIO;
/* ASync fd 설정 */
fcntl(s_Handle, F_SETFL, O_RDONLY | O_ASYNC | O_NONBLOCK);
fcntl(s_Handle, F_SETSIG, SIGRTMIN);
fcntl(s_Handle, F_SETOWN, getpid());
s_IsContinue = 1;
if(sigaction(SIGRTMIN, &s_SignalAction, 0) != (-1))
{ /* Handler 등록 */
s_Prompt = 1;
s_CursorIndex = 0;
do
{
if(s_Prompt == 1)
{ /* 프롬프트 */
fprintf(stdout, "\rInput RTS message >>> "); fflush(stdout);
s_Prompt = 0;
}
else
{ /* 심오한 커서 */
fprintf(stdout, " %c\b\b", s_Cursor[((s_CursorIndex++) / 10) % sizeof(s_Cursor)]); fflush(stdout);
usleep((1000 / HZ) * 1000); /* CPU 부하 균형 - x86계열엣서는 10ms */
}
s_Check = sigwaitinfo(&s_SignalSet, &s_SignalInfo);
if(s_Check == SIGRTMIN)
{ /* 입력한게 있다고 엽구리 찌르네 */
if(s_SignalInfo.si_fd == s_Handle &&( (s_SignalInfo.si_code == POLL_IN) || (s_SignalInfo.si_code == SI_QUEUE) ))
{ /* 진짜 입력한거 맞어? */
s_ReadBytes = read(s_Handle, &s_Buffer[0], sizeof(s_Buffer) - 1);
if(s_ReadBytes > 0)
{ /* 뭔가 있어 */
for(s_Index = 0;s_Index < s_ReadBytes;s_Index++)fprintf(stdout, "[0x%02x]", s_Buffer[s_Index]);
fprintf(stdout, "\n");
s_Prompt = 1;
}
}
}
else fprintf(stdout, "Check = %d\n", s_Check);
}while(s_IsContinue == 1);
}
if(s_Handle > 2)close(s_Handle);
}
return(1);
}
/* vim: set expandtab: */
/* End of source */
댓글+트랙백 RSS :: http://blog.hwport.com/rss/response/91
댓글+트랙백 ATOM :: http://blog.hwport.com/atom/response/91
최대한 비슷하게 만들었습니다.
| 코드: |
|
/* Copyright (c) 2002 Information Equipment co.,LTD. All Right Reserved. Code by JaeHyuk Cho <minzkn@infoeq.co.kr> This example !!! - Simple is best. - Reference RFC 868 -> See http://rfc.sunsite.dk */ #if defined(WIN32) #include <windows.h> #else #include <stdio.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <time.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #endif #define DEF_RFC_868_CORRESPOND_VALUE (2208988800lu) /* 00:00:00 1 JAN 1970 GMT */ #define DEF_RFC_868_TIMESERVER_TCP_PORT (37) #define DEF_RFC_868_TIMESERVER_UDP_PORT (37) int main(int s_Argc, char *s_Argv[]); static time_t MZ_GetRemoteTime(const char *s_TimeServer) { unsigned long s_Return = 0lu; int s_Socket; struct sockaddr_in s_SocketAddress_In; struct hostent *s_HostEntry; s_HostEntry = gethostbyname(s_TimeServer); if(s_HostEntry) { memset((void *)(&s_SocketAddress_In), 0, sizeof(s_SocketAddress_In)); s_SocketAddress_In.sin_family = AF_INET; s_SocketAddress_In.sin_port = htons(DEF_RFC_868_TIMESERVER_TCP_PORT); memcpy((void *)(&s_SocketAddress_In.sin_addr), (void *)(s_HostEntry->h_addr), sizeof(s_SocketAddress_In.sin_addr)); s_Socket = socket(AF_INET, SOCK_STREAM, 0); if(s_Socket >= 0) { /* TODO: Tick save */ if(connect(s_Socket, (struct sockaddr *)&s_SocketAddress_In, sizeof(s_SocketAddress_In)) >= 0) { if(recv(s_Socket, &s_Return, sizeof(s_Return), 0) == sizeof(s_Return)) { s_Return = ntohl(s_Return) - DEF_RFC_868_CORRESPOND_VALUE; /* Time entry 00:00:00 1 JAN 1970 GMT */ /* TODO: s_Return += (Tick value / 2) */ } else fprintf(stderr, "Can not recv time_t from \"%s\" !\n", s_TimeServer); } else fprintf(stderr, "Can not connect to timeserver \"%s\" !\n", s_TimeServer); #if defined(WIN32) closesocket(s_Socket); #else close(s_Socket); #endif } else fprintf(stderr, "Can not open socket !\n"); } else fprintf(stderr, "Can not get host by name !\n"); return((time_t)s_Return); } int main(int s_Argc, char *s_Argv[]) { char *s_TimeServer = "time.bora.net"; time_t s_RemoteTime; fprintf(stdout, "rdate v0.0.1 - Code by JaeHyuk Cho <minzkn@infoeq.co.kr>\n\n"); if(s_Argc > 1)s_TimeServer = s_Argv[1]; fprintf(stdout, "Timeserver is %s\n", s_TimeServer); s_RemoteTime = MZ_GetRemoteTime(s_TimeServer); if(s_RemoteTime) { fprintf(stdout, "TIME>> %s\n", ctime(&s_RemoteTime)); /* TODO: Adjust clock delay */ /* stime(&s_RemoteTime); */ /* Save time */ } else fprintf(stderr, "Can not sync from \"%s\" !\n", s_TimeServer); return(0); } /* End of source */ |
댓글+트랙백 RSS :: http://blog.hwport.com/rss/response/68
댓글+트랙백 ATOM :: http://blog.hwport.com/atom/response/68
하지만 다양한 플랫폼을 지원하기 위해서 범용적인 코드를 원한다면
아래의 예제처럼 구현하기 보다는 pcap library 를 사용하기를 권합니다.
| 코드: |
|
/* Copyright (c) 2002 Information Equipment co.,LTD. All Right Reserved. Code by JaeHyuk Cho <minzkn@infoeq.co.kr> - Simple is best */ #if !defined(DEF_ifconfig_c) #define DEF_ifconfig_c "ifconfig.c" #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <netinet/in.h> #include <net/if.h> #include <netinet/if_ether.h> #include <arpa/inet.h> #include <netdb.h> #include <netinet/ether.h> int main(int s_Argc, char **s_Argv); int main(int s_Argc, char **s_Argv) { int s_SocketHandle; int s_RequestCount = 10; struct ifconf s_ifconfig; struct ifreq *s_ifrequest; struct sockaddr_in *s_SockAddr_In; char s_StringBuffer[1 << 10]; char *s_MyTitle; char *s_MyDevice; char *s_MyIP, *s_MyBroadcastIP, *s_MyNetmaskIP; char *s_MyHWAddr; char *s_MyFlagString; int s_MyFlags, s_MyMTU, s_MyMetric; fprintf(stdout, "MZ_ifconfig v0.0.1b - Copyright(c)InfoEQ co.,LTD - %s %s\n", __DATE__, __TIME__); fprintf(stdout, "Code by JaeHyuk Cho - <minzkn@infoeq.co.kr>\n\n"); s_SocketHandle = socket(AF_INET, SOCK_DGRAM, 0); if(s_SocketHandle >= 0) { memset((void *)&s_ifconfig, 0, sizeof(struct ifconf)); do { if(s_ifconfig.ifc_buf)free(s_ifconfig.ifc_buf); s_ifconfig.ifc_len = sizeof(struct ifreq) * s_RequestCount; s_ifconfig.ifc_buf = malloc(s_ifconfig.ifc_len); if(s_ifconfig.ifc_buf) { if(ioctl(s_SocketHandle, SIOCGIFCONF, &s_ifconfig) == 0) { if(s_ifconfig.ifc_len < (sizeof(struct ifreq) * s_RequestCount)) { s_ifrequest = s_ifconfig.ifc_req; if(s_ifrequest) { for(s_RequestCount = 0;s_RequestCount < s_ifconfig.ifc_len;s_RequestCount += sizeof(struct ifreq), s_ifrequest++) { /* ------------------------------------------------------------------------ */ s_MyDevice = strdup(s_ifrequest->ifr_name); /* ioctl(s_SocketHandle, SIOCGIFADDR, s_ifrequest); */ s_SockAddr_In = (struct sockaddr_in *)(&s_ifrequest->ifr_addr); s_MyIP = strdup(inet_ntoa(s_SockAddr_In->sin_addr)); ioctl(s_SocketHandle, SIOCGIFBRDADDR, s_ifrequest); s_SockAddr_In = (struct sockaddr_in *)&s_ifrequest->ifr_broadaddr; s_MyBroadcastIP = strdup(inet_ntoa(s_SockAddr_In->sin_addr)); ioctl(s_SocketHandle, SIOCGIFNETMASK, s_ifrequest); s_SockAddr_In = (struct sockaddr_in *)&s_ifrequest->ifr_netmask; s_MyNetmaskIP = strdup(inet_ntoa(s_SockAddr_In->sin_addr)); #if 0 if(ioctl(s_SocketHandle, SIOCGIFHWADDR, s_ifrequest) == 0) { unsigned char s_NullHWAddr[] = {0, 0, 0, 0, 0, 0}; if(memcmp(&s_ifrequest->ifr_hwaddr.sa_data[0], &s_NullHWAddr[0], sizeof(s_NullHWAddr)) == 0)strcpy(s_StringBuffer, ""); else sprintf(s_StringBuffer, "HWAddr %s", ether_ntoa((struct ether_addr *)s_ifrequest->ifr_hwaddr.sa_data)); } else strcpy(s_StringBuffer, "HWAddr <ERROR>"); #else if(ioctl(s_SocketHandle, SIOCGIFHWADDR, s_ifrequest) == 0) { sprintf(s_StringBuffer, "HWAddr %s", ether_ntoa((struct ether_addr *)s_ifrequest->ifr_hwaddr.sa_data)); } else strcpy(s_StringBuffer, "HWAddr <ERROR>"); #endif s_MyHWAddr = strdup(s_StringBuffer); if(ioctl(s_SocketHandle, SIOCGIFFLAGS, s_ifrequest) == 0)s_MyFlags = s_ifrequest->ifr_flags; else s_MyFlags = 0; strcpy(s_StringBuffer, ""); if(s_MyFlags == 0)strcpy(s_StringBuffer, "[NO FLAGS]"); else { if(s_MyFlags & IFF_UP )strcat(s_StringBuffer, "UP "); if(s_MyFlags & IFF_BROADCAST )strcat(s_StringBuffer, "BROADCAST "); if(s_MyFlags & IFF_DEBUG )strcat(s_StringBuffer, "DEBUG "); if(s_MyFlags & IFF_LOOPBACK )strcat(s_StringBuffer, "LOOPBACK "); if(s_MyFlags & IFF_POINTOPOINT )strcat(s_StringBuffer, "POINTOPOINT "); if(s_MyFlags & IFF_NOTRAILERS )strcat(s_StringBuffer, "NOTRAILERS "); if(s_MyFlags & IFF_RUNNING )strcat(s_StringBuffer, "RUNNING "); if(s_MyFlags & IFF_NOARP )strcat(s_StringBuffer, "NOARP "); if(s_MyFlags & IFF_PROMISC )strcat(s_StringBuffer, "PROMISC "); if(s_MyFlags & IFF_ALLMULTI )strcat(s_StringBuffer, "ALLMULTI "); if(s_MyFlags & IFF_SLAVE )strcat(s_StringBuffer, "SLAVE "); if(s_MyFlags & IFF_MASTER )strcat(s_StringBuffer, "MASTER "); if(s_MyFlags & IFF_MULTICAST )strcat(s_StringBuffer, "MULTICAST "); } s_MyFlagString = strdup(s_StringBuffer); s_MyTitle = strdup("Unknown"); /* Not support */ if(ioctl(s_SocketHandle, SIOCGIFMTU, s_ifrequest) == 0)s_MyMTU = s_ifrequest->ifr_mtu; else s_MyMTU = 0; if(ioctl(s_SocketHandle, SIOCGIFMETRIC, s_ifrequest) == 0)s_MyMetric = s_ifrequest->ifr_metric; else s_MyMetric = 0; /* Print. */ fprintf(stdout, "%-8s Link encap:%s %s\n" "%-8s inet addr %-15s Broadcast %-15s Netmask %-15s\n" "%-8s %s MTU:%d Metric:%d\n" "\n", s_MyDevice, s_MyTitle, s_MyHWAddr, "", s_MyIP, s_MyBroadcastIP, s_MyNetmaskIP, "", s_MyFlagString, s_MyMTU, s_MyMetric ? s_MyMetric : 1 ); /* Free. */ if(s_MyTitle )free(s_MyTitle); if(s_MyDevice )free(s_MyDevice); if(s_MyIP )free(s_MyIP); if(s_MyBroadcastIP)free(s_MyBroadcastIP); if(s_MyNetmaskIP )free(s_MyNetmaskIP); if(s_MyHWAddr )free(s_MyHWAddr); if(s_MyFlagString )free(s_MyFlagString); /* ------------------------------------------------------------------------ */ } } break; } else s_RequestCount += 10; } else break; } else break; }while(1); if(s_ifconfig.ifc_buf)free(s_ifconfig.ifc_buf); close(s_SocketHandle); } else fprintf(stderr, "Can not open socket !!!\n"); return(0); } #endif /* End of source */ |
위의 예제를 조금더 응용하여
현재 내가 보유한 여러개의 IP중에서 어떤 IP가 route를 통하는지
검출하는 간략한 예제입니다.
즉, 이것은 여러개의 IP를 가지고 있을때 이중에서 어떤것이
인터넷으로 패킷이 탈수 있는지 검출하는 것입니다.
물론 이것은 너무 간략하게 구현하려고 약간의 case 에 대해서 버그가 존재합니다. 그것은 적절히 코드를 보강하면 됩니다.
| 코드: |
|
/* Copyright (c) 2002 Information Equipment co.,LTD. All Right Reserved. Code by JaeHyuk Cho <minzkn@infoeq.co.kr> - Simple is best */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <netinet/in.h> #include <net/if.h> #include <netinet/if_ether.h> #include <arpa/inet.h> #include <netdb.h> #include <unistd.h> #include <fcntl.h> int main(int s_Argc, char **s_Argv); int main(int s_Argc, char **s_Argv) { const char *c_Proc_Route = "/proc/net/route"; int s_SocketHandle, s_Handle, s_ReadBytes, s_RequestCount = 10; struct ifconf s_ifconfig; struct ifreq *s_ifrequest; struct sockaddr_in *s_SockAddr_In; char *s_MyDevice; char *s_MyIP, *s_MyBroadcastIP, *s_MyNetmaskIP, *s_RouteIP, *s_RouteName; char s_Buffer[ 32 << 10 ]; s_RouteIP = s_RouteName = (char *)0; s_Handle = open(c_Proc_Route, O_RDONLY); if(s_Handle >= 0) { s_ReadBytes = read(s_Handle, &s_Buffer[0], sizeof(s_Buffer) - 1); close(s_Handle); if(s_ReadBytes > 0) { unsigned long s_Destination, s_Gateway, s_Flags, s_RefCnt, s_Use, s_Metric, s_Mask; char *s_TraceBuffer; int s_Index; s_Buffer[ s_ReadBytes ] = '\0'; s_Index = 0; s_TraceBuffer = (char *)(&s_Buffer[s_Index]); do { s_RouteName = (char *)0; if(s_Buffer[s_Index] == '\0' || s_Buffer[s_Index] == '\n') { s_Buffer[s_Index] = '\0'; s_RouteName = s_TraceBuffer; while((*s_TraceBuffer) != ' ' && (*s_TraceBuffer) != '\t' && (*s_TraceBuffer) != '\0')s_TraceBuffer++; *(s_TraceBuffer++) = '\0'; while(((*s_TraceBuffer) == ' ' || (*s_TraceBuffer) == '\t') && (*s_TraceBuffer) != '\0')s_TraceBuffer++; if(sscanf(s_TraceBuffer, "%lx%lx%lX%lu%lu%lu%lx", &s_Destination, &s_Gateway, &s_Flags, &s_RefCnt, &s_Use, &s_Metric, &s_Mask) == 7) { if(s_Destination == 0lu) { /* fprintf(stdout, "Default route [%s:%s]\n", s_RouteName, s_TraceBuffer); */ break; } /* else fprintf(stdout, "Normal route [%s:%s]\n", s_RouteName, s_TraceBuffer); */ } /* else fprintf(stdout, "Non line [%s:%s]\n", s_RouteName, s_TraceBuffer); */ s_Index++; s_TraceBuffer = (char *)(&s_Buffer[s_Index]); } else if(s_Buffer[s_Index] == '\r')s_Buffer[s_Index++] = ' '; else s_Index++; }while(s_Index < s_ReadBytes); } } else fprintf(stderr, "Can not open \"%s\"\n", c_Proc_Route); if(s_RouteName == (char *)0) { return(-1); } s_SocketHandle = socket(AF_INET, SOCK_DGRAM, 0); if(s_SocketHandle >= 0) { memset((void *)&s_ifconfig, 0, sizeof(struct ifconf)); do { if(s_ifconfig.ifc_buf)free(s_ifconfig.ifc_buf); s_ifconfig.ifc_len = sizeof(struct ifreq) * s_RequestCount; s_ifconfig.ifc_buf = malloc(s_ifconfig.ifc_len); if(s_ifconfig.ifc_buf) { if(ioctl(s_SocketHandle, SIOCGIFCONF, &s_ifconfig) == 0) { if(s_ifconfig.ifc_len < (sizeof(struct ifreq) * s_RequestCount)) { s_ifrequest = s_ifconfig.ifc_req; if(s_ifrequest) { for(s_RequestCount = 0;s_RequestCount < s_ifconfig.ifc_len;s_RequestCount += sizeof(struct ifreq), s_ifrequest++) { s_MyDevice = strdup(s_ifrequest->ifr_name); ioctl(s_SocketHandle, SIOCGIFADDR, s_ifrequest); s_SockAddr_In = (struct sockaddr_in *)(&s_ifrequest->ifr_addr); s_MyIP = strdup(inet_ntoa(s_SockAddr_In->sin_addr)); ioctl(s_SocketHandle, SIOCGIFBRDADDR, s_ifrequest); s_SockAddr_In = (struct sockaddr_in *)&s_ifrequest->ifr_broadaddr; s_MyBroadcastIP = strdup(inet_ntoa(s_SockAddr_In->sin_addr)); ioctl(s_SocketHandle, SIOCGIFNETMASK, s_ifrequest); s_SockAddr_In = (struct sockaddr_in *)&s_ifrequest->ifr_netmask; s_MyNetmaskIP = strdup(inet_ntoa(s_SockAddr_In->sin_addr)); if(strcmp(s_MyDevice, "lo") != 0 && strcmp(s_RouteName, s_MyDevice) == 0)fprintf(stdout, "%s %s\n", s_MyDevice, s_MyIP); if(s_MyDevice )free(s_MyDevice); if(s_MyIP )free(s_MyIP); if(s_MyBroadcastIP)free(s_MyBroadcastIP); if(s_MyNetmaskIP )free(s_MyNetmaskIP); } } break; } else s_RequestCount += 10; } else break; } else break; }while(1); if(s_ifconfig.ifc_buf)free(s_ifconfig.ifc_buf); close(s_SocketHandle); } else fprintf(stderr, "Can not open socket !!!\n"); return(0); } /* End of source */ |
댓글+트랙백 RSS :: http://blog.hwport.com/rss/response/67
댓글+트랙백 ATOM :: http://blog.hwport.com/atom/response/67
이 소스는 멀티쓰레드 스텔스 포트 스캐너로서 다양한 옵션과 UDP 스캔, TCP 스캔, TCP SYN 스캔등의 기능을 제공합니다.
컴파일 방법 :
| 인용: |
| gcc rootscan.c -o rootscan -lpthreads |
| 코드: |
|
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <netinet/in.h> #include <netdb.h> #include <arpa/inet.h> #include <linux/ip.h> #include <linux/tcp.h> #include <sys/socket.h> #include <sys/types.h> #include <pthread.h> struct timeval timeout; #define MAX 1000 #define GREEN "" #define RED "" #define BLUE "" #define TCP_SCAN 1 #define UDP_SCAN 2 #define SYN_SCAN 3 #define NO 0 #define YES 1 /* End of includes and defines */ /* Defining global variables, arrays and functions */ FILE *fp; char file_to_open[60]; int count = 0; int n_threads = 0; int start_port = 1; int end_port = 65535; int parallel = NO; int verbose = NO; int timeout_sec; char *host_addr; struct pseudohdr { unsigned long saddr; unsigned long daddr; char zer0; unsigned char protocol; unsigned short length; }; /* Set prototypes: */ void usage(char progname[]); void tcp_scan(); void udp(); void syn(); void *try_udp_port (void *); void *try_tcp_port(void *); void *try_syn_port(void *); unsigned short in_cksum(unsigned short *addr,int len); /* End of function prototypes */ /* OpenFiles() function, opens scanresults.txt. */ void OpenFiles() { fp = fopen("rootscan.log", "w" ); if( fp == NULL ) { printf(RED "File Open Error\n"); exit(1); } fprintf(fp,"Rootscan was written by shaunige@yahoo.co.uk" ); fprintf(fp,"\nPorted to windows by : Eckz - mrx@netlane.com - http://eckz.cjb.net\n" ); fprintf(fp,"\nOptions added by : InvisibleGhost : i_t_rules@hotmail.com\n" ); fprintf(fp, "Testers/Bug Testers: Threadhead and Odins_Son\n"); fprintf(fp,"\n******************************************************************" ); fprintf(fp,"\n ROOTSCAN LOG "); fprintf(fp,"\n******************************************************************\n" ); } /* End of OpenFiles() function */ /* CloseFiles() function, closes files */ void CloseFiles() { fclose( fp ); } /* End of global variables, arrays and functions */ /* Main function */ int main(int argc, char *argv[]) { char ch; int scan_type; /* Check args, and print a message if wrong */ if(argc < 2) { usage(argv[0]); exit(-1); } /*Set host address*/ host_addr = argv[1]; /* Check command line arguments, and set variables appropriately */ optarg = NULL; timeout_sec = 3; while ((ch = getopt(argc, argv, "sutpvhb:e:c:")) != -1) switch (ch) { case 's': scan_type = SYN_SCAN; break; case 'u': scan_type = UDP_SCAN; break; case 't': scan_type = TCP_SCAN; break; case 'b': start_port = atoi(optarg); break; case 'e': end_port = atoi(optarg); break; case 'p': parallel = YES; break; case 'c': timeout_sec = atoi(optarg); break; case 'v': verbose = YES; break; case 'h': usage(argv[0]); break; default: break; } if (verbose == YES) printf("Scanning host: %s\n", host_addr); if (verbose == YES && parallel == YES) printf("Going into parallel mode.\n"); switch (scan_type) { case TCP_SCAN: tcp_scan(); break; case UDP_SCAN: udp(); break; case SYN_SCAN: syn(); break; default: tcp_scan(); break; } } /* End of main() */ /* UDP scanning function: * This function was a quick hack, and will probably need some editing to work. */ void udp() { if (verbose == YES) printf("Beginning udp scan from: %d to: %d\n", start_port, end_port); if((gethostbyname(host_addr)) == NULL) { printf(RED "Couldn't resolve %s\n", host_addr); exit(-1); } OpenFiles(); for(count = start_port; count <= end_port; count++) { if (parallel == YES) { pthread_t thread_t; pthread_detach(thread_t); n_threads++; if (pthread_create(&thread_t, NULL, try_udp_port, (void *)count)) { count--; n_threads--; } } else { try_udp_port((void *)count); } if (verbose == YES) printf("\rPort: %d\r", count); } CloseFiles(); } void tcp_scan() { if (verbose == YES) printf("Beginning tcp connect() scan from: %d to: %d\n", start_port, end_port); if((gethostbyname(host_addr)) == NULL) { printf(RED "Couldn't resolve %s\n", host_addr); exit(-1); } printf(BLUE "\t\tPort\t\tState\t\tService\n\n"); /* Start for loop to connect to each port */ OpenFiles(); timeout.tv_sec = timeout_sec; timeout.tv_usec = timeout_sec; for(count = start_port; count <= end_port; count++) { if (parallel == YES) { pthread_t thread_t; pthread_detach(thread_t); n_threads++; if (pthread_create(&thread_t, NULL, try_tcp_port, (void *)count)) { count--; n_threads--; } } else { try_tcp_port((void *)count); } }/* End the for loop */ printf(BLUE "\n\nScan complete!\n\n"); /* Close the file */ CloseFiles(); } /* End function */ void syn() { if (verbose == YES) printf("Beginning syn stealth scan from: %d to: %d\n", start_port, end_port); if((gethostbyname(host_addr)) == NULL) { printf(RED "Couldn't resolve %s!\n", host_addr); exit(-1); } OpenFiles(); printf(BLUE "\t\tPort\t\tState\t\tService\n\n"); for(count = start_port; count <= end_port; count++) { if (parallel == YES) { pthread_t thread_t; pthread_detach(thread_t); n_threads++; if (pthread_create(&thread_t, NULL, try_syn_port, (void *)count)) { count--; n_threads--; } } else { try_syn_port((void *)count); } } /* End for() */ } /* End function */ void *try_udp_port(void *tmp) { int port = (int)(tmp); int sock; struct hostent *udp_host; struct sockaddr_in udp_dest; char udp_data[] = "hello\0"; int udp_len = strlen(udp_data); char udp_buf[20]; int sin_len = sizeof(struct sockaddr); if((udp_host = gethostbyname(host_addr)) == NULL) { printf(RED "Couldn't resolve %s\n", host_addr); exit(-1); } /* Create a SOCK_DGRAM socket instead, SOCK_DGRAM is UDP socket */ if((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { printf(RED "Couldn't create datagram socket!\n"); exit(-1); } /* Fill in address structs. */ udp_dest.sin_family = AF_INET; udp_dest.sin_port = htons(port); udp_dest.sin_addr = *((struct in_addr *)udp_host->h_addr); /* Send the datagram. */ sendto(sock, udp_data, udp_len, 0, (struct sockaddr *)&udp_host, sizeof(struct sockaddr)); /* If we get a reply, the port is probably closed. */ if(recvfrom(sock, udp_buf, 19, 0, (struct sockaddr *)&udp_host, &sin_len) < 0) { close(sock); fprintf(fp, "Port %d \t Closed\n", count); } /* If we received no response, the port is probably open. */ else { printf(RED "Port %d \t Open\n", count); close(sock); fprintf(fp, "Port %d \t Open\n", count); } close(sock); } void *try_tcp_port (void *tmp) { int port = (int)(tmp); int sock = 0; char http; char httpsend[18] = "HEAD / HTTP/1.0\n\n"; char httpbuf[MAX]; struct hostent *tcp_host; struct sockaddr_in tcp_dest; struct servent *serv; if (verbose == YES) printf("Port: %d\r", port); if((tcp_host = gethostbyname(host_addr)) == NULL) { printf(RED "Couldn't resolve %s\n", host_addr); exit(-1); } /* Creating the socket, with the integer variable called sock, checking if it suceeded, socket() returns -1 on error */ if((sock = socket(AF_INET, SOCK_STREAM, 0)) == 0) { printf(RED "Couldn't make socket!\n"); exit(-1); } setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout)); setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(timeout)); /* Setting up the sockaddr_in struct with connection details, port, 'family', hostname/IP address */ tcp_dest.sin_family = AF_INET; tcp_dest.sin_port = htons(port); tcp_dest.sin_addr = *((struct in_addr *)tcp_host->h_addr); /* Connecting the sock to the host on the port the for loop is up to */ if (connect(sock , (struct sockaddr *)&tcp_dest, sizeof(struct sockaddr)) == -1) { fprintf( fp ,"Port %5d Closed\n", port); close(sock); } else { /* Get the service name the port is likely to be. */ serv = getservbyport(htons(port), "tcp"); printf(RED "\t\t%d \t\t Open \t\t %s\n", port, (serv == NULL) ? "UNKNOWN" : serv->s_name); fprintf( fp ,"Port %5d Open \t %s\n", port, (serv == NULL) ? "UNKNOWN" : serv->s_name); /* If the variable the for loop is using equals 80, they might be running a web server, get the version? */ if(port == 80) { printf(GREEN "\n\nThe host is running a HTTP server, get HTTPD version? [y/n]"); scanf("%c", &http); if(http == 'y') { fprintf(fp,"\nHTTP version response:\n"); /* Sending HEAD / HTTP/1.0\n\n to get the version. */ send(sock, httpsend, strlen(httpsend), 0); /* Receiving the result, store it in httpbuf */ recv(sock, httpbuf, MAX-1, 0); /* Print it to stdout (monitor) */ printf("%s", httpbuf); /* Print it to the file */ fprintf(fp, "%s", httpbuf); } } /* Close the socket */ close(sock); } } void *try_syn_port(void *tmp) { int port = (int)(tmp); int sock; struct hostent *h = gethostbyname(host_addr); /* the variables */ int on=1; int ssize = sizeof(struct sockaddr_in); int packet_size = (sizeof(struct tcphdr)+sizeof(struct iphdr)); char *packet = malloc(packet_size); char *received = malloc(packet_size); /* The headers */ struct tcphdr *tcph = (struct tcphdr *)(packet+sizeof(struct iphdr)); struct pseudohdr *pseudo = (struct pseudohdr *)(packet+sizeof(struct iphdr)+sizeof(struct tcphdr)); struct iphdr *iph = (struct iphdr *)(packet); struct tcphdr *tcphr; struct iphdr *iphr; struct sockaddr_in local; struct sockaddr_in remote; struct in_addr saddr, daddr; struct servent *serv; /* making socket, and telling kernel we fill in the ip header */ if( (sock = socket( PF_INET, SOCK_RAW, IPPROTO_TCP)) < 0 ) { perror("socket"); exit(1); } if( (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) < 0 ) { perror("setsockopt"); exit(1); } daddr = *((struct in_addr *)h->h_addr); saddr.s_addr = inet_addr("62.254.68.38"); /* Change the IP address here. */ /***********************/ /* The pseudo header for the checksum */ pseudo->saddr = saddr.s_addr; pseudo->daddr = daddr.s_addr; pseudo->protocol = IPPROTO_TCP; pseudo->zer0 = 0; pseudo->length = htons(sizeof(struct tcphdr)); bzero( packet, packet_size ); tcph->source = htons(8901); tcph->dest = htons(port); tcph->seq = htonl(random()%time(NULL)); tcph->ack_seq= htonl(random()%time(NULL)); tcph->doff = 5; tcph->res1 = 0; tcph->fin = 0; tcph->syn = 1; tcph->rst = 0; tcph->psh = 0; tcph->ack = 0; tcph->urg = 0; tcph->window = htons(12000); tcph->check = (unsigned short)in_cksum((unsigned short *)tcph, sizeof(struct tcphdr)+sizeof(struct pseudohdr)); bzero(packet, sizeof(struct iphdr)); iph->ihl = 5; iph->version = 4; iph->tos = 0; iph->tot_len = htons(packet_size); iph->frag_off = 0; iph->ttl = IPDEFTTL; iph->protocol = IPPROTO_TCP; iph->check = (unsigned short)in_cksum((unsigned short *)iph, sizeof(struct iphdr)); iph->saddr = saddr.s_addr; iph->daddr = daddr.s_addr; remote.sin_family = PF_INET; remote.sin_addr = daddr; remote.sin_port = htons(port); if( (sendto(sock, packet, packet_size, 0x0, (struct sockaddr *)&remote, sizeof(remote))) < 0 ) { perror("sendto"); exit(1); } bzero( packet, packet_size ); if( (recvfrom(sock, received, packet_size, 0x0, (struct sockaddr *)&local, &ssize )) < 0 ) { perror("recvfrom"); exit(1); } iphr = (struct iphdr *)(received); tcphr = (struct tcphdr *)(received+(int)((iphr->ihl)*4)); /* using fixed sizes can be tricky, so i dont;) */ if( tcphr->syn == 1 && tcphr->ack == 1 ) /* SYN/ACK */ { serv = getservbyport(htons(port), "tcp"); printf("\t\t%d \t\t Open \t\t %s\n", ntohs(tcphr->source), (serv == NULL) ? "UNKNOWN" : serv->s_name); } else if( tcphr->rst = 1 ) /* RST */ { printf(""); /* anyone a suggestion what could be done here ? */ } else /* This shouldnt happen */ { printf("Protocol violation :P\n"); exit(-2); } close(sock); } /* The checksum function from the raw ip faq */ unsigned short in_cksum(unsigned short *addr,int len) { register int sum = 0; u_short answer = 0; register u_short *w = addr; register int nleft = len; while (nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(u_char *)(&answer) = *(u_char *)w; sum += answer; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return(answer); } void usage(char *progname) { printf(RED "Usage: %s <host/ip> [-tsu] [-p] [-b number] [-e number] [-c number] [-v]\n", progname); printf(RED "\n\nRootscan was written by shaunige@yahoo.co.uk,\nEckz - mrx@netlane.com - http://freewebs.com/bh_x,\n"); printf(RED "InvisibleGhost : i_t_rules@hotmail.com,\nand Ozzy.\nBug testers: Threadhead and Odins_Son, p4n_n0s.\n"); printf(RED "\n\t-u : Scan for UDP Ports\n"); printf(RED "\tUDP scanning option is currently experimental.\n"); printf(RED "\t-s : Scan using SYN scanning (stealthy).\n"); printf(RED "\t-t : Scan using TCP connect() scanning (default).\n"); printf(RED "\t-p : Scan in parallel mode, using threads (faster in some cases)\n"); printf(RED "\t-b number: start scanning at port number. (default = 1)\n"); printf(RED "\t-e number: stop scanning at port number. (default = 65535)\n"); printf(RED "\t-c number: Set connect() timeout (default = 3, \n\tcurrently only affects tcp connect() scan.)\n"); printf(RED "\t-v: Be verbose (mostly for debugging or checking speed)\n\n"); exit(-1); } /* End function */ |
댓글+트랙백 RSS :: http://blog.hwport.com/rss/response/60
댓글+트랙백 ATOM :: http://blog.hwport.com/atom/response/60
일반 connect 를 수행하면 상대방이 연결을 받아주지 않으면
무한정(대략 30초에서 2분) 대기상태로 빠지게 되는 단점이 있으나
Non-blocking 으로 connect 를 시도하면 제가 원하는 시간뒤에
빠져나올수 있어서 좋겠지요.
| 코드: |
|
/* Code by JaeHyuk Cho <mailto:minzkn@infoeq.com> */ static int __MZ_Poll__(int s_Socket, int s_Event, int s_TimeOut) { /* s_TimeOut < 0 : Blocking, s_TimeOut = 0 : Non blocking, s_TimeOut > 0 : Time block */ int s_Check; struct pollfd s_PollFD; if(s_TimeOut >= 0) { s_PollFD.fd = s_Socket, s_PollFD.events = s_Event; do{s_Check = poll((struct pollfd *)(&s_PollFD), 1u, s_TimeOut);}while(s_Check == (-1) && errno == EINTR); if(s_Check > 0) { if((s_PollFD.revents & s_Event))s_Check = 1; else { s_Check = 0; if(s_PollFD.revents & POLLHUP) { fprintf(stdout, "__MZ_Poll__: [WARNING] HUNG UP poll !\n"); } } } } else s_Check = 1; return(s_Check); } /* (-1): Disconnect, 0: Time out, 1: Poll OK */ int MZ_ConnectEx(int s_Socket, void *s_SocketAddress, int s_SocketAddressSize, int s_TimeOut) { int s_Return = 0, s_SocketError, s_Check; socklen_t s_SocketErrorSize; #ifdef WIN32 unsigned long s_Flags = 0lu; #else int s_Flags = 0; #endif if(s_Socket != (-1) && s_SocketAddress) { if(s_SocketAddressSize <= 0)s_SocketAddressSize = sizeof(struct sockaddr_in); if(s_TimeOut >= 0) { #ifdef WIN32 s_Flags = 1lu; s_Check = ioctl(s_Socket, FIONBIO, &s_Flags); #else s_Flags = fcntl(s_Socket, F_GETFL); s_Check = fcntl(s_Socket, F_SETFL, s_Flags | O_NONBLOCK); #endif } else s_Check = 0; if(s_Check == 0) { if(connect(s_Socket, (struct sockaddr *)s_SocketAddress, (socklen_t)s_SocketAddressSize) == 0)s_Return = 1; else if(s_TimeOut > 0) { s_Check = __MZ_Poll__(s_Socket, POLLIN | POLLOUT, s_TimeOut); if(s_Check == 1) { s_SocketErrorSize = (socklen_t)sizeof(s_SocketError); if(getsockopt(s_Socket, SOL_SOCKET, SO_ERROR, (void *)(&s_SocketError), (socklen_t *)(&s_SocketErrorSize)) == 0) { if(s_SocketError == 0)s_Return = 1; } } } } if(s_TimeOut >= 0) { #ifdef WIN32 s_Flags = 0lu; s_Check = ioctl(s_Socket, FIONBIO, &s_Flags); #else (void)fcntl(s_Socket, F_SETFL, s_Flags); #endif } } return(s_Return); } /* End of source */ |


mzping.tar.bz2
글