Переписать сишную прогу для IPV6
зачем так издеваться над 3proxy?
1. создании сокета (другой параметр указывается);
2. заполнении структуры sockaddr (ошибка у тебя, скорее всего, выдаётся на этом этапе).
При беглом просмотре твоего кода, я не нашёл ни первого, ни второго.
ак минимум, отличия ipv6 от ipv4 проявляются при:1. создании сокета (другой параметр указывается);2. заполнении структуры sockaddr (ошибка у тебя, скорее всего, выдаётся на этом этапе).При беглом просмотре твоего кода, я не нашёл ни первого, ни второго.ГДе то тут?
#ifndef MODULEMAINFUNC
#define MODULEMAINFUNC main
#define STDMAIN
#else
extern int linenum;
extern int haveerror;
#endif
int MODULEMAINFUNC (int argc, char** argv){
SOCKET sock = INVALID_SOCKET;
int i=0;
SASIZETYPE size;
pthread_t thread;
struct clientparam defparam;
int demon=0;
struct clientparam * newparam;
char *s;
int error = 0;
unsigned sleeptime;
struct extparam myconf;
unsigned char buf[256];
struct pollfd fds;
int opt = 1;
PROXYFUNC pf;
FILE *fp = NULL;
int maxchild;
int silent = 0;
int nlog = 5000;
char loghelp[] =
#ifdef STDMAIN
" -d go to background (daemon)\n"
#endif
" -fFORMAT logging format (see documentation)\n"
" -l log to stderr\n"
" -lFILENAME log to FILENAME\n"
" -bBUFSIZE size of network buffer (default 4096 for TCP, 16384 for UDP)\n"
#ifndef _WIN32
" -IDENT log to syslog IDENT\n"
#endif
" -t be silenT (do not log service start/stop)\n"
" -iIP ip address or internal interface (clients are expected to connect)\n"
" -eIP ip address or external interface (outgoing connection will have this)\n";
int childcount=0;
pthread_mutex_t counter_mutex;
#ifdef _WIN32
unsigned long ul;
#endif
#ifndef UDP
int new_sock = INVALID_SOCKET;
struct linger lg;
#endif
#ifdef _WIN32
HANDLE h;
#endif
#ifdef STDMAIN
#ifdef _WIN32
WSADATA wd;
WSAStartup(MAKEWORD( 1, 1 &wd);
#else
signal(SIGPIPE, SIG_IGN);
pthread_attr_init(&pa);
pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + 16384);
pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
#endif
#endif
pf = childdef.pf;
memcpy(&myconf, &conf, sizeof(myconf;
memset(&defparam, 0, sizeof(struct clientparam;
defparam.version = paused;
defparam.childcount = &childcount;
defparam.logfunc = myconf.logfunc;
defparam.authfunc = myconf.authfunc;
defparam.aclnum = myconf.aclnum;
defparam.service = childdef.service;
defparam.usentlm = 1;
defparam.stdlog = NULL;
defparam.time_start = time(NULL);
maxchild = myconf.maxchild;
#ifndef STDMAIN
if(!conf.services){
conf.services = &defparam;
}
else {
defparam.next = conf.services;
conf.services = conf.services->prev = &defparam;
}
#endif
pthread_mutex_init(defparam.counter_mutex = &counter_mutex, NULL);
for (i=1; i<argc; i++) {
if(*argv[i]=='-') {
switch(argv[i][1]) {
case 'd':
if(!demon)daemonize;
demon = 1;
break;
case 'l':
defparam.logfunc = logstdout;
defparam.logtarget = (unsigned char*)mystrdup(argv[i]);
if(argv[i][2]) {
#ifdef STDMAIN
if(argv[i][2]=='@'){
#ifndef _WIN32
openlog(argv[i]+3, LOG_PID, LOG_DAEMON);
defparam.logfunc = logsyslog;
#endif
}
else
#endif
{
fp = fopen(argv[i] + 2, "a");
if (fp) {
defparam.stdlog = fp;
fseek(fp, 0L, SEEK_END);
}
}
}
break;
case 'i':
myconf.intip = getipunsigned char *)argv[i]+2);
break;
case 'e':
myconf.extip = getipunsigned char *)argv[i]+2);
break;
case 'p':
myconf.intport = atoi(argv[i]+2);
break;
case 'b':
myconf.bufsize = atoi(argv[i]+2);
break;
case 'n':
defparam.usentlm = 0;
break;
case 'f':
defparam.logformat = (unsigned char *)argv[i] + 2;
break;
case 't':
silent = 1;
break;
case 's':
case 'a':
myconf.singlepacket = 1 + atoi(argv[i]+2);
break;
default:
error = 1;
break;
}
}
else break;
}
#ifndef STDMAIN
if(childdef.port) {
#endif
#ifndef PORTMAP
if (error || i!=argc) {
#ifndef STDMAIN
haveerror = 1;
conf.threadinit = 0;
#endif
fprintf(stderr, "Usage: %s options\n"
"Available options are:\n"
"%s"
" -pPORT - service port to accept connections\n"
"%s"
"\tExample: %s -i127.0.0.1\n\n"
"%s",
argv[0], loghelp, childdef.helpmessage, argv[0],
#ifdef STDMAIN
copyright
#else
""
#endif
);
return (1);
}
#endif
#ifndef STDMAIN
}
else {
#endif
#ifndef NOPORTMAP
if (error || argc != i+3 || *argv[i]=='-'|| (myconf.intport = atoi(argv[i]==0 || (defparam.targetport = htonsunsigned short)atoi(argv[i+2]==0) {
#ifndef STDMAIN
haveerror = 1;
conf.threadinit = 0;
#endif
fprintf(stderr, "Usage: %s options"
" [-e<external_ip>] <port_to_bind>"
" <target_hostname> <target_port>\n"
"Available options are:\n"
"%s"
"%s"
"\tExample: %s -d -i127.0.0.1 6666 serv.somehost.ru 6666\n\n"
"%s",
argv[0], loghelp, childdef.helpmessage, argv[0],
#ifdef STDMAIN
copyright
#else
""
#endif
);
return (1);
}
defparam.target = (unsigned char *)mystrdup(argv[i+1]);
#endif
#ifndef STDMAIN
}
#endif
if(!defparam.logformat){
defparam.logformat = myconf.logformat;
}
if(defparam.logformat){
if(*defparam.logformat == '-' && (s = strchrchar *)defparam.logformat + 1, '+' && s[1]){
*s = 0;
defparam.nonprintable = (unsigned char *)mystrdupchar *)defparam.logformat + 1);
defparam.replace = s[1];
defparam.logformat = (unsigned char *)mystrdup(s + 2);
*s = '+';
}
else defparam.logformat = (unsigned char *)mystrdupchar *)defparam.logformat);
}
defparam.sinc.sin_addr.s_addr = defparam.intip = myconf.intip;
if(!myconf.intport)myconf.intport = childdef.port;
defparam.sinc.sin_port = defparam.intport = htons(myconf.intport);
defparam.sins.sin_addr.s_addr = defparam.extip = myconf.extip;
defparam.sins.sin_port = defparam.extport = htons(myconf.extport);
defparam.remsock = defparam.clisock = defparam.ctrlsock = INVALID_SOCKET;
defparam.sins.sin_family = defparam.sinc.sin_family = AF_INET;
defparam.singlepacket = myconf.singlepacket;
defparam.bufsize = myconf.bufsize;
#ifndef STDMAIN
conf.threadinit = 0;
#endif
#ifndef UDP
lg.l_onoff = 1;
lg.l_linger = conf.timeouts[STRING_L];
if( (sock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP == INVALID_SOCKET) {
#else
if( (sock=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP == INVALID_SOCKET) {
#endif
perror("socket");
return -2;
}
#ifdef _WIN32
ioctlsocket(sock, FIONBIO, &ul);
#else
fcntl(sock,F_SETFL,O_NONBLOCK);
#endif
defparam.srvsock = sock;
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(intperror("setsockopt");
size = sizeof(defparam.sinc);
for(sleeptime = SLEEPTIME * 100; bind(sock, (struct sockaddr*)&defparam.sinc, size)==-1; usleep(sleeptime {
sprintfchar *)buf, "bind: %s", strerror(errno;
(*defparam.logfunc&defparam, buf);
sleeptime = (sleeptime<<1);
if(!sleeptime) {
closesocket(sock);
return -3;
}
}
#ifndef UDP
if(listen (sock, 1 + (maxchild>>4==-1) {
sprintfchar *)buf, "listen: %s", strerror(errno;
(*defparam.logfunc&defparam, buf);
return -4;
}
#else
defparam.srvfds = &fds;
defparam.clisock = sock;
#endif
defparam.thr
ГДе то тут?Да, где-то тут.
defparam.sinc.sin_addr.s_addr = defparam.intip = myconf.intip;
if(!myconf.intport)myconf.intport = childdef.port;
defparam.sinc.sin_port = defparam.intport = htons(myconf.intport);
defparam.sins.sin_addr.s_addr = defparam.extip = myconf.extip;
defparam.sins.sin_port = defparam.extport = htons(myconf.extport);
defparam.remsock = defparam.clisock = defparam.ctrlsock = INVALID_SOCKET;
defparam.sins.sin_family = defparam.sinc.sin_family = AF_INET;
defparam.singlepacket = myconf.singlepacket;
defparam.bufsize = myconf.bufsize;
#ifndef STDMAIN
conf.threadinit = 0;
#endif
#ifndef UDP
lg.l_onoff = 1;
lg.l_linger = conf.timeouts[STRING_L];
if( (sock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP == INVALID_SOCKET) {
#else
if( (sock=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP == INVALID_SOCKET) {
#endif
perror("socket");
return -2;
}
#ifdef _WIN32
ioctlsocket(sock, FIONBIO, &ul);
#else
fcntl(sock,F_SETFL,O_NONBLOCK);
#endif
defparam.srvsock = sock;
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(intperror("setsockopt");
size = sizeof(defparam.sinc);
Есть AF_INET6 и PF_INET6. Вообще, это все прекрасно описано в манах.
Есть AF_INET6 и PF_INET6. Вообще, это все прекрасно описано в манах.знать бы что читать..
man socket, man bind. Дальше по ссылкам
компилирую под MINGW на WIN32
пробовал уже разные методы, например при компиляции с использование getnameinfo выдёат unresolved external `getnameinfo`
мне бы примерчик заведомо рабочий в стиле
int main(void)
{
struct sockaddr_in stSockAddr;
int i32Res;
int i32SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(-1 == i32SocketFD)
{
perror("Ошибка: не могу создать сокет");
exit(EXIT_FAILURE);
}
memset(&stSockAddr, 0, sizeof(stSockAddr;
stSockAddr.sin_family = PF_INET;
stSockAddr.sin_port = htons(1100);
i32Res = inet_pton(PF_INET, "192.168.1.3", &stSockAddr.sin_addr);
if(0 > i32Res)
{
perror("Ошибка: первый параметр не относится к категории корректных адресов");
close(i32SocketFD);
exit(EXIT_FAILURE);
}
else if(0 == i32Res)
{
perror("char string (Ошибка: второй параметр не содержит корректный IP-адрес");
close(i32SocketFD);
exit(EXIT_FAILURE);
}
if(-1 == connect(i32SocketFD, (const void *)&stSockAddr, sizeof(stSockAddr
{
perror("Ошибка соединения");
close(i32SocketFD);
exit(EXIT_FAILURE);
}
/* выполнение операций чтения и записи ... */
shutdown(i32SocketFD, SHUT_RDWR);
close(i32SocketFD);
return 0;
}
тока для IV6
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
int main(void)
{
struct sockaddr_in6 stSockAddr;
int i32Res;
int i32SocketFD = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
if(-1 == i32SocketFD)
{
perror("Ошибка: не могу создать сокет");
exit(EXIT_FAILURE);
}
memset(&stSockAddr, 0, sizeof(stSockAddr;
stSockAddr.sin6_family = AF_INET6;
stSockAddr.sin6_port = htons(1100);
i32Res = inet_pton(AF_INET6, "2a00:1450:8004::93", &stSockAddr.sin6_addr);
if(0 > i32Res)
{
perror("Ошибка: первый параметр не относится к категории корректных адресов");
close(i32SocketFD);
exit(EXIT_FAILURE);
}
else if(0 == i32Res)
{
perror("char string (Ошибка: второй параметр не содержит корректный IP-адрес");
close(i32SocketFD);
exit(EXIT_FAILURE);
}
if(-1 == connect(i32SocketFD, (const void *)&stSockAddr, sizeof(stSockAddr
{
perror("Ошибка соединения");
close(i32SocketFD);
exit(EXIT_FAILURE);
}
/* выполнение операций чтения и записи ... */
shutdown(i32SocketFD, SHUT_RDWR);
close(i32SocketFD);
return 0;
}
сейчас у меня начало программы выглядит так:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <Winsock2.h>
#include <ws2tcpip.h>
то есть всё под винду (mingw winxp)...........
ПОд винду не могу найти рабочий пример ipv6
В мэйке сделующие либы
LIBS = -lws2_32 -lodbc32
Я подозреваю что сюда надо что то еще дописать чтобы pton использовать
А код из первого сообщения компилится? Способ компиляции точно такой же, как и в случае второго кода?
с CMD из папки с исходником.
ф-ция inet_pton UNRESOLVED EXTERNAL
Ну зарезолвь. Или замени ее на что-нибудь.
о бишь свой "заведомо рабочий примерчик" для IPv4 ты тоже скомпилить не можешь?Да, ввёл в заблуждение..,т.к. не сразу разобрался.
То что сейчас есть в исходнике выглядит так:
if param->remsock=socket(ipv6?AF_INET6:AF_INET, SOCK_STREAM, IPPROTO_TCP == INVALID_SOCKET) {return (11);}
param->sins.sin_family = 0?AF_INET6:AF_INET;
if (ipv6){
printf("SOCK6 start!connect\n");
struct sockaddr_in6 sin6;
sin6.sin6_family = AF_INET6;
sin6.sin6_flowinfo = 0;
sin6.sin6_port = htons(80);
if (inet_pton(AF_INET6,"2a00:1450:8007::68:\0",&sin6.sin6_addr )>0) printf ("RSOLVE O\n");
if (connect(param->remsock, (struct sockaddr *) &sin6, sizeof(sin6 == -1) {return (13);}
}
else
if(connect(param->remsockstruct sockaddr *)¶m->sins,sizeof(param->sins {return (13);}
пытаюсь скомпилить и вот вывод
gcc -oout.exe -Wall -O2 -s -mno-cygwin -mthreads 3 tcpmainfun
c.o udpmainfunc.o auth.o datatypes.o srvpop3p.o srvftppr.o srvsocks.o
srvtcppm.o srvudppm.o sockmap.o sockgetchar.o myalloc.o common.o mycrypt.o md5.
o md4.o base64.o ftp.o smbdes.o ntlm.o stringtable.o srvwebadmin.o srvdnspr.o -
lws2_32 -lodbc32
common.o:common.c:(.text+0x1858): undefined reference to `inet_pton'
collect2: ld returned 1 exit status
Ну не пользуйся им, пиши адрес сразу в двоичном виде.
странно, но в итоге connect dcё равно выдаёт -1 хотя и адрес пингуется и телнет на 80 порт работает
struct sockaddr_in6 sin6;
sin6.sin6_family = AF_INET6;
sin6.sin6_flowinfo = 0;
sin6.sin6_port = htons(80);//u_long _S6_u32[4];
sin6.sin6_addr._S6_un._S6_u32[0]=0x2a00;
sin6.sin6_addr._S6_un._S6_u32[1]=0x1450;
sin6.sin6_addr._S6_un._S6_u32[2]=0x8007;
sin6.sin6_addr._S6_un._S6_u32[3]=0x0068;
printf("try 6 connect\n");
if param->remsock=socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP == INVALID_SOCKET) {printf("error creating !\т"); return (11);}
if (connect(param->remsock, (struct sockaddr *) &sin6, sizeof(sin6 == -1) {printf("Error!\n"); return (13);}
как то так(не уверен в порядке байтов _S6_u32[0])?А я вот уверен в их количестве: в u32 4 байта, а не два, как ты написал.
-1
sin6.sin6_addr._S6_un._S6_u32[0]=0x00002a00;
sin6.sin6_addr._S6_un._S6_u32[1]=0x00001450;
sin6.sin6_addr._S6_un._S6_u32[2]=0x00008007;
sin6.sin6_addr._S6_un._S6_u32[3]=0x00000068;
sin6.sin6_addr._S6_un._S6_u32[0] = 0x2a001450;
sin6.sin6_addr._S6_un._S6_u32[1] = 0x80070000;
sin6.sin6_addr._S6_un._S6_u32[2] = 0x00000000;
sin6.sin6_addr._S6_un._S6_u32[3] = 0x00000068;
Но это будет правильно, только если у тебя хост BE, AFAIK.
В итоге не работает.
ВЫВОД:
param->remsock = -1 try 6 connect
param->remsock = 1840
aram->remsock = 1840 Error connect!
КОД:
struct sockaddr_in6 sin6;
sin6.sin6_family = AF_INET6;
sin6.sin6_flowinfo = 0;
sin6.sin6_port = htons(80);//u_long _S6_u32[4];
sin6.sin6_addr._S6_un._S6_u32[0] = 0x2a001450;
sin6.sin6_addr._S6_un._S6_u32[1] = 0x80070000;
sin6.sin6_addr._S6_un._S6_u32[2] = 0x00000000;
sin6.sin6_addr._S6_un._S6_u32[3] = 0x00000068;
printf(" param->remsock = %d try 6 connect\n", param->remsock);
if param->remsock=socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP == INVALID_SOCKET) {printf("param->remsock = %d error creating !\т", param->remsock); return (11);}
printf("param->remsock = %d\n", param->remsock);
if (connect(param->remsock, (struct sockaddr *) &sin6, sizeof(sin6 == -1) {printf("aram->remsock = %d Error connect!\n", param->remsock); return (13);}
Под хост я имел ввиду хост из торйки build-host-target. То бишь компьютер, где выполняется программа. И да, я сильно смоневаюсь, что он у тебя Big-Endian.
http://%5B2a00:1450:8007::68:%5D превосходно открывается!
она выполняется на обычном компе официалки из оперы гугль пробовал так
sin6.sin6_addr._S6_un._S6_u32[0] = 0x2a001450;
sin6.sin6_addr._S6_un._S6_u32[1] = 0x8007006A;
sin6.sin6_addr._S6_un._S6_u32[2] = 0x00000000;
sin6.sin6_addr._S6_un._S6_u32[3] = 0x00000000;
и так
sin6.sin6_addr._S6_un._S6_u32[0] = 0x2a001450;
sin6.sin6_addr._S6_un._S6_u32[1] = 0x80070000;
sin6.sin6_addr._S6_un._S6_u32[2] = 0x00000000;
sin6.sin6_addr._S6_un._S6_u32[3] = 0x0000006A;
Короче, иди ботай матчасть (про сокеты, IP-адреса и их запись, endianness и прочее). А то ты сейчас как студент-двоечник на экзамене, пытающийся угадать формулировку теоремы.
Короче, иди ботай матчасть (про сокеты, IP-адреса и их запись, endianness и прочее). А то ты сейчас как студент-двоечник на экзамене, пытающийся угадать формулировку теоремы.Ну я щас явно не на экзамене =)
Насчет матчасти - пока нету времени ботать ее, я подозревал что задача как то легко решается. но видимо ошибался и всё не так просто.
Оставить комментарий
356ft85
Не очень ориентируюсь, но в каком месте нужно переписывать программу, которая нормально работает на IPV4 а вот если ей на вход подать ipv6 адрес то получаю Bad host name.я так понимаю что это может быть связано с тем что где то в программе она опирается на то что после преобразования получает адрес в виде строки xxx.xxx.xxx.xxx ? или там нужно глобально отказываться от WINSOCK ?
кусок кода в котором на мой взгляд проблема