• Welcome to Valhalla Legends Archive.
 

C++ Basic Connection

Started by Trunning, March 27, 2010, 03:25 AM

Previous topic - Next topic

Trunning

@Brew
Removed the break, that was there from earlier experimentation, the if statement was in a while loop. And I'm still not receving anything with your code.

brew

Quote from: Trunning on March 28, 2010, 11:02 PM
@Brew
Removed the break, that was there from earlier experimentation, the if statement was in a while loop. And I'm still not receving anything with your code.

Ooops, my mistake!
Remove the -4 from the third parameter of the second send(). That should do it.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

Trunning

Done that, still nothing.

#pragma comment(lib, "Ws2_32.lib")
#include <windows.h>
#include <winsock.h>
#include <string>
#include <iostream>
using namespace std;

int main(){
struct SID_AUTH_INFO {
BYTE   Header;
BYTE   MsgID;
WORD   wLen;
DWORD   ProtocolID;
DWORD   PlatformID;
DWORD   ProductID;
DWORD   VerByte;
DWORD   ProductLang;
DWORD   LocalIP;
DWORD   TimeZone;
DWORD   LocaleID;
DWORD   LangID;
char   CountryAbr[4];
char   Country[10];
} Packet;
   
Packet.Header      = 0xFF;
Packet.MsgID      = 0x50;
Packet.ProtocolID   = 0x0;
Packet.PlatformID   = 'IX86';
Packet.ProductID   = 'D2DV';
Packet.VerByte      = 0x0D;
Packet.ProductLang   = 0;
Packet.LocalIP      = inet_addr("192.168.1.100");
Packet.TimeZone      = 600;
Packet.LocaleID      = 0;
Packet.LangID      = (DWORD)GetUserDefaultLangID();
Packet.wLen         = sizeof(SID_AUTH_INFO) - 4;
strcpy(Packet.CountryAbr, "Aus");
strcpy(Packet.Country, "Australia");
/*int size = sizeof((Packet.MsgID) & (Packet.ProtocolID) & (Packet.PlatformID) & (Packet.ProductID) & (Packet.VerByte) & (Packet.ProductLang) & (Packet.LocalIP) & (Packet.TimeZone) & (Packet.LocaleID) & (Packet.LangID) );
DWORD Pre = 0x01;*/

BYTE PingPacket[8];

int con;
WSADATA wsaData;

WSAStartup(MAKEWORD(2,0), &wsaData);

LPHOSTENT host;

host = gethostbyname("useast.battle.net");

if (!host)
{
  MessageBox(NULL, "Host error", "", MB_OK);
  WSACleanup();
  return 0;
}

SOCKET theSocket;

theSocket = socket(AF_INET,
  SOCK_STREAM,
  IPPROTO_TCP);

if (theSocket == INVALID_SOCKET)
{
  MessageBox(NULL, "theSocket bad...", "", MB_OK);
  WSACleanup();
  return 0;
}

SOCKADDR_IN info;

info.sin_family = AF_INET;
info.sin_addr = *((LPIN_ADDR)*host->h_addr_list);
info.sin_port = htons(6112);

con = connect(theSocket, (LPSOCKADDR)&info, sizeof(info));

if (con == SOCKET_ERROR)
{
  MessageBox(NULL, (LPCSTR)WSAGetLastError(), "", MB_OK);
  WSACleanup();
  return 0;
}

cout << "Sending 0x01...\n";
con = send(theSocket, "\x01", 1, NULL); //look at this, you're sending _1_ byte. nothing more.
if (con > 0){
cout << con << " bytes sent\n";
} else {
cout << "Nothing sent!\n";
}

cout << "Sending 0x50...\n";
con = send(theSocket, (const char*)&Packet, sizeof(SID_AUTH_INFO), NULL);
if ( con > 0 ){
   cout << con << " bytes sent\n";
} else {
   cout << "Nothing sent!\n";
}

con = recv(theSocket, (char*)&PingPacket, sizeof(PingPacket), NULL);
if (con > 0){
cout << "Ping cookie: " << *(unsigned __int32 *)(PingPacket + 4);
}

// for testing purposes
char n;
cin >> n;
closesocket(theSocket);
return 0;
}

rabbit

Check your packet log.  Are you sure the typecast of your packet struct is working properly?
Grif: Yeah, and the people in the red states are mad because the people in the blue states are mean to them and want them to pay money for roads and schools instead of cool things like NASCAR and shotguns.  Also, there's something about ketchup in there.

