Ping 6 program in nano linux using c programming - c

I am trying to write a program in C language using the nano ceditor in linux(ubuntu) in order to ping many devices at the same time, the goal is to retrieve roundtime information about the ping.
The program looks like this :
#include <stdio.h>
main()
{
int i;
for (i=0; i<9; i++)
printf("pinging device number:%d",i);
ping6 fe80::acbd:ff:fe00:i%nstack -c 2
printf(" \n Done");
}
With ping it works normally but im using ipv6 and it doesnt work.
Note: if i do the ping6 command alone it works its just when im putting it in my program
Thank you

the posted code contains several problems:
Most of those problems are covered in the question comments.
The following code compiles cleanly and performs the desired function
#include <stdio.h> // printf()
#include <stdlib.h> // system()
int main( void )
{
int i;
for (i=0; i<9; i++)
{
printf("pinging device number:%d\n",i);
system( "ping6 fe80::acbd:ff:fe00:i%nstack -c 2" );
}
printf(" \n Done\n");
}
the output from the above code is:
pinging device number:0
unknown host
pinging device number:1
unknown host
pinging device number:2
unknown host
pinging device number:3
unknown host
pinging device number:4
unknown host
pinging device number:5
unknown host
pinging device number:6
unknown host
pinging device number:7
unknown host
pinging device number:8
unknown host
Done
You may be able to reach a valid host from your network.
However, remember the excerpt from the man page about not being able to perform routing.
(edit) the following code cleanly compiles and uses sprintf()
However, I find nothing that supports the 6th address :1%nstack parameter! I would expect to only see the device number, not the text: %nstack what am I missing?
#include <stdio.h> // printf(), sprintf()
#include <stdlib.h> // system()
int main( void )
{
int i;
char pingCmd[100] = {'\0'};
for (i=0; i<9; i++)
{
printf("\npinging device number:%d\n",i);
//system( "ping6 fe80::acbd:ff:fe00:i%nstack -c 2" );
sprintf( pingCmd, "%s%d%s", "ping6 -c 2 fe80::acbd:ff:fe00:", i, "%nstack");
printf( "%s\n", pingCmd);
system( pingCmd );
}
printf(" \n Done\n");
}
the output from the above is:
pinging device number:0
ping6 -c 2 fe80::acbd:ff:fe00:0%nstack
unknown host
pinging device number:1
ping6 -c 2 fe80::acbd:ff:fe00:1%nstack
unknown host
pinging device number:2
ping6 -c 2 fe80::acbd:ff:fe00:2%nstack
unknown host
pinging device number:3
ping6 -c 2 fe80::acbd:ff:fe00:3%nstack
unknown host
pinging device number:4
ping6 -c 2 fe80::acbd:ff:fe00:4%nstack
unknown host
pinging device number:5
ping6 -c 2 fe80::acbd:ff:fe00:5%nstack
unknown host
pinging device number:6
ping6 -c 2 fe80::acbd:ff:fe00:6%nstack
unknown host
pinging device number:7
ping6 -c 2 fe80::acbd:ff:fe00:7%nstack
unknown host
pinging device number:8
ping6 -c 2 fe80::acbd:ff:fe00:8%nstack
unknown host
Done

Related

Binding a BPF descriptor to an interface

