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.
Related
I am learning about kernel TLS on kernel 5.3 version (Fedora 30 and 31) but stuck even on enabling ULP:
// tls.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/tls.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
int main() {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
perror("socket creation");
exit (EXIT_FAILURE);
}
if (setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls")) == -1 ) {
perror("tls init");
exit (EXIT_FAILURE);
}
close (sock);
return EXIT_SUCCESS;
}
Then:
$ cat /proc/sys/net/ipv4/tcp_available_ulp
tls
$ gcc tls.c -O0 -g
$ lsmod | grep tls
$ ./a.out
tls init: No such file or directory
$ lsmod | grep tls
$ sudo ./a.out
tls init: Unknown error 524
$ lsmod | grep tls
tls 57344 0
$ ./a.out
tls init: Unknown error 524
$
I don't know where I am wrong. It looks so simple in Kernel TLS docs:
Creating a TLS connection
First create a new TCP socket and set the TLS ULP.
sock = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));
Setting the TLS ULP allows us to set/get TLS socket options. Currently
only the symmetric encryption is handled in the kernel. After the TLS
handshake is complete, we have all the parameters required to move the
data-path to the kernel. There is a separate socket option for moving
the transmit and the receive into the kernel.
I don't understand how I can enable in kernel TLS and what I am doing wrong.
I'm quite new to C and run into strange problem that I can not explain or solve.
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
void main ()
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sock_addr;
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons(1500);
connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
puts("A");
char foo[9];
puts("B");
close(sock);
}
Code above prints out following lines:
A
B
If I comment out char foo[9] or change 9 to some smaller value then nothing is being printed out and program hangs. Looks like connect is that makes program to freeze but I don't see anything wrong on that line.
How to fix above code so that char foo[9] can be removed and program still prints out A and B and then exits? Why completely unrelated char foo[9] avoids program to freeze?
I'm using GCC 6.3.0 on Ubuntu.
Converting comments to an answer.
The code shown has an incorrect return type for the main() function on Linux. That is required to be int on all systems except Windows — only on Windows can you possibly hope to use void main(). See What should main() return in C and C++ for more information.
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
int main(void)
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
// missed error check - probably not critical
struct sockaddr_in sock_addr;
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons(1500);
// missed intialization of sock_addr.sin_addr - crucial!
// omitted trace printing before the call
connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
// missed error check — possibly critical
// omitted trace printing after the call - not crucial because of puts() calls
puts("A");
char foo[9];
puts("B");
close(sock);
}
Have you tried error checking the system calls? You set the port and family but not the IP address when you try to connect — that is dubious at best, erroneous at worst. I'm not immediately sure why it causes the symptoms you're seeing, but there are problems en route to where the trouble occurs. It could be that your changed code changes the IP address part of sock_addr and your system is hanging trying to contact an uncontactable machine.
How long have you waited before deciding the program's frozen?
Have you tried adding fprintf(stderr, "BC\n"); before the call to connect() and fprintf(stderr, "AC\n"); after it? Does the call hang?
Are you using the optimizer at all?
Do you compile with warnings enabled, such as warnings for unused variables? (Use gcc -Wall -Werror -Wextra -Wstrict-prototypes -Wmissing-prototypes as a starting point — if it doesn't compile cleanly under those options, it quite possibly won't run cleanly either. Include -g for debug information and -O3; if you're doing serious debugging in a debugger, then drop the -O3.)
The code doesn't initialize the sock_addr variable properly — it doesn't set the sin_addr at all, so you're connecting to an indeterminate IP address (you've literally no idea what you're trying to connect to). At minimum, use struct sockaddr_in sock_addr = { 0 }; to set it to zeros. Or use memset(&sock_addr, '\0', sizeof(sock_addr));. You're invoking undefined behaviour because you don't initialize the structure properly. And variable responses from compilers and optimizers is symptomatic of undefined behaviour.
Karmo Rosental notes:
It is connecting to localhost when it's not freezing but your suggestion struct sockaddr_in sock_addr = { 0 }; helped to avoid freezing in GCC.
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/sctp.h>
#include <stdio.h>
#include <string.h>
int main(int argc,char **argv)
{
struct sockaddr_in remoteAddr;
int clientSock = socket(PF_INET,SOCK_SEQPACKET,IPPROTO_SCTP);
if(clientSock == -1) {
perror("socket");
return 1;
}
memset(&remoteAddr,0,sizeof remoteAddr);
remoteAddr.sin_family = AF_INET;
remoteAddr.sin_len = sizeof remoteAddr;
remoteAddr.sin_port = htons(5555);
remoteAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
sctp_assoc_t assoc_id = 0;
if(sctp_connectx(clientSock,(struct sockaddr*)&remoteAddr,1, &assoc_id)!= 0) {
perror("sctp_connectx");
return 1;
}
printf("Connected! Assoc ID %d\n",(int)assoc_id);
return 0;
}
When run, this code fails:
$ clang -Wall sctp_connect.c
$ ./a.out
sctp_connectx: Invalid argument
$ uname -rp
11.0-RELEASE-p9 amd64
But I cannot figure out what's wrong. The sctp_connectx() manpage says it will fail with EINVAL if an address with invalid family or no addresses was provided - but that seems not to be the case from the code.
The sctp_connectx() has several parts where it can fail with EINVAL, but truss shows it gets to the setsockopt() call, so it's the kernel that fails the call:
socket(PF_INET,SOCK_SEQPACKET,132) = 3 (0x3)
mmap(0x0,2097152,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 34374418432 (0x800e00000)
setsockopt(0x3,0x84,0x8007,0x800e16000,0x14) ERR#22 'Invalid argument'
I think answer is there in your query. If we follow the truss trace then as you said it fails on setsockopt().
So the error EINVAL is returned by setsockopt(). And as per FreeBSD setsockopt() manual:
[EINVAL]: Installing an accept_filter(9) on a non-listening
socket was attempted.
is the description of the error. So I think you should do below things:
Explore your socket options whether they are correct with respect to you listener socket.
Check for the errors for functions htons() and inet_addr()
And my suggestion is that you should not use inet_addr(), for more details see man pages, as per that:
Use of this function is problematic because -1 is a valid address
(255.255.255.255). Avoid its use in favor of inet_aton(),
inet_pton(3), or getaddrinfo(3), which provide a cleaner way to
indicate error return.
I have a test program:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <mqueue.h>
#include <errno.h>
#include <fcntl.h>
int main() {
struct mq_attr attrs;
attrs.mq_maxmsg = 10;
attrs.mq_msgsize = sizeof(int);
const char name[] = "/test-queue";
mqd_t q = mq_open(name, O_CREAT | O_RDWR, 0600, &attrs);
if (q == (mqd_t)-1) {
perror("mq_open");
exit(EXIT_FAILURE);
}
mq_unlink(name); // it doesn't matter if I do this at the end or not
if (fork()) {
int msg = 666;
if (mq_send(q, (const char *)&msg, sizeof(msg), 1)) {
perror("mq_send");
exit(EXIT_FAILURE);
}
} else {
int msg;
unsigned priority;
if (mq_receive(q, (char *)&msg, sizeof(msg), &priority) == -1) {
perror("mq_receive");
exit(EXIT_FAILURE);
}
printf("%d\n", msg);
}
mq_close(q);
return 0;
}
I compile this program using gcc -std=c99 -Wall -o mqtest mqtest.c -lrt on two platforms:
Linux kallikanzarid-desktop 3.8.0-31-generic #46-Ubuntu SMP Tue Sep 10 20:03:44 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
FreeBSD bsd.localhost 9.2-RELEASE FreeBSD 9.2-RELEASE #0 r255898: Thu Sep 26 22:50:31 UTC 2013 root#bake.isc.freebsd.org:/usr/obj/usr/src/sys/GENERIC amd64
On Linux, everything works. On FreeBSD, I get mq_receive: Bad file descriptor. Moving the mq_unlink call to the end of main() doesn't help. Is there a way to fix this, or do I have to postpone marking the queue for deletion and reopen it after the fork?
FreeBSD does preserve message queue descriptors. See mq_open(2):
FreeBSD implements message queue based on file descriptor. The descriptor is inherited by child after fork(2). The descriptor is closed in a new image after exec(3). The select(2) and kevent(2) system calls are supported for message queue descriptor.
Edit:
The structure that mqd_t points to does contain a descriptor. But if you test that file descriptor just after the fork() using fcntl(), it also returns EBADF.
This is a bug in FreeBSD. But wether the bug is in the docs or in the implementation I cannot say.
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.