Assign ipv6 address using ioctl - networking

I'm trying to assign an IPv6 address to an interface using ioctl, but in vain. Here's the code I used:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <net/if.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/sockios.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define IFNAME "eth1"
#define HOST "fec2::22"
#define ifreq_offsetof(x) offsetof(struct ifreq, x)
int main(int argc, char **argv) {
struct ifreq ifr;
struct sockaddr_in6 sai;
int sockfd; /* socket fd we use to manipulate stuff with */
int selector;
unsigned char mask;
char *p;
/* Create a channel to the NET kernel. */
sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
if (sockfd == -1) {
printf("Bad fd\n");
return -1;
}
/* get interface name */
strncpy(ifr.ifr_name, IFNAME, IFNAMSIZ);
memset(&sai, 0, sizeof(struct sockaddr));
sai.sin6_family = AF_INET6;
sai.sin6_port = 0;
//if(inet_aton(HOST, &sai.sin_addr.s_addr) == 0) {
if(inet_pton(AF_INET6, HOST, (void *)&sai.sin6_addr) <= 0) {
//&((struct sockaddr_in*)&sa)->sin_addr
printf("Bad address\n");
return -1;
}
p = (char *) &sai;
memcpy( (((char *)&ifr + ifreq_offsetof(ifr_addr) )),
p, sizeof(struct sockaddr));
int ret = ioctl(sockfd, SIOCSIFADDR, &ifr);
printf("ret: %d\terrno: %d\n", ret, errno);
ioctl(sockfd, SIOCGIFFLAGS, &ifr);
printf("ret: %d\terrno: %d\n", ret, errno);
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
// ifr.ifr_flags &= ~selector; // unset something
ioctl(sockfd, SIOCSIFFLAGS, &ifr);
printf("ret: %d\terrno: %d\n", ret, errno);
close(sockfd);
return 0;
}
The ioctl calls fail saying ENODEV. When the family of the socket is changed to sockfd = socket(AF_INET, SOCK_DGRAM, 0);, the calls fail again saying EINVAL.
I was able to assign an IPv4 address to the interface with the above code by using
sockaddr_in in lieu of sockaddr_in6.
Is it not possible to assign IPv6 address using ioctl?

Drawing inspiration from the linux implementation of 'ifconfig' command, I was able to set the IPv6 address on an interface. Here's the code for it:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <net/if.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/sockios.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
#include <netpacket/packet.h>
#include <net/ethernet.h>
#else
#include <asm/types.h>
#include <linux/if_ether.h>
#endif
#define IFNAME "eth0"
#define HOST "fec2::22"
#define ifreq_offsetof(x) offsetof(struct ifreq, x)
struct in6_ifreq {
struct in6_addr ifr6_addr;
__u32 ifr6_prefixlen;
unsigned int ifr6_ifindex;
};
int main(int argc, char **argv) {
struct ifreq ifr;
struct sockaddr_in6 sai;
int sockfd;
struct in6_ifreq ifr6;
sockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
if (sockfd == -1) {
printf("Bad fd\n");
return -1;
}
/* get interface name */
strncpy(ifr.ifr_name, IFNAME, IFNAMSIZ);
memset(&sai, 0, sizeof(struct sockaddr));
sai.sin6_family = AF_INET6;
sai.sin6_port = 0;
if(inet_pton(AF_INET6, HOST, (void *)&sai.sin6_addr) <= 0) {
printf("Bad address\n");
return -1;
}
memcpy((char *) &ifr6.ifr6_addr, (char *) &sai.sin6_addr,
sizeof(struct in6_addr));
if (ioctl(sockfd, SIOGIFINDEX, &ifr) < 0) {
perror("SIOGIFINDEX");
}
ifr6.ifr6_ifindex = ifr.ifr_ifindex;
ifr6.ifr6_prefixlen = 64;
if (ioctl(sockfd, SIOCSIFADDR, &ifr6) < 0) {
perror("SIOCSIFADDR");
}
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
int ret = ioctl(sockfd, SIOCSIFFLAGS, &ifr);
printf("ret: %d\terrno: %d\n", ret, errno);
close(sockfd);
return 0;
}

