mirror of
https://github.com/0intro/libtask
synced 2024-11-21 21:31:30 +03:00
implement ipv6
This commit is contained in:
parent
e82890a2aa
commit
f5ea2e72ba
3
Makefile
3
Makefile
@ -12,10 +12,11 @@ OFILES=\
|
|||||||
qlock.o\
|
qlock.o\
|
||||||
rendez.o\
|
rendez.o\
|
||||||
task.o\
|
task.o\
|
||||||
|
ip.o\
|
||||||
|
|
||||||
all: $(LIB) primes tcpproxy testdelay
|
all: $(LIB) primes tcpproxy testdelay
|
||||||
|
|
||||||
$(OFILES): taskimpl.h task.h 386-ucontext.h power-ucontext.h
|
$(OFILES): taskimpl.h task.h 386-ucontext.h power-ucontext.h ip.h
|
||||||
|
|
||||||
AS=gcc -c
|
AS=gcc -c
|
||||||
CC=gcc
|
CC=gcc
|
||||||
|
@ -9,10 +9,11 @@ OFILES=\
|
|||||||
qlock.o\
|
qlock.o\
|
||||||
rendez.o\
|
rendez.o\
|
||||||
task.o\
|
task.o\
|
||||||
|
ip.o\
|
||||||
|
|
||||||
all: $(LIB) primes tcpproxy testdelay
|
all: $(LIB) primes tcpproxy testdelay
|
||||||
|
|
||||||
$(OFILES): taskimpl.h task.h 386-ucontext.h power-ucontext.h
|
$(OFILES): taskimpl.h task.h 386-ucontext.h power-ucontext.h ip.h
|
||||||
|
|
||||||
AS=as
|
AS=as
|
||||||
CC=cc
|
CC=cc
|
||||||
|
4
README
4
README
@ -131,10 +131,10 @@ int netaccept(int fd, char *server, int *port)
|
|||||||
Get the next connection that comes in to the listener fd.
|
Get the next connection that comes in to the listener fd.
|
||||||
Returns a fd to use to talk to the guy who just connected.
|
Returns a fd to use to talk to the guy who just connected.
|
||||||
If server is not null, it must point at a buffer of at least
|
If server is not null, it must point at a buffer of at least
|
||||||
16 bytes that is filled in with the remote IP address.
|
46 bytes that is filled in with the remote IP address.
|
||||||
If port is not null, it is filled in with the report port.
|
If port is not null, it is filled in with the report port.
|
||||||
Example:
|
Example:
|
||||||
char server[16];
|
char server[46];
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
if(netaccept(fd, server, &port) >= 0)
|
if(netaccept(fd, server, &port) >= 0)
|
||||||
|
211
ip.c
Normal file
211
ip.c
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
#include "taskimpl.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "ip.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
hnputl(void *p, uint v)
|
||||||
|
{
|
||||||
|
uchar *a;
|
||||||
|
|
||||||
|
a = p;
|
||||||
|
a[0] = v>>24;
|
||||||
|
a[1] = v>>16;
|
||||||
|
a[2] = v>>8;
|
||||||
|
a[3] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hnputs(void *p, ushort v)
|
||||||
|
{
|
||||||
|
uchar *a;
|
||||||
|
|
||||||
|
a = p;
|
||||||
|
a[0] = v>>8;
|
||||||
|
a[1] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
nhgetl(void *p)
|
||||||
|
{
|
||||||
|
unsigned char *a;
|
||||||
|
|
||||||
|
a = p;
|
||||||
|
return (a[0]<<24)|(a[1]<<16)|(a[2]<<8)|(a[3]<<0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
nhgets(void *p)
|
||||||
|
{
|
||||||
|
unsigned char *a;
|
||||||
|
|
||||||
|
a = p;
|
||||||
|
return (a[0]<<8)|(a[1]<<0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
v4parseip(unsigned char *to, char *from)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = from;
|
||||||
|
for(i = 0; i < 4 && *p; i++){
|
||||||
|
to[i] = strtoul(p, &p, 0);
|
||||||
|
if(*p == '.')
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
switch(CLASS(to)){
|
||||||
|
case 0: /* class A - 1 uchar net */
|
||||||
|
case 1:
|
||||||
|
if(i == 3){
|
||||||
|
to[3] = to[2];
|
||||||
|
to[2] = to[1];
|
||||||
|
to[1] = 0;
|
||||||
|
} else if (i == 2){
|
||||||
|
to[3] = to[1];
|
||||||
|
to[1] = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: /* class B - 2 uchar net */
|
||||||
|
if(i == 3){
|
||||||
|
to[3] = to[2];
|
||||||
|
to[2] = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ipcharok(int c)
|
||||||
|
{
|
||||||
|
return c == '.' || c == ':' || (isascii(c) && isxdigit(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
delimchar(int c)
|
||||||
|
{
|
||||||
|
if(c == '\0')
|
||||||
|
return 1;
|
||||||
|
if(c == '.' || c == ':' || (isascii(c) && isalnum(c)))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
parseip(uchar *to, char *from)
|
||||||
|
{
|
||||||
|
int i, elipsis = 0, v4 = 1;
|
||||||
|
uint32_t x;
|
||||||
|
char *p, *op;
|
||||||
|
|
||||||
|
memset(to, 0, IPaddrlen);
|
||||||
|
p = from;
|
||||||
|
for(i = 0; i < IPaddrlen && ipcharok(*p); i+=2){
|
||||||
|
op = p;
|
||||||
|
x = strtoul(p, &p, 16);
|
||||||
|
if(*p == '.' || (*p == 0 && i == 0)){ /* ends with v4? */
|
||||||
|
p = v4parseip(to+i, op);
|
||||||
|
i += 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* v6: at most 4 hex digits, followed by colon or delim */
|
||||||
|
if(x != (ushort)x || (*p != ':' && !delimchar(*p))) {
|
||||||
|
memset(to, 0, IPaddrlen);
|
||||||
|
return -1; /* parse error */
|
||||||
|
}
|
||||||
|
to[i] = x>>8;
|
||||||
|
to[i+1] = x;
|
||||||
|
if(*p == ':'){
|
||||||
|
v4 = 0;
|
||||||
|
if(*++p == ':'){ /* :: is elided zero short(s) */
|
||||||
|
if (elipsis) {
|
||||||
|
memset(to, 0, IPaddrlen);
|
||||||
|
return -1; /* second :: */
|
||||||
|
}
|
||||||
|
elipsis = i+2;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
} else if (p == op) /* strtoul made no progress? */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (p == from || !delimchar(*p)) {
|
||||||
|
memset(to, 0, IPaddrlen);
|
||||||
|
return -1; /* parse error */
|
||||||
|
}
|
||||||
|
if(i < IPaddrlen){
|
||||||
|
memmove(&to[elipsis+IPaddrlen-i], &to[elipsis], i-elipsis);
|
||||||
|
memset(&to[elipsis], 0, IPaddrlen-i);
|
||||||
|
}
|
||||||
|
if(v4){
|
||||||
|
to[10] = to[11] = 0xff;
|
||||||
|
return nhgetl(to + IPv4off);
|
||||||
|
} else
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
uchar IPnoaddr[IPaddrlen];
|
||||||
|
|
||||||
|
uchar v4prefix[IPaddrlen] = {
|
||||||
|
0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
0, 0, 0xff, 0xff,
|
||||||
|
0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
isv4(uchar *ip)
|
||||||
|
{
|
||||||
|
return memcmp(ip, v4prefix, IPv4off) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
v4tov6(unsigned char *v6, unsigned char *v4)
|
||||||
|
{
|
||||||
|
v6[0] = 0;
|
||||||
|
v6[1] = 0;
|
||||||
|
v6[2] = 0;
|
||||||
|
v6[3] = 0;
|
||||||
|
v6[4] = 0;
|
||||||
|
v6[5] = 0;
|
||||||
|
v6[6] = 0;
|
||||||
|
v6[7] = 0;
|
||||||
|
v6[8] = 0;
|
||||||
|
v6[9] = 0;
|
||||||
|
v6[10] = 0xff;
|
||||||
|
v6[11] = 0xff;
|
||||||
|
v6[12] = v4[0];
|
||||||
|
v6[13] = v4[1];
|
||||||
|
v6[14] = v4[2];
|
||||||
|
v6[15] = v4[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
v6tov4(unsigned char *v4, unsigned char *v6)
|
||||||
|
{
|
||||||
|
if(v6[0] == 0
|
||||||
|
&& v6[1] == 0
|
||||||
|
&& v6[2] == 0
|
||||||
|
&& v6[3] == 0
|
||||||
|
&& v6[4] == 0
|
||||||
|
&& v6[5] == 0
|
||||||
|
&& v6[6] == 0
|
||||||
|
&& v6[7] == 0
|
||||||
|
&& v6[8] == 0
|
||||||
|
&& v6[9] == 0
|
||||||
|
&& v6[10] == 0xff
|
||||||
|
&& v6[11] == 0xff)
|
||||||
|
{
|
||||||
|
v4[0] = v6[12];
|
||||||
|
v4[1] = v6[13];
|
||||||
|
v4[2] = v6[14];
|
||||||
|
v4[3] = v6[15];
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
memset(v4, 0, 4);
|
||||||
|
if(memcmp(v6, IPnoaddr, IPaddrlen) == 0)
|
||||||
|
return 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
32
ip.h
Normal file
32
ip.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef _IP_H_
|
||||||
|
#define _IP_H_ 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
IPaddrlen = 16,
|
||||||
|
IPv4addrlen = 4,
|
||||||
|
IPv4off = 12
|
||||||
|
};
|
||||||
|
|
||||||
|
int isv4(unsigned char*);
|
||||||
|
uint32_t parseip(unsigned char*, char*);
|
||||||
|
char* v4parseip(unsigned char*, char*);
|
||||||
|
|
||||||
|
void hnputl(void*, uint32_t);
|
||||||
|
void hnputs(void*, uint16_t);
|
||||||
|
uint32_t nhgetl(void*);
|
||||||
|
uint16_t nhgets(void*);
|
||||||
|
|
||||||
|
int v6tov4(unsigned char*, unsigned char*);
|
||||||
|
void v4tov6(unsigned char*, unsigned char*);
|
||||||
|
|
||||||
|
#define CLASS(p) ((*(uchar*)(p))>>6)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
166
net.c
166
net.c
@ -4,29 +4,56 @@
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
|
#include "ip.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
family(unsigned char *addr)
|
||||||
|
{
|
||||||
|
if(isv4(addr))
|
||||||
|
return AF_INET;
|
||||||
|
return AF_INET6;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
netannounce(int istcp, char *server, int port)
|
netannounce(int istcp, char *server, int port)
|
||||||
{
|
{
|
||||||
int fd, n, proto;
|
int fd, n, proto;
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_storage ss;
|
||||||
socklen_t sn;
|
socklen_t sn;
|
||||||
uint32_t ip;
|
unsigned char ip[IPaddrlen];
|
||||||
|
|
||||||
taskstate("netannounce");
|
taskstate("netannounce");
|
||||||
proto = istcp ? SOCK_STREAM : SOCK_DGRAM;
|
proto = istcp ? SOCK_STREAM : SOCK_DGRAM;
|
||||||
memset(&sa, 0, sizeof sa);
|
memset(&ss, 0, sizeof ss);
|
||||||
sa.sin_family = AF_INET;
|
|
||||||
if(server != nil && strcmp(server, "*") != 0){
|
if(server != nil && strcmp(server, "*") != 0){
|
||||||
if(netlookup(server, &ip) < 0){
|
if(netlookup(server, ip) < 0){
|
||||||
taskstate("netlookup failed");
|
taskstate("netlookup failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memmove(&sa.sin_addr, &ip, 4);
|
ss.ss_family = family(ip);
|
||||||
|
switch(ss.ss_family){
|
||||||
|
case AF_INET:
|
||||||
|
v6tov4((unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr, ip);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
memcpy(&((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, ip, sizeof(struct in6_addr));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
sa.sin_port = htons(port);
|
}else{
|
||||||
if((fd = socket(AF_INET, proto, 0)) < 0){
|
ss.ss_family = AF_INET6;
|
||||||
|
((struct sockaddr_in6*)&ss)->sin6_addr = in6addr_any;
|
||||||
|
}
|
||||||
|
switch(ss.ss_family){
|
||||||
|
case AF_INET:
|
||||||
|
hnputs(&((struct sockaddr_in*)&ss)->sin_port, port);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if((fd = socket(ss.ss_family, proto, 0)) < 0){
|
||||||
taskstate("socket failed");
|
taskstate("socket failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -37,7 +64,7 @@ netannounce(int istcp, char *server, int port)
|
|||||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof n);
|
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof n);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bind(fd, (struct sockaddr*)&sa, sizeof sa) < 0){
|
if(bind(fd, (struct sockaddr*)&ss, sizeof ss) < 0){
|
||||||
taskstate("bind failed");
|
taskstate("bind failed");
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
@ -55,24 +82,32 @@ int
|
|||||||
netaccept(int fd, char *server, int *port)
|
netaccept(int fd, char *server, int *port)
|
||||||
{
|
{
|
||||||
int cfd, one;
|
int cfd, one;
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_storage ss;
|
||||||
uchar *ip;
|
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
|
|
||||||
fdwait(fd, 'r');
|
fdwait(fd, 'r');
|
||||||
|
|
||||||
taskstate("netaccept");
|
taskstate("netaccept");
|
||||||
len = sizeof sa;
|
len = sizeof ss;
|
||||||
if((cfd = accept(fd, (void*)&sa, &len)) < 0){
|
if((cfd = accept(fd, (void*)&ss, &len)) < 0){
|
||||||
taskstate("accept failed");
|
taskstate("accept failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(server){
|
|
||||||
ip = (uchar*)&sa.sin_addr;
|
switch(ss.ss_family){
|
||||||
snprint(server, 16, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
case AF_INET:
|
||||||
}
|
if(server)
|
||||||
|
inet_ntop(AF_INET, &((struct sockaddr_in*)&ss)->sin_addr.s_addr, server, INET_ADDRSTRLEN);
|
||||||
if(port)
|
if(port)
|
||||||
*port = ntohs(sa.sin_port);
|
*port = nhgets(&((struct sockaddr_in*)&ss)->sin_port);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
if(server)
|
||||||
|
inet_ntop(AF_INET6, &((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, server, INET6_ADDRSTRLEN);
|
||||||
|
if(port)
|
||||||
|
*port = nhgets(&((struct sockaddr_in6*)&ss)->sin6_port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
fdnoblock(cfd);
|
fdnoblock(cfd);
|
||||||
one = 1;
|
one = 1;
|
||||||
setsockopt(cfd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof one);
|
setsockopt(cfd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof one);
|
||||||
@ -80,64 +115,30 @@ netaccept(int fd, char *server, int *port)
|
|||||||
return cfd;
|
return cfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CLASS(p) ((*(unsigned char*)(p))>>6)
|
|
||||||
static int
|
|
||||||
parseip(char *name, uint32_t *ip)
|
|
||||||
{
|
|
||||||
unsigned char addr[4];
|
|
||||||
char *p;
|
|
||||||
int i, x;
|
|
||||||
|
|
||||||
p = name;
|
|
||||||
for(i=0; i<4 && *p; i++){
|
|
||||||
x = strtoul(p, &p, 0);
|
|
||||||
if(x < 0 || x >= 256)
|
|
||||||
return -1;
|
|
||||||
if(*p != '.' && *p != 0)
|
|
||||||
return -1;
|
|
||||||
if(*p == '.')
|
|
||||||
p++;
|
|
||||||
addr[i] = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(CLASS(addr)){
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
if(i == 3){
|
|
||||||
addr[3] = addr[2];
|
|
||||||
addr[2] = addr[1];
|
|
||||||
addr[1] = 0;
|
|
||||||
}else if(i == 2){
|
|
||||||
addr[3] = addr[1];
|
|
||||||
addr[2] = 0;
|
|
||||||
addr[1] = 0;
|
|
||||||
}else if(i != 4)
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if(i == 3){
|
|
||||||
addr[3] = addr[2];
|
|
||||||
addr[2] = 0;
|
|
||||||
}else if(i != 4)
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*ip = *(uint32_t*)addr;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
netlookup(char *name, uint32_t *ip)
|
netlookup(char *name, unsigned char *ip)
|
||||||
{
|
{
|
||||||
struct hostent *he;
|
struct hostent *he;
|
||||||
|
struct addrinfo *result;
|
||||||
|
|
||||||
if(parseip(name, ip) >= 0)
|
if(parseip(ip, name) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* BUG - Name resolution blocks. Need a non-blocking DNS. */
|
/* BUG - Name resolution blocks. Need a non-blocking DNS. */
|
||||||
taskstate("netlookup");
|
taskstate("netlookup");
|
||||||
if((he = gethostbyname(name)) != 0){
|
if((he = gethostbyname(name)) != 0){
|
||||||
*ip = *(uint32_t*)he->h_addr;
|
ip = (unsigned char*)he->h_addr;
|
||||||
|
taskstate("netlookup succeeded");
|
||||||
|
return 0;
|
||||||
|
}else if(getaddrinfo(name, NULL, NULL, &result) == 0) {
|
||||||
|
switch (result->ai_family) {
|
||||||
|
case AF_INET:
|
||||||
|
v4tov6(ip, (unsigned char*)&((struct sockaddr_in*)result->ai_addr)->sin_addr.s_addr);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
memcpy(ip, (unsigned char*)&((struct sockaddr_in6*)result->ai_addr)->sin6_addr.s6_addr, sizeof(struct in6_addr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
taskstate("netlookup succeeded");
|
taskstate("netlookup succeeded");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -150,16 +151,16 @@ int
|
|||||||
netdial(int istcp, char *server, int port)
|
netdial(int istcp, char *server, int port)
|
||||||
{
|
{
|
||||||
int proto, fd, n;
|
int proto, fd, n;
|
||||||
uint32_t ip;
|
unsigned char ip[IPaddrlen];
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_storage ss;
|
||||||
socklen_t sn;
|
socklen_t sn;
|
||||||
|
|
||||||
if(netlookup(server, &ip) < 0)
|
if(netlookup(server, ip) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
taskstate("netdial");
|
taskstate("netdial");
|
||||||
proto = istcp ? SOCK_STREAM : SOCK_DGRAM;
|
proto = istcp ? SOCK_STREAM : SOCK_DGRAM;
|
||||||
if((fd = socket(AF_INET, proto, 0)) < 0){
|
if((fd = socket(family(ip), proto, 0)) < 0){
|
||||||
taskstate("socket failed");
|
taskstate("socket failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -172,11 +173,20 @@ netdial(int istcp, char *server, int port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* start connecting */
|
/* start connecting */
|
||||||
memset(&sa, 0, sizeof sa);
|
memset(&ss, 0, sizeof ss);
|
||||||
memmove(&sa.sin_addr, &ip, 4);
|
ss.ss_family = family(ip);
|
||||||
sa.sin_family = AF_INET;
|
switch(ss.ss_family){
|
||||||
sa.sin_port = htons(port);
|
case AF_INET:
|
||||||
if(connect(fd, (struct sockaddr*)&sa, sizeof sa) < 0 && errno != EINPROGRESS){
|
v6tov4((unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr, ip);
|
||||||
|
hnputs(&((struct sockaddr_in*)&ss)->sin_port, port);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
memcpy(&((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, ip, sizeof(struct in6_addr));
|
||||||
|
hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(connect(fd, (struct sockaddr*)&ss, sizeof ss) < 0 && errno != EINPROGRESS){
|
||||||
taskstate("connect failed");
|
taskstate("connect failed");
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
@ -184,8 +194,8 @@ netdial(int istcp, char *server, int port)
|
|||||||
|
|
||||||
/* wait for finish */
|
/* wait for finish */
|
||||||
fdwait(fd, 'w');
|
fdwait(fd, 'w');
|
||||||
sn = sizeof sa;
|
sn = sizeof ss;
|
||||||
if(getpeername(fd, (struct sockaddr*)&sa, &sn) >= 0){
|
if(getpeername(fd, (struct sockaddr*)&ss, &sn) >= 0){
|
||||||
taskstate("connect succeeded");
|
taskstate("connect succeeded");
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
2
task.h
2
task.h
@ -172,7 +172,7 @@ enum
|
|||||||
int netannounce(int, char*, int);
|
int netannounce(int, char*, int);
|
||||||
int netaccept(int, char*, int*);
|
int netaccept(int, char*, int*);
|
||||||
int netdial(int, char*, int);
|
int netdial(int, char*, int);
|
||||||
int netlookup(char*, uint32_t*); /* blocks entire program! */
|
int netlookup(char*, unsigned char*); /* blocks entire program! */
|
||||||
int netdial(int, char*, int);
|
int netdial(int, char*, int);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -38,7 +38,7 @@ taskmain(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int cfd, fd;
|
int cfd, fd;
|
||||||
int rport;
|
int rport;
|
||||||
char remote[16];
|
char remote[46];
|
||||||
|
|
||||||
if(argc != 4){
|
if(argc != 4){
|
||||||
fprintf(stderr, "usage: tcpproxy localport server remoteport\n");
|
fprintf(stderr, "usage: tcpproxy localport server remoteport\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user