I'm trying to write a small C program on an OpenBSD vm I just installed, and cannot get my file descriptor (to /dev/bpf) to bind to my interface.
OpenBSD info:
openbsd:waffles uplime$ uname -a
OpenBSD openbsd.securitea.app 6.5 GENERIC#3 amd64
openbsd:waffles uplime$ ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 32768
index 4 priority 0 llprio 3
groups: lo
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4
inet 127.0.0.1 netmask 0xff000000
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 00:0c:29:34:99:7b
index 1 priority 0 llprio 3
groups: egress
media: Ethernet autoselect (1000baseT full-duplex,master)
status: active
inet 10.10.73.199 netmask 0xfffffc00 broadcast 10.10.75.255
em1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 00:0c:29:34:99:85
index 2 priority 0 llprio 3
media: Ethernet autoselect (1000baseT full-duplex,master)
status: active
inet 172.16.221.129 netmask 0xffffff00 broadcast 172.16.221.255
enc0: flags=0<>
index 3 priority 0 llprio 3
groups: enc
status: active
pflog0: flags=141<UP,RUNNING,PROMISC> mtu 33136
index 5 priority 0 llprio 3
groups: pflog
openbsd:waffles uplime$
However, when I try to bind my descriptor to em0, I get the following error:
openbsd:waffles uplime$ cc -std=c99 -Wall -Wextra -pedantic -g -O1 -o tmp/test tmp/test.c
openbsd:waffles uplime$ doas tmp/test
ioctl: em0: Device not configured
openbsd:waffles uplime$
I'm using the following testcase:
#include <errno.h>
#include <fcntl.h>
#include <net/bpf.h>
#include <net/if.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
int fd = open("/dev/bpf", O_RDONLY);
int packet_max = 32768;
if(fd < 0) {
fprintf(stderr, "open: /dev/bpf: %s\n", strerror(errno));
return 1;
}
if(ioctl(fd, BIOCSBLEN, &packet_max) < 0) {
fprintf(stderr, "ioctl: BIOCSBLEN: %s\n", strerror(errno));
return 1;
}
struct ifreq req;
memset(&req, 0, sizeof(req));
strcpy(req.ifr_name, "em0");
if(ioctl(fd, BIOCSETIF, req) < 0) {
fprintf(stderr, "ioctl: em0: %s\n", strerror(errno));
return 1;
}
return 0;
}
I know the interface is fine, because it is the only one connected to the internet, and I'm able to make inbound/outbound requests without issue. I can also run tcpdump -i em0 without issue. Am I missing an ioctl call (or something similar) to make the interface usable?

OpenMPI Execution Problems on Raspberry Pi

I am trying to build a beowulf cluster with Raspberry Pi. I downloaded the following packages of OpenMPI: openmpi-bin, openmpi-common, libopenmpi1.3, libopenmpi-dbg, libopenmpi-dev. I used static IP on each of the Raspberrys and tested the connection between each of them and it was working. I also enabled the ssh and I used it to login from one Raspberry to all the other Raspberrys.
This is the following code I used:
#include <mpi.h>
int main(int argc, char *argv[])
{
int tid,nthreads;
char *cpu_name;
/* add in MPI startup routines */
/* 1st: launch the MPI processes on each node */
MPI_Init(&argc,&argv);
/* 2nd: request a thread id, sometimes called a "rank" from
the MPI master process, which has rank or tid == 0
*/
MPI_Comm_rank(MPI_COMM_WORLD, &tid);
/* 3rd: this is often useful, get the number of threads
or processes launched by MPI, this should be NCPUs-1
*/
MPI_Comm_size(MPI_COMM_WORLD, &nthreads);
/* on EVERY process, allocate space for the machine name */
cpu_name = (char *)calloc(80,sizeof(char));
/* get the machine name of this particular host ... well
at least the first 80 characters of it ... */
gethostname(cpu_name,80);
printf("hello MPI user: from process = %i on machine=%s, of NCPU=%i processes\n",
tid, cpu_name, nthreads);
MPI_Finalize();
return(0);
}
I tested the code first with only 2 boards and it worked fine no problems no errors and it printed the printf statement in the code.
I created a host file which includes the following:
Pi0
Pi1
Pi2
Pi3
I have 4 Raspberry Pis. I copied the code on each of them and compiled the code also using the following statements:
mpicc -g -0O -c hello-mpi.c -o hello-mpi.o
mpicc -g hello-mpi.o -o hello-mpi
I executed the code with the following statement:
mpirun -np 4 -hostfile hostfile hello-mpi
when I run the program nothing happens it just gives me an new empty line. No errors are given also. Any suggestion what I can I do to make it work

C/UNIX: port scanner

