Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Работает в VisualC++ и не работает в CBuilder!!!  (Прочитано 9396 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ogurets
Гость
« : 28-06-2004 21:43 » new

SOS! HELP! Есть программа работающая с raw сокетом.
В CBuilder(5-я версия) в ней была такая ошибка: при юзании флага IP_HDRINCL в setsockopt функция sendto давала ошибку 10022(не помню что это, да и неважно). Без этого флага всё работало, но блин заголовок-то уже не тот Жаль В лепешку разбился, как исправить - непонятно...Ну ладно, нашел в инете другую программу, слегка поправил - в том же Билдере не работает!!! Ошибка WSAEADDRNOTAVAIL, хотя это бред полный - адреса в норме, заголовки пакетов тоже. Что самое интересное, ТОТ ЖЕ КОД откомпиленный в Visual C++ 6 РАБОТАЕТ ПРЕКРАСНО! ПОМОГИТЕ! Не знаю уже что делать...на Visual C++ перенести свою исходную программу не могу - придется всю визуальную часть переписывать, а время поджимает.
Система Win2000 Server Service pack 3, winsock version 2.2, код программы см. далее(IP-адрес в bind'е исправьте ессно на свой локальный, иначе не заработает...):

main.cpp
Код:
#include "head.h" 
#include "check.cpp"
#include <conio.h>

#define PORT 80

int main(void)
{
WSADATA wsd;
char *datagram="";
int bOpt = 1;
char info[30] ="das ist ein test";

if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("WSAStartup() failed: %d\n", GetLastError());
return -1;
}

// Create a raw socket

SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (s == INVALID_SOCKET)
{
printf("WSASocket() failed: %d\n", WSAGetLastError());
return -1;
}



struct ipheader *iph = (struct ipheader *) malloc(sizeof(struct
ipheader));
struct tcpheader *tcph = (struct tcpheader *) malloc( sizeof
(struct tcpheader));
struct body *bo = (struct body *) malloc( sizeof (struct body));
struct ps_hdr *ps = (struct ps_hdr *) malloc( sizeof (struct
ps_hdr));

datagram = (char *) malloc(sizeof(struct ipheader) + sizeof(struct
tcpheader)+sizeof (struct body));



struct sockaddr_in sin;



iph= (struct ipheader *) datagram;
tcph=(struct tcpheader *) (datagram+ sizeof(struct ipheader));
bo= (struct body *) (datagram+sizeof(struct ipheader)+ sizeof(struct
tcpheader));
memset(bo->data,'\0',sizeof(body));


sin.sin_family = AF_INET;
sin.sin_port = htons (PORT);
sin.sin_addr.s_addr = inet_addr ("213.180.216.200");


//printf("%i\n",sizeof(datagram));
iph->ip_hl = 5;
iph->ip_v = 4;
iph->ip_tos = 0;
iph->ip_len = sizeof (struct ipheader) + sizeof (struct
tcpheader)+sizeof(struct body);

iph->ip_id = 1;
iph->ip_off = 0;
iph->ip_ttl = 255;
iph->ip_p = 6;
iph->ip_sum = 0;
iph->ip_src = inet_addr ("213.180.216.200");
iph->ip_dst = sin.sin_addr.s_addr;

tcph->th_sport = htons (PORT);
tcph->th_dport = htons (PORT);
tcph->th_seq = rand();
tcph->th_ack = htons (6234);
tcph->th_x2 = 0;
tcph->th_off = 5;
tcph->th_flags = 16; // SYN
tcph->th_win = htons(65535);
tcph->th_sum = 0;
tcph->th_urp = 0;





// Build the Psuedo Header

ps->source_address = inet_addr ("213.180.216.200");
ps->dest_address = sin.sin_addr.s_addr;
ps->placeholder = 0;
ps->protocol = IPPROTO_TCP;
ps->tcp_length = htons(sizeof(struct tcpheader)+sizeof(struct
body));

ps->tcp = *tcph;
ps->data=*bo;

strcpy((char *)bo->data,info);
// Calculate Checksum


tcph->th_sum = checksum((unsigned short *)ps, sizeof(struct
ps_hdr));
iph->ip_sum = checksum((unsigned short *)iph, sizeof(struct
ipheader));




// ENABLE IPHDRINCL
sockaddr_in sii;
int sin_len=sizeof(sii);
memset(&sii, 0, sin_len);
sii.sin_family = AF_INET;
sii.sin_port = htons(1080);
sii.sin_addr.s_addr = inet_addr ("62.33.238.3");
if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt,
sizeof(bOpt)) == SOCKET_ERROR)
{
printf("setsockopt(IP_HDRINCL) failed: %d\n", WSAGetLastError());
return -1;
}
if (bind(s, (const sockaddr *)&sii, sin_len) == SOCKET_ERROR)
{
printf("bind failed: %d\n", WSAGetLastError());
return -1;
}


// Send The Packet
char *target=inet_ntoa(sin.sin_addr);
char buf[16];
memcpy(buf, target, 16);

