SocketCAN: No telegrams received - c

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);

Related

What is the socket address family defined by 30?

I am writing a simple FTP server program in C. I am mostly following Beej's Guide to Network Programming. In order to complete the pasv mode functionality, I have to create another socket and send its ip and port to the client.
Since gethostbyname() is deprecated, I am using getsockname() to get my current network IP address. My plan is that I separate two cases (ipv4 and ipv6) and send info to the client accordingly. But, whenever I try to get the address family it always 30. I am not sure if I am printing this correctly though.
I am doing something simple like this (which might include mistakes), and it prints 30.
struct sockaddr_storage my_addr;
int result;
socklen_t len = sizeof(my_addr);
result = getsockname(current_fd, (struct sockaddr *) &my_addr, &len);
if (my_addr.ss_family == AF_INET) { // ipv4
struct sockaddr_in * ipv4 = (struct sockaddr_in *) &my_addr;
addr = &(ipv4->sin_addr);
} else { // ipv6
struct sockaddr_in6 * ipv6 = (struct sockaddr_in6 *) &my_addr;
addr = &(ipv6->sin6_addr);
}
printf(" family: %u\n", (unsigned short) my_addr.ss_family);
When I searched this online, I got:
#define AF_ATM 30 /* ATM */
What is this exactly? Is this expected? If not, where am I doing something wrong?
Thank you.
Edit:
Apparently what it was printing was something different.
It is not defined as:
#define AF_ATM 30 /* ATM */
but it is defines as:
MT IPv6: Multi-Topology IP version 6 [RFC7307]

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);

Sendto returns -1 and errno 22 (Invalid argument), when set the multicast outgoing interface by ip_mreqn

I faced an issue, when I try to send to multicast group by setting the intended outgoing interface by the code bellow, Actually when the condition is TRUE (if(config.enable_if == 1)) the sendto system call returns error Invalid Argument, but if the condition was False sendto send data and doesn't generate any error.
Please Anyone has an idea, or should I modify anything in my code?
/* Create a datagram socket on which to send. */
sd = socket(AF_INET, SOCK_DGRAM, 0);
/* Set local interface for outbound multicast datagrams. */
/* The IP address specified must be associated with a local */
/* multicast capable interface. */
if(config.enable_if == 1){
mreqn.imr_ifindex = if_nametoindex("eth3");
rc = setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, (void *)&mreqn, sizeof(mreqn));
}
/* Initialize the group sockaddr structure with a */
/* group address of dynamic address and port dynamic port. */
memset((char *) &groupSock, 0, sizeof(groupSock));
groupSock.sin_family = AF_INET;
groupSock.sin_addr.s_addr = inet_addr(config.mip);
groupSock.sin_port = htons(config.port);
/* Send a message to the multicast group specified by the*/
/* groupSock sockaddr structure. */
rc = sendto(sd, (const char *)& databuf, datalen, 0, (const struct sockaddr*)&groupSock, sizeof (struct sockaddr));
printf("errno %d\n",errno);
One reason sendto fails is because you pass it a data pointer it does not expect. If you have char* databuf and you then do &databuf you get the address of the pointer, i.e. a pointer to a pointer, of type char**. If you remove the cast (which is not needed) then you will get at least a warning or maybe even an error when compiling.

How to re bind a udp socket in Linux