I need program that find all web servers into file that contains IP addresses.
I found that IP address is server if his port 80 is open. And I wrote this code but it doesn't work. Аlways sayd that port 80 is closed, even i write IP with open port 80. (194.153.145.104 for example). Where I wrong?
I'm cheking here for IP's with open ports: http://www.yougetsignal.com/tools/open-ports/
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
u_short port=80; /* user specified port number */
short int sock = -1; /* the socket descriptor */
struct hostent *host_info; /* host info structure */
struct sockaddr_in address; /* address structures */
char addr[1023];
char buf[20];
char *filename;
filename=argv[1];
FILE *file = fopen( filename, "r" );
while (!feof(file))
{
fscanf(file,"%s",buf);
strncpy(addr, buf, 1023);
bzero((char *)&address, sizeof(address));
address.sin_addr.s_addr = inet_addr(addr);
address.sin_port = htons(port);
address.sin_family=AF_INET;
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock == -1) {
fprintf(stderr, "Error: could not assign master socket\n");
exit (1);
}
if(connect(sock,(struct sockaddr *)&address,sizeof(address)) == 0)
printf("%s is a web server\n", addr);
else printf("%s isn't a web server\n", addr);
close(sock);
}
return 0;
}
Did you compile with warnings enabled? Using gcc I added -Wall, which says inet_addrisnt declared right. Including <arpa/inet.h> makes the program work just fine.
I suggest checking the return values of all functions and system calls you use, as to detect and locate any possible errors.
Sample output:
$ ./a.out ip.txt
127.0.0.1 is a web server
127.0.0.1 isn't a web server
EDIT: Adding some more details about my test setup, since it still does not work for the OP.
Added the include for <arpa/inet.h>
Compiled with gcc -Wall -O0 http_port_scan.c
Set up a listener on port 80 with: sudo nc -l 80
Executed: ./a.out ip.txt
The file ip.txt looks like:
~/src/so$ cat ip.txt
127.0.0.1
thuovila#glx:~/src/so$ file ip.txt
ip.txt: ASCII text
On this computer I get two lines saying "is a web server" since the nc is closed slower than my other computer. The execution environment is Ubuntu LTS 12.04 with the uname -a: Linux glx 3.2.0-43-generic #68-Ubuntu SMP Wed May 15 03:33:33 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
My suggestion is still, that you add checking for all the return values of functions and if they fail, call perror() or use some other means to figure out the error.

simple UDP server can't accept packets

