sending a struct over UDP UNIX sockets in C - c

I'm working on a client/server ftp program for a class using UNIX sockets in C. I have to send my data to this process my professor is having us use to simulate network traffic (called "troll"). It requires a special header. So I was going to try to make a struct with the header and then tack my data on to it... but my compiler keeps giving me this error...
"cannot convert to a pointer type" (referring to the last line of code)
I can not figure out what I am doing wrong...
/* make troll header */
struct sockaddr_in dest, troll;
struct {
struct sockaddr_in header;
char body[MAXDATASIZE];
} message;
message.header.sin_family = htons(AF_INET);
message.header.sin_port = htons(SERVER_PORT);
bcopy((char *)&server_name.sin_addr, (char *)&message.header.sin_addr, sizeof(server_name.sin_addr));
troll.sin_family = AF_INET;
troll.sin_port = htons(TROLL_PORT);
bcopy((char *)&name.sin_addr, (char *)&troll.sin_addr, sizeof(name.sin_addr));
/* send mini_buffer to troll */
memcpy(message.body, mini_buffer, MAXDATASIZE);
int result = sendto(troll_sock, (char *) &message, sizeof(message), 0, (struct sockaddr *) troll, sizeof(troll));

You need to pass the address of troll - not the the object itself. Try: ...(struct sockaddr *)(&troll)...

Related

SocketCAN: No telegrams received

I want to receive messages periodically using socketCAN. But the program didnt receive any telegrams.
I think one problem may be the telegram ID inside the BCM.
Can somebody help me with a hint?
Thank you
Edit:
The goal is to send and to receive can frames on the embedded hw device. I am able to send can frames from the hw to the connected pc. Thats still working fine. But actual I am not able to receive any can frames, which where send from the pc. The bitrate is actual 125000. I think one problem is, that I have to subscribe the can-id of the received telegrams to the broad cast manager. But I cant find an example in the documentation. If I run the code with strace on the hw, I can see the code stucks at the recvfrom() method.
/* Create the socket */
int skt = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);
/* Locate the interface can0 */
struct ifreq ifr;
strcpy(ifr.ifr_name, "can0");
/* Set that interface in the address structure */
struct sockaddr_can addr;
socklen_t addrlen = sizeof(addr);
addr.can_family = PF_CAN;
addr.can_ifindex = 0;
/* Connect the socket to that interface */
ret = connect(skt, (struct sockaddr *) &addr, sizeof(addr));
/* Create a struct to set up a sequence of one CAN frame */
struct {
struct bcm_msg_head msg_head;
struct can_frame frame[1];
} msg;
msg.msg_head.opcode = RX_SETUP;
msg.msg_head.flags = RX_FILTER_ID | SETTIMER;
msg.frame[0].can_id = 0x123;
nbytes = recvfrom(skt, &msg.frame, sizeof(struct can_frame), 0, (struct sockaddr*) &addr, &addrlen);

why the sendto function needs the third parameter, in socket programming