I am an experienced Linux socket programmer and am writing a server application which has many outgoing interfaces. Now server socket binds to a random source port in the start of the process along with INADDR_ANY.
Later at some point when submitting response to a specific node, i need to assign a fixed source ip address. The standard way to do this is calling bind. However, bind is called once for the port number, successive calls fail with invalid argument error.
Creating a new socket is not really a good choice since i will have to be doing this very often upon responding to some clients.
I have also explored SO and a lot of socket options such as IP_FREEBIND, but it doesn't quite suite my scenario.
Perhaps using IP_PKT_INFO and setting source address might work unless it suffers the same problem i.e. not allowing a socket once bound to INADDRANY to rebind to a fixed source ip latter.
Is there a way to unbind an existing socket or an alternate way to setting source ip address in outgoing packet?
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock < 0)
printf("Failed creating socket\n");
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(1500);
addr.sin_addr.s_addr = INADDR_ANY;
// first bind succeeds
if ( (status = bind(sock, (struct sockaddr *) &addr, sizeof(addr))) < 0)
printf("bind error with port %s\n", strerror(errno));
struct sockaddr_in src_addr;
memset(&src_addr, 0, sizeof(struct sockaddr_in));
src_addr.sin_family = AF_INET;
if (inet_aton("10.0.2.17", &(src_addr.sin_addr)) == 0)
printf("Failed copying address\n");
// second bind fails
if((status = bind(sock, (struct sockaddr *)&src_addr, sizeof(src_addr))) < 0)
printf("re bind error with ip %s\n", strerror(errno));
Any ideas in this regard will be highly appreciated. I have gone through considerable material on sockets, SO etc. but no success yet.
I finally found the solution myself so accepting my own answer (shameless but correct plugin), supplemented with code sample.
I originally wanted to rewrite source address of an outgoing packet without creating the socket again where the socket was already bound. Calling bind multiple times fail for this case, and (in my particular situation), i was not able to just have separate sockets for each source ip and use it.
I found some references in IP_PACKET_INFO but it was a pain to get it to work correctly. Following reference was helpful.
Setting source of udp socket
Sample Code
Here is a trivial application which creates a udp socket, binds it to a local port, then before sending a particular message, it appends the outgoing source ip address. Keeping in mind that in my case, i created a sudo interface and assigned it another ip. The send call will fail if this is not the case.
int status=-1;
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock < 0)
printf("Failed creating socket\n");
int opt = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in bind_addr;
memset(&bind_addr, 0, sizeof(struct sockaddr_in));
bind_addr.sin_family = AF_INET;
bind_addr.sin_port = htons(44000); // locally bound port
if((status = bind(sock, (struct sockaddr *)&bind_addr, sizeof(bind_addr))) < 0)
printf("bind error with port %s\n", strerror(errno));
// currently using addr as destination
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(80); // destination port
if (inet_aton("74.125.236.35", &(addr.sin_addr)) == 0)
printf("Failed copying remote address\n");
else
printf("Success copying remote address\n");
struct sockaddr_in src_addr;
memset(&src_addr, 0, sizeof(struct sockaddr_in));
src_addr.sin_family = AF_INET;
if (inet_aton("10.0.2.17", &(src_addr.sin_addr)) == 0)
printf("Failed copying src address\n");
else
printf("Success copying src address\n");
char cmbuf[CMSG_SPACE(sizeof(struct in_pktinfo))];
char msg[10] = "hello";
int len = strlen(msg);
struct msghdr mh;
memset(&mh, 0, sizeof(mh));
struct cmsghdr *cmsg;
struct in_pktinfo *pktinfo;
struct iovec iov[1];
iov[0].iov_base = msg;
iov[0].iov_len = len;
mh.msg_name = &addr; // destination address of packet
mh.msg_namelen = sizeof(addr);
mh.msg_control = cmbuf;
mh.msg_controllen = sizeof(cmbuf);
mh.msg_flags = 0;
mh.msg_iov = iov;
mh.msg_iovlen = 1;
// after initializing msghdr & control data to
// CMSG_SPACE(sizeof(struct in_pktinfo))
cmsg = CMSG_FIRSTHDR(&mh);
cmsg->cmsg_level = IPPROTO_IP;
cmsg->cmsg_type = IP_PKTINFO;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
pktinfo = (struct in_pktinfo*) CMSG_DATA(cmsg);
//src_interface_index 0 allows choosing interface of the source ip specified
pktinfo->ipi_ifindex = 0;
pktinfo->ipi_spec_dst = src_addr.sin_addr;
int rc = sendmsg(sock, &mh, 0);
printf("Result %d\n", rc);
The key statement is
pktinfo->ipi_spec_dst = src_addr.sin_addr;
where we are specifying the source ip address to be used. The rest of things like cmsg struct etc. are merely used in order to be able to write ipoktinfo struct ourselves
There is no way to unbind and rebind an existing socket.
Why don't you create a socket for each interface instead? Since the UDP/IP protocol is connectionless, you can choose the source IP address by choosing which socket you use to send the reply with; there is no need to use the same socket the incoming datagram was received on.
The downsides are that you can no longer bind to the wildcard address, and you must use select(), poll(), multiple threads, or some other mechanism to receive datagrams from multiple sources concurrently. You'll also need some logic to efficiently pick the socket based on the client IP address.
In most cases, I suspect that adding a few route entries to route each remote IP address to the desired host IP address, and using a separate socket for each host IP address and port combination, solves the issues perfectly -- and using the very efficient kernel functionality to do so. While the behaviour may be an application requirement, I suspect it is better solved using the network interface configuration instead. Unfortunately, often the requirements are written by semi-functional idiots better suited for manual labor, and your hands are tied.. if so, I commiserate.
If you have a test network with workstations having multiple physical network interfaces, I can provide a simple example C99 test program you can use to verify the design works.

sending a struct over UDP UNIX sockets in 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)...

Resources