Based off of #maddy's answer I made a more compact version that is a little easier to adapt. The trick is the struct in6_ifreq structure that has to be passed to the ioctl.
#include <stdint.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#define IFNAME "eth0"
#define HOST "2001::22"
struct in6_ifreq {
struct in6_addr addr;
uint32_t prefixlen;
unsigned int ifindex;
};
int main(int argc, char **argv) {
struct ifreq ifr;
struct in6_ifreq ifr6;
int sockfd;
int err;
// Create IPv6 socket to perform the ioctl operations on
sockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
// Copy the interface name to the ifreq struct
strncpy(ifr.ifr_name, IFNAME, IFNAMSIZ);
// Get the ifrindex of the interface
err = ioctl(sockfd, SIOGIFINDEX, &ifr);
// Prepare the in6_ifreq struct and set the address to the interface
inet_pton(AF_INET6, HOST, &ifr6.addr);
ifr6.ifindex = ifr.ifr_ifindex;
ifr6.prefixlen = 64;
err = ioctl(sockfd, SIOCSIFADDR, &ifr6);
close(sockfd);
return 0;
}
I left off all error checking for readability but the commands should be checked for errors.

Related

Catch signals SIGUSR1 or SIGTERM with signalfd on MPI applications?

A simple MPI code to catch the SIGUSR1, SIGTERM signals with signalfd unix system call
#include <assert.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <sys/signalfd.h>
#include <unistd.h>
#include <mpi.h>
/*Simple MPI Code*/
int main(int argc, char* argv[]){
MPI_Init(&argc, &argv);
int err, nbProcs, rank;
sigset_t sigset;
int fd;
MPI_Comm_size(MPI_COMM_WORLD, &nbProcs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
****
Setup SIGALRM to be delivered via SignalFD
****
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGTERM);
sigaddset(&mask, SIGUSR1);
/* */
if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
printf("Failed to signalmask\n");
return -1;
}
fd = signalfd(-1, &mask, 0);
if (fd < 0)
return -1;
while (1) {
struct signalfd_siginfo si;
int ret;
ret = read(fd, &si, sizeof(si));// here the MPI process doesn't
return when I send SIGTERM or SIGUSR1
if (ret < 0)
return -1;
if (ret != sizeof(si))
return -1;
if (si.ssi_signo == SIGTERM)
printf("receive SIGTERM \\\n");
else if (si.ssi_signo == SIGUSR1)
printf("receive SIGUSR1\n");
}
MPI_Finalize();
return 0;
}
In this code, I am using signalfd to catch SIGUSR1, SIGTERM. At
ret = read(fd, &si, sizeof(si));
read() system call it doesn't return and the program dies at this point. When I use the same code without MPI simple C code it works perfect.Can anyone explain me how does signalfd works inside MPI???

Peer credentials through unix domain socket ipc mechanism