Hdx

#19
btw, I was waiting for brew to correct himself, but the Length in the packet Header INCLUDES the fucking header!
Anyways, as a side note, you are not guaranteed to get SID_PING before you get SID_AUTH_INFO back (you usually do but still)

Clean your code, test each section, use wireshark to see whats actually being sent. And it should be easy to get it working. Did you just gloss over my post because it wasn't copy/paste code?
And your table breakage is annoying!

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Trunning

I looked at your code, but I really wanted to fix mine.

brew

#21
Quote from: Hdx on March 29, 2010, 03:22 AM
btw, I was waiting for brew to correct himself, but the Length in the packet Header INCLUDES the fucking header!

Yes. Wow... I screwed up twice in the same post. I've forgotten a bunch about the BNCS protocol over the years. It makes me feel pretty bad that I'm giving this guy bad advice, thanks for pointing that out though, Hdx.

Oh well, who cares? Bnet2 is where it's at! :P
This guy is just probably trying to make a D2-run "clientless" bot in order to sell items, like the thousands of others....
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

Trunning

Are you serious? My final goal was just logging into the chat room.

Hdx

Just read my code. Understand what i'm saying, and you would have working code days ago. As for wanting to get 'your code working' most of what I posted was your code, just reorganized.
Well, you could write a connection in a single function, but it would just be a huge headache and be annoying.

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Trunning

Ok I ran through your code best I could, and came up with this. And strcpy doesn't return the bytes copied, it returns the destination string, according to MSDN. Anyway, with the following code, I'm still not receiving anything.

#pragma comment(lib, "Ws2_32.lib")
#include <stdio.h>
#include <winsock.h>
#include <windows.h>

int socket_connect(SOCKET sockBNCS, const char *Server, WORD Port);
int send_SID_AUTH_INFO(SOCKET sockBNCS);

struct BNCS_HEADER {
BYTE Sanity;
BYTE ID;
WORD Length;
};

struct SID_AUTH_INFO {
BNCS_HEADER Header;
DWORD   ProtocolID;
DWORD   PlatformID;
DWORD   ProductID;
DWORD   VerByte;
DWORD   ProductLang;
DWORD   LocalIP;
DWORD   TimeZone;
DWORD   LocaleID;
DWORD   LangID;
char   CountryInfo[0x100];
};

int main(){
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 0), &wsaData);

SOCKET sockBNCS = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockBNCS == INVALID_SOCKET){
MessageBox(NULL, "Error -> Invalid Socket!", "", MB_OK);
closesocket(sockBNCS);
WSACleanup();
return 0;
}

int sent;
if (socket_connect(sockBNCS, "useast.battle.net", 6112) == 0){

printf("Sending Protocol Byte 0x01\n");
sent = send(sockBNCS, (const char*)'\x01', 1, NULL);
if (sent > 0){
printf("Sent %d bytes\n", sent);
} else if (sent == 0) {
printf("Failed to send protocol byte!");
}
}

send_SID_AUTH_INFO(sockBNCS);

BNCS_HEADER header; // hold incoming data
void *data = malloc(0x200);
int data_max = 0x200;

while(true){
sent = recv(sockBNCS, (char*)&header, sizeof(header), NULL);
if (sent != sizeof(header)){
printf("Didn't receive full header!\n");
}
}

if (header.Length - 4 > data_max){
free(data);
data = malloc(header.Length - 4);
}

sent = recv(sockBNCS, (char*)&data, header.Length -4, NULL);
if (sent != header.Length - 4){
printf("Could not read packet data!");
}

switch (header.ID){
case 0x25:
printf("We got 0x25!\n");
case 0x50:
printf("We got 0x50!\n");
}

WSACleanup();
closesocket(sockBNCS);
system("pause");
return 0;
}

int socket_connect(SOCKET sockBNCS, const char *Server, WORD Port){
LPHOSTENT host = gethostbyname(Server);

if (!host){
MessageBox(NULL, "Error -> Host", "", MB_OK);
return -1;
}

SOCKADDR_IN info;
info.sin_family = AF_INET;
info.sin_addr = *((LPIN_ADDR)*host->h_addr_list);
info.sin_port = htons(Port);

if (connect(sockBNCS, (LPSOCKADDR)&info, sizeof(info)) == SOCKET_ERROR){
MessageBox(NULL, (LPCSTR)WSAGetLastError(), "", MB_OK);
return -1;
}
return 0;
}