if (sendto(s, datagram, iph->ip_len, 0, (SOCKADDR *)&sin,
sizeof(sin)) == SOCKET_ERROR)
{
printf("sendto() failed: %d\n", WSAGetLastError());
return -1;
}

getch();
return 0;
}
check.cpp
Код:
unsigned short checksum(unsigned short *addr, int len) 
{
register int sum = 0;
u_short answer = 0;
register u_short *w = addr;
register int nleft = len;

/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we
add
* sequential 16 bit words to it, and at the end, fold back all
the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}

/* mop up an odd byte, if necessary */
if (nleft == 1)
{
*(u_char *) (&answer) = *(u_char *) w;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff);/* add hi 16 to low 16 */
sum += (sum >> 16);/* add carry */
answer = ~sum;/* truncate to 16 bits */
return (answer);
}
head.h
Код:
#include <winsock2.h> 
#include <ws2tcpip.h>
#include <stdio.h>

unsigned short checksum(unsigned short *addr, int len);

struct tcpheader {
unsigned short int th_sport;
unsigned short int th_dport;
unsigned int th_seq;
unsigned int th_ack;
unsigned char th_x2:4, th_off:4;
unsigned char th_flags;
unsigned short int th_win;
unsigned short int th_sum;
unsigned short int th_urp;
}; /* total tcp header length: 20 bytes (=160 bits) */

struct ipheader {
unsigned char ip_hl:4, ip_v:4; /* this means that each member is 4
bits */
unsigned char ip_tos;
unsigned short int ip_len;
unsigned short int ip_id;
unsigned short int ip_off;
unsigned char ip_ttl;
unsigned char ip_p;
unsigned short int ip_sum;
unsigned int ip_src;
unsigned int ip_dst;
}; /* total ip header length: 20 bytes (=160 bits) */

// Psuedo Header


struct body
{

unsigned char data [40];


};


struct ps_hdr
{
unsigned int source_address; // Source Address => 4 Bytes
unsigned int dest_address; // Destination Address => 4 Bytes
unsigned char placeholder; // Place Holder => 1 Bytes
unsigned char protocol; // Protocol => 1 Bytes
unsigned short tcp_length; // TCP Length => + 2 Bytes

struct tcpheader tcp;
struct body data;

};
« Последнее редактирование: 29-11-2007 15:22 от Алексей1153++ » Записан
ogurets
Гость
« Ответ #1 : 29-06-2004 13:24 » 

Всё! Въехал! Дело в библиотеках - Билдер подключает wsock32.lib, а VC - ws2_32.lib
Теперь непонятно, как заставить Билдера подключать ws2_32??? #pragma link не работает - все равно подключает не то что надо, копания в опциях результатов не дали Жаль
Записан
ixania
Гость
« Ответ #2 : 01-07-2004 09:34 » 

Project->Add to Project... then in add to project dialog select in the drop down list *.lib extention, %BUILDER_INSTAL_DIR%\LIB and add the lib you need  Ага
Записан
ogurets
Гость
« Ответ #3 : 01-07-2004 09:51 » 

Цитата: ixania
Project->Add to Project... then in add to project dialog select in the drop down list *.lib extention, %BUILDER_INSTAL_DIR%\LIB and add the lib you need  Ага

Если б все было так просто Улыбаюсь Либу в проект добавляет, но линкует все равно wsock32
Кстати, wsock32 - это похоже жуткий глюк Билдера, поскольку привязка к ее dll'ке идет в системной библиотеке import32.lib. Сейчас пытаюсь ссылку оттуда выковыривать, пока получаю только жуткие матюки линкера Жаль
Записан
ogurets
Гость
« Ответ #4 : 01-07-2004 13:28 » 

АААААААААА!!!! Победааа! Тем кто еще мучается, рассказываю секрет:
Поскольку дело в отстойной import32.lib, берем утиль implib, им обгрызаем аккуратненько kernel32.dll и user32.dll, получаем библиотеку(.lib). Подключаем ее вместо import32.lib(я нашел один безотказный способ - грязно вырезать ее имя из билдеровского проектного файла(.bpr) и всунуть туда свою библиотеку). Можно кстати(и так даже, имхо, красивее) подключить ее через #pragma link в основном модуле, но это уже дело вкуса. И может быть придется покопаться hexeditor'ом в Cw32.lib чтобы пофиксить баг с printf'ом. Дело в том что в Борланд почему-то считают что функция wsprintfA пишется как _wsprintfA, и почему-то у них так все работает. А у нас работать не будет, поэтому надо вручную заменить имя на правильное, такое какое оно есть в user32.dll. Но это все фигня, зато вы наконец познакомитесь с winAPI(самые хитрые правда познакомятся только с поиском текста по dll'кам...), и сможете наконец что-то сделать с этим гадским глюком сетевой библиотеки!!! И не только! На моей программке например такая операция еще и уменьшила размер exe'шника на пару килобайт! В VC кстати с настройками по умолчанию + ws2_32.lib было на 100 Кб больше! Так что не спешите ругать Борландовские Си, они еще всем покажут Кузькину Мать Улыбаюсь)

Ну всё...концерт окончен, за сим откланяюсь. Искренне ваш, Огурец(с)
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines