Skip to content

Instantly share code, notes, and snippets.

@aji
Created March 27, 2013 23:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aji/5259202 to your computer and use it in GitHub Desktop.
Save aji/5259202 to your computer and use it in GitHub Desktop.
netcat clone hacked together in 30 minutes
#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