int send_SID_AUTH_INFO(SOCKET sockBNCS){
  SID_AUTH_INFO pkt;
  int AbbrLen, NameLen, sent;
  memset(&pkt, 0, sizeof(SID_AUTH_INFO)); //If you don't do this, the pkt could have random info.
 
  pkt.ProtocolID  = 0x00;
  pkt.PlatformID  = 'IX86';
  pkt.ProductID   = 'D2DV';
  pkt.VerByte     = 0x0D;
  pkt.ProductLang = 0x00;
  pkt.LocalIP     = inet_addr("192.168.1.100");
  pkt.TimeZone    = 600;
  pkt.LocaleID    = 0x00;
  pkt.LangID      = (DWORD)GetUserDefaultLangID();
  strcpy(&pkt.CountryInfo[0], "AUS"); //I *think* strcpy() returns the number of bytes copied, can't remember
  AbbrLen = sizeof(pkt.CountryInfo[0]);
  strcpy(&pkt.CountryInfo[AbbrLen + 1], "Australia");
  NameLen = sizeof(pkt.CountryInfo[AbbrLen + 1]);
 
  pkt.Header.Sanity = 0xFF;
  pkt.Header.ID     = 0x50;
  pkt.Header.Length =  4       //Header Length
                     + (4 * 9) //Number of DWORDs in the packet
                     + AbbrLen //Abbreviation Length
                     + 1       //Null Terminator
                     + NameLen //Country Name Length
                     + 1;      //Null Terminator
  printf("Sending %d bytes for 0x50 SID_AUTH_INFO\n", pkt.Header.Length);
  sent = send(sockBNCS, (const char*)&pkt, pkt.Header.Length, NULL);
  if(sent > 0){
    printf("Sent %d bytes\n", sent);
  }else{
    printf("Sending failed!\n");
  }
  return 0;
}

l)ragon

Just a thought, have you set any break points to see if its even getting to the packet send?
yeah ive neglected to read the entire thread sue me, if you are connected you will still recieve SID_NULL, side note if you havent sent nothing you also wont recieve nothing besides SID_NULL unless ofcorse you are ipbanned.
*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*ˆ¨¯¯¨ˆ*^~·.,l)ragon,.-·~^*ˆ¨¯¯¨ˆ*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*

Hdx

#26
you fucked up the while(true) loop, it should include everything up to the WSACleanup() at the end.
Also, everything except for the stuff after WSACleanup at th end should be inside the if(socket_connect) condition. Howed you mess up the structure of the code i posted so much?
Think of it logically, why would you want to send shit if you arnt connected?

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Trunning

#27
Ah, it also looks like 01 isn't being sent, on the left is the code below, and the right is actual diablo 2 client.


I put the crap into the while loop, up until the WSACleanup. And put the while loop in the if(socket_connet), and still no go. Maybe you can clean it up.

#pragma comment(lib, "Ws2_32.lib")
#include <stdio.h>
#include <winsock.h>
#include <windows.h>

int socket_connect(SOCKET sockBNCS, const char *Server, WORD Port);
int send_SID_AUTH_INFO(SOCKET sockBNCS);

struct BNCS_HEADER {
BYTE Sanity;
BYTE ID;
WORD Length;
};

struct SID_AUTH_INFO {
BNCS_HEADER Header;
DWORD   ProtocolID;
DWORD   PlatformID;
DWORD   ProductID;
DWORD   VerByte;
DWORD   ProductLang;
DWORD   LocalIP;
DWORD   TimeZone;
DWORD   LocaleID;
DWORD   LangID;
char   CountryInfo[0x100];
};

int main(){
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 0), &wsaData);

SOCKET sockBNCS = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockBNCS == INVALID_SOCKET){
MessageBox(NULL, "Error -> Invalid Socket!", "", MB_OK);
closesocket(sockBNCS);
WSACleanup();
return 0;
}