I'm writing a code for extraction of peer credential by the server process connected through ipc using domain sockets to the client process. There is no error in the code but while running it I don't get the euid and gid of the peer process.
Code for server process is:
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
//#include<ucred.h>
#define SCM_CREDENTIALS
# define UNIX_PATH_MAX 100
int getpeereid(int connection_fd,uid_t euid,gid_t gid)
{
struct ucred cred;
socklen_t len = sizeof(cred);
if (getsockopt(connection_fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0)
return (-1);
euid =cred.uid;
gid = cred.gid;
//int passcred=1;
//setsockopt(connection_fd,SOL_SOCKET,SO_PASSCRED,(void *)&passcred,sizeof(passcred));
printf("effective user id", euid);
printf("effective group id",gid);
return 0;
}
int connection_handler(int connection_fd)
{
int nbytes;
char buffer[1024];
char msg[256];
//while(cont=recv(connection_fd,buffer,sizeof(buffer),0)>0)
//{
//write(1,buffer,cont)
nbytes = read(connection_fd, buffer, 256);
buffer[nbytes] = 0;
printf("MESSAGE FROM CLIENT: %s\n", buffer);
printf("enter the message");
scanf("%s",msg);
nbytes = snprintf(buffer, 256,msg);
write(connection_fd, buffer, nbytes);
//}
close(connection_fd);
return 0;
}
int main(void)
{
struct sockaddr_un address;
int socket_fd, connection_fd,res;
socklen_t address_length;
pid_t child;
uid_t eid;
gid_t gid;
socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
if(socket_fd < 0)
{
printf("socket() failed\n");
return 1;
}
printf("socket created\n");
unlink("./demo_socket");
/* start with a clean address structure */
memset(&address, 0, sizeof(struct sockaddr_un));
address.sun_family = AF_UNIX;
snprintf(address.sun_path, UNIX_PATH_MAX, "./demo_socket");
if(bind(socket_fd,
(struct sockaddr *) &address,
sizeof(struct sockaddr_un)) != 0)
{
printf("bind() failed\n");
return 1;
}
if(listen(socket_fd, 5) != 0)
{
printf("listen() failed\n");
return 1;
}
while((connection_fd = accept(socket_fd,
(struct sockaddr *) &address,
&address_length)) > -1)
{
// get the credentials
res=getpeereid(connection_fd,geteuid(),getgid());
if (res==0)
{
//if(res==0)
//{
child = fork();
if(child == 0)
{
/* now inside newly created connection handling process */
return connection_handler(connection_fd);
}
}
/* still inside server process */
close(connection_fd);
//}
}
close(socket_fd);
unlink("./demo_socket");
return 0;
}
the code for client
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <string.h>
#define UNIX_PATH_MAX 100
int connection_handler(int socket_fd)
{
int nbytes;
char buffer[1024];
char mesg[256];
printf("enter the message");
scanf("%s",mesg);
//printf("message is %s",mesg);
nbytes = snprintf(buffer, 256,mesg);
//fgets(buffer,256,mesg);
//i=atoi(mesg);
write(socket_fd,buffer,nbytes);
//send(socket_fd,mesg,sizeof(mesg),0);
}
//nbytes = read(socket_fd, buffer, 256);
//buffer[nbytes] = 0;
//printf("MESSAGE FROM SERVER: %s\n", buffer);
//}
int main(void)
{
struct sockaddr_un address;
int socket_fd, nbytes,i;
pid_t child;
char buffer[256];
//char mesg[100];
socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
if(socket_fd < 0)
{
printf("socket() failed\n");
return 1;
}
printf("socket created\n");
/* start with a clean address structure */
memset(&address, 0, sizeof(struct sockaddr_un));
address.sun_family = AF_UNIX;
snprintf(address.sun_path, UNIX_PATH_MAX, "./demo_socket");
if(connect(socket_fd,
(struct sockaddr *) &address,
sizeof(struct sockaddr_un)) != 0)
{
printf("connect() failed\n");
return 1;
}
child=fork();
while(child==0)
{
return connection_handler(socket_fd);
//printf("connection established\n");
//printf("enter the message");
//scanf("%s",mesg);
//printf("message is %s",mesg);
//bytes = snprintf(buffer, 256,mesg);
//fgets(buffer,256,mesg);
//i=atoi(mesg);
//write(socket_fd,buffer,nbytes);
//send(socket_fd,mesg,sizeof(mesg),0);
}
nbytes = read(socket_fd, buffer, 256);
buffer[nbytes] = 0;
printf("MESSAGE FROM SERVER: %s\n", buffer);
close(socket_fd);
return 0;
}
See http://www.thomasstover.com/uds.html for good overview.
If the server is Linux, the main problem is missing _GNU_SOURCE. Full patch below, it has a few minor changes just to get rid of gcc -Wall -Werror -pedantic -std=c99 errors and warnings.
--- server.c.orig 2014-12-06 13:23:09.138472871 +0200
+++ server.c 2014-12-06 13:21:31.962475754 +0200
## -1,3 +1,4 ##
+#define _GNU_SOURCE
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
## -5,7 +6,6 ##
#include <unistd.h>
#include <string.h>
//#include<ucred.h>
-#define SCM_CREDENTIALS
# define UNIX_PATH_MAX 100
int getpeereid(int connection_fd,uid_t euid,gid_t gid)
## -20,8 +20,8 ##
//int passcred=1;
//setsockopt(connection_fd,SOL_SOCKET,SO_PASSCRED,(void *)&passcred,sizeof(passcred));
-printf("effective user id", euid);
-printf("effective group id",gid);
+printf("effective user id %d", euid);
+printf("effective group id %d",gid);
return 0;
}
## -40,7 +40,7 ##
printf("MESSAGE FROM CLIENT: %s\n", buffer);
printf("enter the message");
scanf("%s",msg);
-nbytes = snprintf(buffer, 256,msg);
+nbytes = snprintf(buffer, 256, "%s", msg);
write(connection_fd, buffer, nbytes);
//}
close(connection_fd);
## -54,8 +54,6 ##
int socket_fd, connection_fd,res;
socklen_t address_length;
pid_t child;
-uid_t eid;
-gid_t gid;
socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
if(socket_fd < 0)

