-
-
Save aji/5259202 to your computer and use it in GitHub Desktop.
netcat clone hacked together in 30 minutes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <sys/socket.h> | |
#include <netdb.h> | |
#include <stdarg.h> | |
#include <string.h> | |
#include <arpa/inet.h> | |
#include <sys/select.h> | |
#define LG_SEVERE 0 | |
#define LG_ERROR 1 | |
#define LG_WARN 2 | |
#define LG_INFO 3 | |
#define LG_DEBUG 4 | |
#define BUFSIZE 65536 | |
char recvbuf[BUFSIZE]; | |
char sendbuf[BUFSIZE]; | |
size_t rb_size = 0; | |
size_t sb_size = 0; | |
int running = 0; | |
int sock = -1; | |
void nlog(int level, const char *fmt, ...) | |
{ | |
char buf[BUFSIZE]; | |
va_list va; | |
va_start(va, fmt); | |
vsnprintf(buf, BUFSIZE, fmt, va); | |
va_end(va); | |
printf("%s\n", buf); | |
} | |
int connect_to(const char *host, unsigned short port) | |
{ | |
char buf[INET_ADDRSTRLEN]; | |
struct hostent *he; | |
struct sockaddr_in sin; | |
int err = -1; | |
if (sock >= 0) { | |
nlog(LG_SEVERE, "Already connected!"); | |
return -1; | |
} | |
he = gethostbyname(host); | |
if (he == NULL) { | |
nlog(LG_SEVERE, "Can't find host %s", host); | |
return err; | |
} | |
if (he->h_length <= 0 || he->h_addrtype != AF_INET) { | |
nlog(LG_SEVERE, "gethostbyname() was not helpful"); | |
goto out; | |
} | |
if (inet_ntop(AF_INET, he->h_addr_list[0], buf, INET_ADDRSTRLEN) < 0) { | |
nlog(LG_WARN, "inet_pton() complained! Using 0.0.0.0..."); | |
strcpy(buf, "0.0.0.0"); | |
} | |
nlog(LG_DEBUG, "Connecting to %s (%s:%u)...", he->h_name, buf, port); | |
sin.sin_family = AF_INET; | |
sin.sin_port = htons(port); | |
memcpy((void*)&sin.sin_addr, he->h_addr_list[0], 4); /* 4... */ | |
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { | |
nlog(LG_SEVERE, "socket() failed!"); | |
goto out; | |
} | |
if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) < 0) { | |
nlog(LG_SEVERE, "connect() failed!"); | |
goto out; | |
} | |
nlog(LG_DEBUG, "Connected!"); | |
err = 0; | |
out: | |
endhostent(); | |
return err; | |
} | |
void disconnect(void) | |
{ | |
if (sock < 0) { | |
nlog(LG_SEVERE, "Can't disconnect! (not connected)"); | |
return; | |
} | |
close(sock); | |
sock = -1; | |
nlog(LG_DEBUG, "Disconnected!"); | |
} | |
void do_read(int fd, char *buf, size_t *size) | |
{ | |
ssize_t sz; | |
sz = read(fd, buf + *size, BUFSIZE - *size); | |
if (sz <= 0) { | |
if (sz < 0) | |
nlog(LG_INFO, "Read error"); | |
running = 0; | |
return; | |
} | |
*size += sz; | |
} | |
void do_write(int fd, char *buf, size_t *size) | |
{ | |
ssize_t sz; | |
sz = write(fd, buf, *size); | |
if (sz <= 0) { | |
nlog(LG_INFO, "Write error"); | |
running = 0; | |
return; | |
} | |
*size -= sz; | |
if (*size > 0) | |
memmove(buf, buf + sz, *size); | |
} | |
void loop(void) | |
{ | |
fd_set r, w, x; | |
int err; | |
for (running=1; running;) { | |
FD_ZERO(&r); | |
FD_ZERO(&w); | |
FD_ZERO(&x); | |
FD_SET(0, &r); | |
FD_SET(sock, &r); | |
if (rb_size > 0) | |
FD_SET(1, &w); | |
if (sb_size > 0) | |
FD_SET(sock, &w); | |
err = select(sock + 1, &r, &w, &x, NULL); | |
if (FD_ISSET(0, &r)) | |
do_read(0, sendbuf, &sb_size); | |
if (FD_ISSET(sock, &r)) | |
do_read(sock, recvbuf, &rb_size); | |
if (FD_ISSET(1, &w)) | |
do_write(1, recvbuf, &rb_size); | |
if (FD_ISSET(sock, &w)) | |
do_write(sock, sendbuf, &sb_size); | |
} | |
} | |
int main(int argc, char *argv[]) | |
{ | |
if (argc != 3) { | |
fprintf(stderr, "Usage: %s HOST PORT\n", argv[0]); | |
return 1; | |
} | |
if (connect_to(argv[1], atoi(argv[2])) < 0) { | |
nlog(LG_SEVERE, "Connecting failed :("); | |
return 1; | |
} | |
loop(); | |
disconnect(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment