Solved

c++ connect() permission denied, why?

Posted on 2009-05-06
17
884 Views
Last Modified: 2012-08-14
Hi all,

I have a c++ client that communicates with a service on a small network. I am trying to let the user find the IP address of the service by sending a message to a broadcast IP address, to which my service will respond, etc. I don't think I am doing this correctly, however...

The IP of the service is 192.168.1.102
The subnet mask is 255.255.255.0

As far as I could tell, the corresponding broadcast would be 192.168.1.255, is that right? Well, when I try to connect() to that IP address, it always comes back with errno 13 Permission denied. Does anyone have any idea why this is happening or better yet how I can properly send out one single message to every IP my service could possibly be on?

Thank you!
0
Comment
Question by:ehensens
  • 10
  • 6
17 Comments
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24318817
.255 would be the broadcast address, but it is not a single IP/interface so you can't "connect" to it.

To broadcast you don't need to connect, you just need to open a socket from an interface and send to the broadcast address.
0
 

Author Comment

by:ehensens
ID: 24318861
Hi mrjoltcola,

Thank you for your response. I'm afraid I don't quite understand what you mean that I don't need to connect to it. How do I send to the broadcast address without connecting?

Thanks again!
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24318932
For example, with sendto() and UDP, you won't use connect(), you just use sendto().

Using the Berkeley socket call, sendto() allows you to pass the sockaddr structure in as the 5th argument, along with the address len. That is what differentiates sendto() from send() which operates on a connected socket.

You can use connect() on UDP sockets, but only if it is a valid IP address, which .255 and .0 are not. And connect() is only needed if you wish to then use send() without passing the 5th and 6th arguments as with sendto(). It might speed up things a bit, and make your socket code less cluttered, and I use it when I can in UDP programming.

Note the difference:

  ssize_t send(int s, const void *buf, size_t len, int flags);
  ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);

In your case, just pass the address, something like this, where toaddr is a "struct sockaddr" that contains the .255 network broadcast address.

sendto(fd, &datastruct, sizeof(datastruct), flags, &toaddr, sizeof(sockaddr));
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24318962
You also need to use setsockopt(fd, SOL_SOCKET, SO_BROADCAST, ... ) or you may also get permission denied. This is from W. Richard Stevens book, _UNIX Network Programming_ which is probably the best single book you can own if you write networking software.

Even if using Windows, the old Berkeley sockets API still applies, mostly, so the book is very relevant and has a complete chapter on Broadcasting.

http://www.amazon.com/UNIX-Network-Programming-Networking-Sockets/dp/013490012X
0
 

Author Comment

by:ehensens
ID: 24318992
So do I call setsockopt() , sendto() , write() , read() in that order?
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24319133
That is the order, but sendto is in place of write, and recvfrom/recv is in place of read. No need for both. write cannot write to broadcast addresses, that I know of, as it just uses a descriptor, and since you cannot obtain a "connected descriptor" to a broadcast adderss, you cannot use write.

0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24319152
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24319171
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 

Author Comment

by:ehensens
ID: 24319354
Those are both great links but I don't see how the sender receives the response? Before I was just connect(), write(), and then read()

since i'm not doing connect() or write() now, just sendto(), how do I do the equivalent of "read()"?
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24319395
The sender would receive the response by calling recv on the socket. You can bind to that socket, and read from it. The 2nd link I provided does discuss that in the last message.
0
 

Author Comment

by:ehensens
ID: 24319405
Sorry, I guess I overlooked it. Let me give it a whirl!
0
 

Author Comment