Reading from serial port in C

I'm trying to read from Arduino (who's sending char '4' constantly) with XBee.
I have tried writing from the PC to Arduino, and it works, so the connection is correct.
When I execute de following code, the terminal doesn't show anything and don't finish the program, so it gets stuck on reading.
#include <stdio.h> // Standard input / output functions
#include <stdlib.h>
#include <string.h> // String function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitions
#define XBEE "/dev/ttyUSB0"
#define BAUDRATE B9600
int main(int argc,char** argv)
{
struct termios tio;
struct termios stdio;
struct termios old_stdio;
int tty_fd = open(XBEE , O_RDWR| O_NOCTTY);
cfsetospeed(&tio,BAUDRATE);
cfsetispeed(&tio,BAUDRATE); // Baudrate is declared above
tcsetattr(tty_fd,TCSANOW,&tio);
// for(i;i<5;i++){
// write(tty_fd,&c,1); //If new data is available on the console, send it to the serial port
// write(tty_fd,&o,1); //If new data is available on the console, send it to the serial port
// }
int n=0;
char buf = '\0';
/* Whole response*/
do
{
n = read( tty_fd, &buf, sizeof(char) );
}
while( n > 0);
if (n < 0)
{
printf("ERROR READING");
}
else if (n == 0)
{
printf("Read nothing!");
}
else
{
printf("Response: %c",buf);
}
close(tty_fd);
tcsetattr(STDOUT_FILENO,TCSANOW,&old_stdio);
return EXIT_SUCCESS;
}
How do I solve this?
UPDATE
I tried this other code and receive a warning: turning off output flushing and then the terminal froze.
#include <stdio.h> // Standard input / output functions
#include <stdlib.h>
#include <string.h> // String function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitions
#define XBEE "/dev/ttyUSB0"
#define BAUDRATE B9600
int main(int argc,char** argv)
{
struct termios tio;
struct termios stdio;
struct termios old_stdio;
struct termios options;
int tty_fd = open(XBEE , O_RDWR | O_NOCTTY | O_NDELAY);
cfsetospeed(&tio,BAUDRATE);
cfsetispeed(&tio,BAUDRATE); // Baudrate is declared above
tcsetattr(tty_fd,TCSANOW,&tio);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// for(i;i<5;i++){
// write(tty_fd,&c,1);//if new data is available on the console, send it to serial port
// write(tty_fd,&o,1);//if new data is available on the console, send it to serial port
// }
int n=0;
char buf = '1';
int i = 1;
/* Whole response*/
while(i==1){
n = read( tty_fd, &buf, sizeof(char) );
if (n < 0)
{
printf("ERROR READING");
}
else if (n == 0)
{
printf("Read nothing!");
}
else
{
printf("Response: %c",buf);
close(tty_fd);
break;
}
}
tcsetattr(STDOUT_FILENO,TCSANOW,&old_stdio);
return EXIT_SUCCESS;
}
If you're going to be using C to communicate with XBee modules, you might want to check out this Open Source XBee Host library. You could just use the serial driver from it in your code, or take a look at the xbee_term sample program as a simple terminal.
If you are printing data, why are you using printf? You must use the Serial.print() syntax w.r.t the Arduino IDE.

TCP optimisation