int sent;
if (socket_connect(sockBNCS, "useast.battle.net", 6112) == 0){

printf("Sending Protocol Byte 0x01\n");
sent = send(sockBNCS, (const char*)'\x01', 1, NULL);
if (sent > 0){
printf("Sent %d bytes\n", sent);
} else if (sent == 0) {
printf("Failed to send protocol byte!");
}
send_SID_AUTH_INFO(sockBNCS);

BNCS_HEADER header; // hold incoming data
void *data = malloc(0x200);
int data_max = 0x200;

while(true){
sent = recv(sockBNCS, (char*)&header, sizeof(header), NULL);
if (sent != sizeof(header)){
printf("We didn't get the full header!\n");
}
if (header.Length - 4 > data_max){
free(data);
data = malloc(header.Length - 4);
}

sent = recv(sockBNCS, (char*)&data, header.Length -4, NULL);
if (sent != header.Length - 4){
printf("Could not read packet data!\n");
}

switch (header.ID){
case 0x25:
printf("We got 0x25!\n");
break;
case 0x50:
printf("We got 0x50!\n");
break;
}
}
}

WSACleanup();
closesocket(sockBNCS);
system("pause");
return 0;
}

int socket_connect(SOCKET sockBNCS, const char *Server, WORD Port){
LPHOSTENT host = gethostbyname(Server);

if (!host){
MessageBox(NULL, "Error -> Host", "", MB_OK);
return -1;
}

SOCKADDR_IN info;
info.sin_family = AF_INET;
info.sin_addr = *((LPIN_ADDR)*host->h_addr_list);
info.sin_port = htons(Port);

if (connect(sockBNCS, (LPSOCKADDR)&info, sizeof(info)) == SOCKET_ERROR){
MessageBox(NULL, (LPCSTR)WSAGetLastError(), "", MB_OK);
return -1;
}
return 0;
}

int send_SID_AUTH_INFO(SOCKET sockBNCS){
 SID_AUTH_INFO pkt;
 int AbbrLen, NameLen, sent;
 memset(&pkt, 0, sizeof(SID_AUTH_INFO)); //If you don't do this, the pkt could have random info.
 
 pkt.ProtocolID  = 0x00;
 pkt.PlatformID  = 'IX86';
 pkt.ProductID   = 'D2DV';
 pkt.VerByte     = 0x0D;
 pkt.ProductLang = 0x00;
 pkt.LocalIP     = inet_addr("192.168.1.100");
 pkt.TimeZone    = 600;
 pkt.LocaleID    = 0x00;
 pkt.LangID      = (DWORD)GetUserDefaultLangID();
 strcpy(&pkt.CountryInfo[0], "AUS"); //I *think* strcpy() returns the number of bytes copied, can't remember
 AbbrLen = sizeof(pkt.CountryInfo[0]);
 strcpy(&pkt.CountryInfo[AbbrLen + 1], "Australia");
 NameLen = sizeof(pkt.CountryInfo[AbbrLen + 1]);
 
 pkt.Header.Sanity = 0xFF;
 pkt.Header.ID     = 0x50;
 pkt.Header.Length =  4       //Header Length
                    + (4 * 9) //Number of DWORDs in the packet
                    + AbbrLen //Abbreviation Length
                    + 1       //Null Terminator
                    + NameLen //Country Name Length
                    + 1;      //Null Terminator
 printf("Sending %d bytes for 0x50 SID_AUTH_INFO\n", pkt.Header.Length);
 sent = send(sockBNCS, (const char*)&pkt, pkt.Header.Length, NULL);
 if(sent > 0){
   printf("Sent %d bytes\n", sent);
 }else{
   printf("Sending failed!\n");
 }
 return 0;
}

rabbit

You should probably try to send 0x01 a few times and then abort the entire condition if you can't send it for some reason, since you can't do anything without it.
Grif: Yeah, and the people in the red states are mad because the people in the blue states are mean to them and want them to pay money for roads and schools instead of cool things like NASCAR and shotguns.  Also, there's something about ketchup in there.

Hdx

#29
True, but heres the kicker, what does the console say?
If it failed to send you should see an error, and if it did send ou should see confirmation.
ALSO Don't fucking use sizeof() to get the length of a string.
strlen() is what you want. As you can see in the screen shot, you're not sending the full strings. I bet you're IP banned.
Also, use "\x1" not (const char *)'\x1', it's a faster way, and should solve your issue. (Instead of placing the value it places a pointer to your binaries data segment which is exactly what you want)

But, look at your console, see what it says.

Another question, why are you sending Australia if you are in the US?
Also, FOR THE LOVE OF GOD stop breaking tables!

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

|