I was new to socket program.
When learning the sendto function, as the prototype:
ssize_t sendto(int socket, const void *message, size_t length,
int flags, const struct sockaddr *dest_addr,
socklen_t dest_len);
I get to know that the "message" has contain the target IP, and the dest_addr argument also specifies the target IP address.
Is there other usage of the dest_addr argument?
I think you are confusing "message" and "dest_addr".
Let's look at the prototype for sendto in expanded form:
ssize_t sendto (int sockfd,
const void *buf,
size_t length,
int flags,
const struct sockaddr *dest_addr,
socklen_t addrlen);
sockfd - this is the socket you created with a call to socket()
buf - this is a pointer to an ARRAY OF BYTES (i.e. they could have made buf of type char* ). That is, this is the data that you want to send across the wire encapsulated in a UDP packet.
length - this is how many bytes are in that array. If you didn't pass "length", it wouldn't know if "buf" was 1 byte or 10000 bytes.
flags - Typically 0. This is advanced stuff
dest_addr - this is a pointer to the destination address. Typically you initialize a sockaddr_in instance and cast its pointer value to a sockaddr* type.
addrlen - the size of the dest_addr. typically, sizeof(sockaddr_in). Address length is variable because dest_addr could pointer to an IPV4 address (sockaddr_in type) or an IPV6 address (sockaddr_in6 type), or some other type.
Example of sending a packet from local port 9999 to remote host "1.2.3.4" on its port 8888. Error checking of return codes left out for brevity.
int s;
sockaddr_in addrDest;
sockaddr_in addrLocal;
char* msg = "Hello World";
// create the socket
s = socket(AF_INET, SOCK_DGRAM, 0); // UDP socket
addrLocal.sin_family = AF_INET;
addrLocal.sin_port = htons(9999);
addrLocal.sin_addr = INADDR_ANY; // zero-init sin_addr to tell it to use all available adapters on the local host
// associate this socket with local UDP port 9999
result = bind(s, (struct sockaddr*)&addrLocal, 0);
// send "Hello world" from local port 9999 to the host at 1.2.3.4 on its port 8888
addrDest.sin_family = AF_INET;
addrDest.sin_port = htons(8888);
addrDest.sin_addr.s_addr = inet_addr("1.2.3.4");
// strlen(msg)+1 for terminating null char
result = sendto(s, msg, strlen(msg)+1, 0, (struct sockaddr*)&addrDest, sizeof(addrDest));
No, Message Contains what you will send, here is an example:
int spatula_count = 3490;
char *secret_message = "The Cheese is in The Toaster";
int stream_socket, dgram_socket;
struct sockaddr_in dest;
int temp;
// first with TCP stream sockets:
// assume sockets are made and connected
//stream_socket = socket(...
//connect(stream_socket, ...
// convert to network byte order
temp = htonl(spatula_count);
// send data normally:
send(stream_socket, &temp, sizeof temp, 0);
// send secret message out of band:
send(stream_socket, secret_message, strlen(secret_message)+1, MSG_OOB);
// now with UDP datagram sockets:
//getaddrinfo(...
//dest = ... // assume "dest" holds the address of the destination
//dgram_socket = socket(...
// send secret message normally:
sendto(dgram_socket, secret_message, strlen(secret_message)+1, 0,
(struct sockaddr*)&dest, sizeof dest);
The message does not contain the destination address, only the payload bytes.
Unless you are using raw sockets... And you should not do that if you are new to socket programming.

How can I get the connected client's IP address using WinSock2 and C?

I want to get the IP address of the client who’s just connected into my server running WinSock2. I’m using C.
You could get the client's IP-address and port via the call to accept().
Just pass in the appropriate data into the last two parameters.
struct sockaddr_in sa = {0}; /* for TCP/IP */
socklen_t socklen = sizeof sa;
... = accept(..., (struct sockaddr *) &sa, &socklen);
For details please read here.
Have not done it myself, but take a look at getpeername. Looks like this is what you need.
This work for me on winsock2. No need of getpeername
SOCKET newConnection;
SOCKADDR_IN addr;
int addrlen = sizeof(addr);
newConnection = accept(sListen, (SOCKADDR*)&addr, &addrlen);
char *ip = inet_ntoa(addr.sin_addr);
printf("Accepted Connection from : %s", ip);

how to connect to a bit torrent tracker in c