I have a simple UDP server program
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char**argv)
{
int sockfd,n;
struct sockaddr_in servaddr,cliaddr;
socklen_t len;
char mesg[1000];
sockfd=socket(AF_INET,SOCK_DGRAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(54000);
bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
for (;;)
{
len = sizeof(cliaddr);
n = recvfrom(sockfd,mesg,1000,0,(struct sockaddr *)&cliaddr,&len);
sendto(sockfd,mesg,n,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
printf("-------------------------------------------------------\n");
mesg[n] = 0;
printf("Received the following:\n");
printf("%s",mesg);
printf("-------------------------------------------------------\n");
}
}
~
I compile it
gcc -m32 -o udp_server udp_server.c
and run it(./udp_server) on several linux machines, it works fine and I use a udp client client to send packets to the UDP server on these machines, they are accepted
but I have a new machine(let me call it A), it is relatively strange compared to other linux machines, as shown in https://superuser.com/questions/581442/ifconfig-command-not-found
anyway it has no "eth0" and the interfaces are:
[root#kitch proxy]# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: em1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT qlen 1000
link/ether 00:1a:a0:23:86:6c brd ff:ff:ff:ff:ff:ff
First, I run the 32-bit-version of the program on it and I got
-bash: ./udp_server: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
Then, second, I compile the UDP program without '-m32' and run it on the machine A, it runs normally
Then I use UDP client to send packets to the UDP server on A
I can capture the sent packets on this machine, but the UDP server doesn't accept those packets,
are there any potential reasons for this?
maybe the binding doesn't work here because this machine is special?
thanks!
Some recent Linux distros (e.g. Fedora) have changed the name of the interface from ethX to emX, so, nothing wrong with it.
You got problem with that machine because the server is not running at all as this line claims:
-bash: ./udp_server: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
I guess you've compiled the program in a 32bit mode ( look at the -m32 gcc parameter ) in a 64bit machine with no 32bit library support installed.
Recompile it without -m32 options.

Linux ioctl command is changing between userspace and kernel space

Not sure if anyone has any ideas here, I haven't seen this before. I'm writing a stub to test out my kernel module, when I check the value of the command in userspace I get a different value vs. when I take a look at the in kernel space.
Part of the stub:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "ain.h"
#include "ain_ioctl.h"
#define AI_DEVICE "/dev/ain"
void main()
{
int fd, error, ioctl_par = 0;
char* dev;
long ret;
dev = AI_DEVICE;
printf("Starting driver test\n");
fd = open(dev, O_RDWR);
if (fd < 0) {
/* Failed to open -> Print error-message and exit */
printf("%s failed to open, error: %s\n", dev, strerror(errno));
}
printf("Doing the IOCTL now... cmd: %d\n", AIN_IOC_GET_AN0_CONF);
fflush(stdout);
ret = ioctl(fd, AIN_IOC_GET_AN0_CONF, &ioctl_par);
The ain_ioctl.h file:
#define AIN_IOC_MAGIC 'e'
#define AIN_IOC_GET_AN0_CONF _IOR(AIN_IOC_MAGIC, 46, int)
The ioctl routine in the kernel:
int ain_ioctl (struct inode * inodep, struct file * filp, unsigned int cmd, unsigned long arg)
{
printk("In the ain_ioctl function, cmd: %d. type: %d, dir: %d, nr: %d, size: %d\n",
cmd, _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
printk("Testing against command: %d. type: %d, dir: %d, nr: %d, size: %d\n",
AIN_IOC_GET_AN0_CONF, _IOC_TYPE(AIN_IOC_GET_AN0_CONF), _IOC_DIR(AIN_IOC_GET_AN0_CONF),
_IOC_NR(AIN_IOC_GET_AN0_CONF), _IOC_SIZE(AIN_IOC_GET_AN0_CONF));
Now I would have expected identical output in the user space print as in the kernel. And in the first set of prints in the kernel to the second. However that's not what I'm seeing...
Output:
mike#linux-4puc:~> ./a.out
Starting driver test
Doing the IOCTL now... cmd: -2147195602
mike#linux-4puc:~> dmesg | tail
[75253.205136] In the ain_ioctl function, cmd: -1078168112. type: 117, dir: 2, nr: 208, size: 16316
[75253.205140] Testing against cmd: -2147195602. type: 101, dir: 2, nr: 46, size: 4
Anyone have any ideas on why my command is acting differently when I pass it to the kernel via the ioctl command vs when I just check the values by hard coding them (as I am doing in my prints)?
The only warnings I'm seeing when I build seem nothing to do with the ioctl calls:
makedepend: warning: ignoring option -Wall
makedepend: warning: ignoring option -Wall
makedepend: warning: ain.c (reading /usr/src/linux/include/linux/compiler-gcc.h), line 94: incomplete include == "#include gcc_header(__GNUC__)"
makedepend: warning: ain.c (reading /usr/src/linux/include/linux/string.h, line 13): cannot find include file "stdarg.h"
Thanks.
The -1078168112 (why aren't you printing these in hex?) looks like a stack pointer. Possibly &ioctl_par. This suggests that your ioctl method is receiving different parameters than you expected.
In the current kernel source I see ioctl methods taking 3 parameters, not 4. The 4-argument ioctl seems to be an older interface.
Do you get any warnings during the module compilation? Pay attention to them!
Alan Curry's answer was not the complete "correct" answer, but it lead me to the solution. The hex value of the command was way off so I took a look at other ioctl calls in the kernel.
The system I have is based off an older 2.4X kernel, and I'm updating it for 3.1. The issue here is the parameter list for the ioctl call. Having the inode pointer in the parameter list was causing the problem as it was taking the file pointer to be the command.
Proper solution:
long ain_ioctl (struct file * filp, unsigned int cmd, unsigned long arg) {
...

Resources