// JP opened flex table

Click to See Complete Forum and Search --> : connecting to a modem using winsock


bishnu12
February 1st, 2007, 11:50 PM
Hi all,

I am a new member of this forum. But i have been visiting it for a long time now.

There are two questions

1. I am trying to write a programme which can query to a modem get the modem details. i am using normal send() and recv() functions. But when i try to fetch a file from the modem. It shows me...

Error:400 Bad request.

2. The modem requires a username and password to get inside it. How can i set the username and password into it?

Here goes my code..

I hope my approach is correct. May be the way i am doing it is wrong.

#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include<conio.h>

#define DEFAULT_PORT 80

#define DEFAULT_PROTOCOL SOCK_STREAM // TCP
#define PRINTERROR(s) \
fprintf(stderr,"\n%: %d\n", s, WSAGetLastError())

void GetHTTP(LPCSTR lpServerName);
void parse(FILE *fp);

int main(void)
{
WSADATA wsaData;
SOCKET conn_socket;
struct sockaddr_in server;
struct hostent *hp;
char *server_name = "192.168.1.1";// modem IP address
unsigned short port = DEFAULT_PORT;
unsigned int addr = 0;
int socket_type = DEFAULT_PROTOCOL;
int retval = 0;
int loopflag = 0;
int loopcount = 0;
int maxloop = -1;
int i = 0;
char szBuffer[1024];
int nRet;


FILE *fp = fopen("read.txt","w");

if( WSAStartup(0x202,&wsaData) == SOCKET_ERROR )
{
fprintf(stderr,"WSAStartup failed with error %d\n",WSAGetLastError());
WSACleanup();
return -1;
}


if( isalpha(server_name[0]) )
{
hp = gethostbyname(server_name);
}
else
{
addr = inet_addr(server_name);
hp = gethostbyaddr((char *)&addr,4,AF_INET);
}


if( hp == NULL )
{
fprintf(stderr,"Client: Cannot resolve address [%s]: Error %d\n",
server_name,WSAGetLastError());
WSACleanup();
exit(1);
}

memset(&server,0,sizeof(server));
memcpy(&(server.sin_addr),hp->h_addr,hp->h_length);
server.sin_family = hp->h_addrtype;
server.sin_port = htons(port);

conn_socket = socket(AF_INET,socket_type,0); /* Open a socket*/

if( conn_socket < 0 )
{
fprintf(stderr,"Client: Error Opening socket: Error %d\n",
WSAGetLastError());
WSACleanup();
return -1;
}


printf("Client connecting to: %s\n",hp->h_name);

if(connect(conn_socket,(struct sockaddr*)&server,sizeof(server)) == SOCKET_ERROR)
{
fprintf(stderr,"connect() failed: %d\n",WSAGetLastError());
fprintf(stderr,"Server not found...\n\n");
WSACleanup();
return -1;
}

/* Trying to get data from the modem*/

sprintf(szBuffer, "GET %s\n","/cgi-bin/webcm.html\n","\n");

nRet = send(conn_socket, szBuffer, strlen(szBuffer), 0);
if (nRet == SOCKET_ERROR)
{
PRINTERROR("send()");
closesocket(conn_socket);
}

while(1)
{
nRet = recv(conn_socket, szBuffer, sizeof(szBuffer), 0);
if (nRet == SOCKET_ERROR)
{
PRINTERROR("recv()");
break;
}

if (nRet == 0)
break;
fwrite(szBuffer, nRet, 1,fp);

}
closesocket(conn_socket);
parse(fp);
fclose(fp);
return 0;
}


Anybody has any idea how to proceed. Please help. Sorry if there are any spelling mistakes.

Thanks in advance

MikeAThon
February 2nd, 2007, 06:52 PM
1. The "400 Bad Request" is a response from your modem that tells you it has received a badly-formed HTTP request.

This is the code that sets up your request, and the content of the request is not correct:
sprintf(szBuffer, "GET %s\n","/cgi-bin/webcm.html\n","\n");
The request should actually look something like this:
sprintf(szBuffer, "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n","/cgi-bin/webcm.html\n","192.168.1.1");

2. You send the username and password as a base64-encoded string in an additional request header, i.e, under the "Authorization:" header. Altogether, the string sent to the modem should look something like this (note that there's a blank line at the end, corresponding to the two "\r\n"'s in the above code):
GET /cgi-bin/webcm.html HTTP/1.0
Host: 192.168.1.1
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==


The string "QWxhZGRpbjpvcGVuIHNlc2FtZQ==" is base64 encoding of "Aladdin:open sesame" and naturally you should replace it with the base64 encoding of your actual username and password.

In general, you need to read the HTTP specification, and understand what needs to be sent. Start with HTTP/1.0 since it's easier to understand and code than HTTP/1.1. The rfc is rfc 1945 and can be viewed in many places such as ftp://ftp.rfc-editor.org/in-notes/rfc1945.txt

One recommendation for learning this is to spy on valid HTTP conversations that are taking place between your browser and the modem. To do so, install a local HTTP debugging proxy on your machine, and connect from the browser to your modem through the proxy. One excellent debugging proxy is Fiddler, free from Microsoft, at www.fiddlertool.com

Mike

bishnu12
February 4th, 2007, 10:47 PM
Thanks mike...I will try to implement your suggestions and surely let you know what is the output...

bishnu12

bishnu12
February 6th, 2007, 12:58 AM
Hi Mike,

Thank you very much.I implemented your suggestions. I got the desired output also. But i've got a small problem now.

The code runs differently for different modems. For one modem "192.168.1.1" is resolved using gethostbyaddr() while for another modem this is resovled using gethostbyname().

Is there any standard format for this or any alternative for these two functions. Meant to say. Is there any other alternate single function.

Thanks

bishnu12
February 6th, 2007, 04:01 AM
Also i forgot to mention one more thing.

Most of the webpages i am getting are having links which are having java scripts and functions inside.

Can i click on a button or go to a link by accessing those functions of course through the GET request.

If anybody has any idea, please share this with me.

Thanks in advance.

MikeAThon
February 6th, 2007, 10:48 AM
For your gethostbyaddr() question, call inet_addr() first to check for a plain old ASCII dotted IP address, and if that fails, then call gethostbyname() to try to resolve the address. This should avoid use of gethostbyaddr(), and should work in all situations.

For the java question, if there are scripts and functions inside the page retrieved by GET, then you will need code to execute those scripts/functions. Either write the code yourself, or find a good library. I don't know of a good library, although it might be possible (if this is a Windows app) to use a hidden IWebBrowser2 COM object.

Mike

bishnu12
February 12th, 2007, 08:19 AM
Hi Mike,

Just wanted to check with you, if the header i am sending is correct or not. The header I sent to the modem is not working properly. I think I tested it on a modem which doesn't require username and password.

Because when i tested it on another modem it doesn't go to the desired page rather it remains ther on the LogIn page only.


sprintf(cBuffer, "GET %s HTTP/1.0\r\nHost: %s\r\nAuthorization: Basic %s\r\n\r\n","/cgi-bin/webcm",Server_name,"YWRtaW46YWRtaW4=");


Sorry to bother you again. But I require help badly in this regard.

utpal1005
May 21st, 2008, 08:09 AM
i have a doubt regarding detecting MODEMS.

I am writing a program which will dial a dial-up connection and use it. Now my problem is if the modem is not present (not physically connected) in the system then also it is dialing. I dont want this scenario. Ideally I want an API which will check whether a particular MODEM is physically connected to the system or not.

//JP added flex table