I am tying to connect to a bit torrent tracker, http://tracker.thepiratebay.org. The gethostbyname() keeps returning null, how should I fix this? Also do you see anything else wrong with this code?
int sock;
struct sockaddr_in servAddr;
int portNum = 80;
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
printf("fail create socket");
return 0;
}
char *path = "http://tracker.thepiratebay.org/";
struct hostent *hp = gethostbyname(path);
if(hp==NULL){
printf("null");
else{
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
memcpy( (char *) &servAddr.sin_addr.s_addr, (char *) hp->h_addr, hp->h_length );
servAddr.sin_port = htons(portNum);
}
//send request to tracker server
if (send(sock, requestToSend, strlen(requestToSend), 0) != strlen(requestToSend)){
printf("fail send");
return 0;
}
The problem here is that http://tracker.thepiratebay.org/ is a URL, but gethostbyname() expects just the host name. The host name is tracker.thepiratebay.org.
It would make it much easier if you just use libcurl, which will handle all of that HTTP stuff for you. It is extremely common to use libcurl in applications that connect to HTTP servers; it is an excellent library. It's certainly easier than socket programming.
Use getaddrinfo()
The modern alternative to gethostbyname() is getaddrinfo(). It's not that gethostbyname() doesn't do what you want, rather, getaddrinfo() is simply better in every conceivable way.
struct addrinfo hint, *ap;
memset(&hint, 0, sizeof(hint));
hint.ai_family = AF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
int r = getaddrinfo("tracker.thepiratebay.org", "http", &hint, &ap);
This will not only get you the address for the host you want, but it will also fill in the port number. You can use "http" as the port, or you can use "80" for the port, they are the same thing (as long as /etc/services has the right entry).
Other problems
This line is wrong.
memcpy( (char *) &servAddr.sin_addr.s_addr, (char *) hp->h_addr, hp->h_length );
You don't know that gethostbyname() returned an IPv4 address, and it is foolish to try and copy it into a struct sockaddr_in. If gethostbyname() returned an IPv6 address, you have just smashed your stack and your program will crash -- or worse, it might not crash.
Either check that it returns an IPv4 address, or simply copy hp->h_addr into a generic struct sockaddr that was returned from malloc(hp->h_length). This is a bit ugly but it's the way it goes.
Finally, it is wrong to cast the arguments to memcpy(). It's not an error, but it's wrong. Don't do it, it can cause otherwise legitimate compiler errors to be suppressed, e.g., if you accidentally cast an int to char *.

Passing structures using UDP

I have been trying to send and receive structures on the same machine using UDP and the server and client in this case run on the same machine and share common structure definitions (using a header file).
Hostent structure defn(UNIX built-in type) :
struct hostent{
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
}
Server Code snippet follows :
struct hostent* resolved_host = DNS_translate(DNSname);
if((numbytes = sendto(sockfd, (void*)&resolved_host, sizeof(struct hostent), 0, (struct sockaddr *)&client_addr, sizeof(struct sockaddr))) == -1)
{
perror("sendto failed");
exit(EXIT_FAILURE);
}
Client Code snippet follows:
struct hostent resolved_host;
int addr_len = sizeof(struct sockaddr);
if((numbytes = recvfrom(sockfd, (void*)&resolved_host, sizeof(struct hostent), 0, (struct sockaddr *)&server_addr, &addr_len)) == -1)
{
perror("recvfrom failed");
exit(EXIT_FAILURE);
}
The server sends and the client receives as normal (no error raised).
The *resolved_host* structure is filled in the server and all its data can be accessed with no problem.
However, if I now try to use the *resolved_host* structure in the client, I get a seg fault. For example:
printf("Name : %s\n", resolved_host.h_name);
raises a seg fault. (but works in the server)
Your struct is full of pointers. When you send it over the network, you send the actual addresses, not the data pointed to by those pointers.
Those addresses are invalid in the target process.
You will need to serialize the data yourself. See for examples:
Serialization/Deserialization of a struct to a char* in C
Serialization techniques
The structure contains pointers - so when you copy the structure over UDP you're only copying the values of those pointers (i.e. the addresses of some other pieces of data) and not the actual data itself.
When you receive those pointers in the server they no longer mean anything - those pointer addresses are meaningless to the other program.
You are sending pointers. Even on the same machine these are not valid in different address spaces.

Resources