I've written a code using SOL_SOCKET protocol but getting error as 10043 (error in socket).
The code is as follows:
#include <QCoreApplication>
#include<QDebug>
//#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
/****************************************/
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
/****************************************/
#define DEFAULT_BUFLEN 512
int recvbuflen = DEFAULT_BUFLEN;
char recvbuf[DEFAULT_BUFLEN];
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
WSADATA wsaData;
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
ZeroMemory( &hints, sizeof(hints) );
//hints.ai_family = AF_UNSPEC;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = SOL_SOCKET;
//hints.ai_protocol = IPPROTO_TCP;
#define DEFAULT_PORT "10990"
// Resolve the server address and port
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return 1;
}
SOCKET ConnectSocket = INVALID_SOCKET;
// Attempt to connect to the first address returned by
// the call to getaddrinfo
ptr=result;
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
int rcvbuf = 8192; /* recv buffer size */
int z = setsockopt(ConnectSocket,SOL_SOCKET,SO_RCVBUF,
(char*)&rcvbuf,sizeof(rcvbuf));
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if (iResult > 0)
printf("Bytes received: %d\n", iResult);
else if (iResult == 0)
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
} while (iResult > 0);
return a.exec();
}
When I run it shows::
Error in socket:10043
I googled it and found that the error is because of wrong protocol for the socket type,I tried to find the correct protocol and socket type match but couldn't find.I tried every possible socket option and protocol match.
Any body facing the same problem?
You're putting the wrong value in the ai_protocol field. It needs to be one of the IPPROTO_ constants (like e.g. IPPROTO_TCP or IPPROTO_ICMP).
SOL_SOCKET is used to set socket options (like you do later in the code).
You should normally not set that member, except to zero.

NETworking with UDP

what happens when a UDP packet is sent to a host using sendto().
all the bits i am sending are sent(known from the return value).immediately i use a recvfrom() which does not output anything but program do not exit(i.e no return value).
I think that the program must exit if no reply is recieved.
what will the replies for a UDP packet from a port.
is this packet blocked by firewall?? if yes then why is the return value of sendto is non-negative.
recvfrom() will block until a message is received unless you set the socket to non-blocking.
The interfaces you want to look for are
ioctl() with FIONBIO or O_NONBLOCK (depending your platform),
select() to wait for data to arrive, or timeout after a while
Also remember that the address and port number for sendto() usually be network-byte order, so look into ntohl and ntohs.
you must have some error in your client or server. try localhost first, so you avoid firewall problems
this is an example of nonblocking udp client/server I was using for my tests, it uses ioctl() to check if there is data to read on the socket, however if you want to do some serious application using epoll would be more efficient also you can specify timeout to wait in microseconds:
[null#localhost tests]$ cat udpserv.c
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#define BUFLEN 512
#define NPACK 15
#define PORT 9930
void diep(char *s)
{
printf("erno=%d errstr=%s\n",errno,strerror(errno));
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_me, si_other;
int s,ret,nbytes, i, slen=sizeof(si_other);
char buf[BUFLEN];
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
diep("socket");
memset((char *) &si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (struct sockaddr*) &si_me, sizeof(si_me))==-1)
diep("bind");
fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0) | O_NONBLOCK);
sleep(10);
for (i=0; i<NPACK; i++) {
ret=ioctl(s,FIONREAD,&nbytes);
if (ret==-1) {
printf("error on FIONREAD\n");
} else {
printf("nbytes=%d\n",nbytes);
}
if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, &slen)==-1)
diep("recvfrom()");
printf("Received first half of packet from %s:%d\nData: %s\n\n",
inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);
}
close(s);
return 0;
}
[null#localhost tests]$ cat udpclient.c
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#define SRV_IP "127.0.0.1"
#define BUFLEN 200
#define NPACK 10
#define PORT 9930
/* diep(), #includes and #defines like in the server */
void diep(char *s)
{
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_other;
int s, i, slen=sizeof(si_other);
char buf[BUFLEN];
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
diep("socket");
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
if (inet_aton(SRV_IP, &si_other.sin_addr)==0) {
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
for (i=0; i<NPACK; i++) {
printf("Sending packet %d\n", i);
sprintf(buf, "This is packet %d\n", i);
if (sendto(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, slen)==-1)
diep("sendto()");
}
close(s);
return 0;
}
the sendto() is non negative because it returns number of bytes sent. check the man page for sendto

Resources