by:ehensens
ID: 24319506
It just sits on recv() seemingly forever, I don't see what I'm doing wrong, do you?

    struct hostent *hostentPointer;

    

    hostentPointer = gethostbyname(broadcastHost);

   

    struct sockaddr_in serverAddress;

    

    char **pPointer;

    char networkAddress[A_NUMBER];

    

    int broadcast = 1;

       

    hostentPointer = gethostbyname(broadcastHost);

       

    pPointer = hostentPointer -> h_addr_list;

    

    inet_ntop(hostentPointer->h_addrtype, *pPointer, networkAddress, sizeof(networkAddress));

    

    int sockFD = socket(PF_INET, SOCK_DGRAM, 0);

    

    setsockopt(sockFD, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));

    

    bind(sockFD, (struct sockaddr*) &serverAddress, sizeof(serverAddress));

   

    bzero(&serverAddress, sizeof(serverAddress));

    serverAddress.sin_family = PF_INET;

    serverAddress.sin_port = htons(8004);

    inet_pton(AF_INET, networkAddress, &serverAddress.sin_addr);
 

    char sendRequest[SENDSIZE];
 

    char payload[SOME_NUMBER] = "";

        

    strcat(payload, "broadcastFunction");

    

    snprintf(sendRequest, BUFFSIZE,

            

             /* Actual HTTP POST text */

             "POST %s HTTP/1.0\r\n"

             "Host: %s\r\n"

             "Content-type: text/plain\r\n"

             "Content-length: %d\r\n\r\n"

             "%s", "Directory", broadcastHost, strlen(payload), payload);

    
 
 

    sendto(sockFD, sendRequest, strlen(sendRequest), 0, (struct sockaddr *) &serverAddress, sizeof(serverAddress));
 
 

    unsigned int msgLength = 10000;

   

    recv(sockFD, broadcastResponse, msgLength, 0);

    

    

    printf("\n\nBroadcast response:\n\n%s\n", broadcastResponse);

Open in new window

0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24320936
Curious why you are broadcasting an HTTP POST.

Anyway, is your receiver showing anything, and is it responding?
0
 
LVL 4

Accepted Solution

by:
lhl60 earned 250 total points
ID: 24323232
well I wouldn't use HTTP in the discovery

HTTP is meant for connection oriented stuff
I will suggest something like this:

Let your server listen for UDP packets on a "discover port"
and let it listen for TCP connects requests on a "production" port

on the client side
build a discovery routine

Send a UDP packet to the subnet (broadcast) on the "discover" port, the content can be something identifying the client (version,secret code....)

The server picks it up, and respond (UPD)  with  some previously agreed message content that allow your client to identify it as a valid server ( maybe even information about the production port, or some other useful information)

If a satisfactory answer to the broadcast arrives, within a reasonable timer limit. the client then  know the IP address of the server. and the client can initiate a normal  production connection (TCP).


0
 

Author Comment

by:ehensens
ID: 24325106
Sorry if my code is a little perplexing, I am brand new to networking. I've been POSTing information from my app to my service under normal running conditions, so I thought that for any kind of automatic "Find Service IP Address" feature I'd just do the same thing, only use a broadcast IP address instead of the service's specific IP. Then I found out that you can't connect() to a broadcast IP... I guess I'll just have to try to sludge through this...

I've gotten to the point where I can finally recv() from that socket now after I sendto() but it's just reading exactly what I sent, and my service is not responding. It seems I can only get my service to acknowledge communication when I write() to it...
0
 
LVL 40

Assisted Solution

by:mrjoltcola
mrjoltcola earned 250 total points
ID: 24325998
broadcasting is connectionless, yes.

Typically you use it with UDP, then wait for responses, in packet mode, and the response can be from anyone. Stream mode won't work.

The POST you have is an HTTP request, which requires TCP level anyway. A listening TCP socket will never receive a broadcast, its impossible.
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24326001
Oh, sorry I did not see lhl60's response, he already explained.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
PRTG Network Monitor lets you monitor your bandwidth usage, so you know who is using up your bandwidth, and what they're using it for.
Viewers will learn how to connect to a wireless network using the network security key. They will also learn how to access the IP address and DNS server for connections that must be done manually. After setting up a router, find the network security…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now