/* * Splice stdin to net */ #include #include #include #include #include #include #include #define SPLICE_SIZE (64*1024) #if defined(__i386__) #define __NR_splice 313 #elif defined(__x86_64__) #define __NR_splice 275 #elif defined(__powerpc__) || defined(__powerpc64__) #define __NR_splice 283 #else #error unsupported arch #endif static inline int splice(int fdin, int fdout, size_t len, unsigned long flags) { return syscall(__NR_splice, fdin, fdout, len, flags); } int main(int argc, char *argv[]) { struct sockaddr_in addr; unsigned short port; int fd; if (argc < 3) { printf("%s: target port\n", argv[0]); return 1; } port = atoi(argv[2]); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); if (inet_aton(argv[1], &addr.sin_addr) != 1) { struct hostent *hent = gethostbyname(argv[1]); if (!hent) { perror("gethostbyname"); return 1; } memcpy(&addr.sin_addr, hent->h_addr, 4); } printf("Connecting to %s/%d\n", argv[1], port); fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { perror("socket"); return 1; } if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("connect"); return 1; } do { int ret = splice(STDIN_FILENO, fd, SPLICE_SIZE, 0); if (ret < 0) { perror("splice"); break; } else if (!ret) { break; } } while (1); close(fd); return 0; }