How can retrive all TCP UDP opened ports? - c

I need to make a custom port scanner that scan only opened TCP and UDP ports. I'm working in standard C with sockets. For the moment i retrieve all ports in a range i set.
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <errno.h>
int scanPort(struct hostent *hostaddr,int port){
char responce[1024];
char *message="checking port";
struct sockaddr_in server_address;
int socket_d;
int rval;
socket_d = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(socket_d == -1)
{
perror("Socket()\n");
return errno;
}
memset(&server_address,0,sizeof(server_address));
server_address.sin_family=AF_INET;
server_address.sin_port=htons(port);
memcpy(&server_address.sin_addr,hostaddr->h_addr,hostaddr->h_length);
rval = connect(socket_d,(struct sockaddr *) &server_address, sizeof(server_address));
if(rval == -1)
{
close(socket_d);
return 0;
}else{
close(socket_d);
return 1;
}
}
int main(int argc, char **argv)
{
if(argc < 4){
printf("Exemplu: ./portscanner <adresa_ip> <port_pornire> <port_oprire> \n");
return (EINVAL);
}
int startPort;
int endPort;
int port;
struct hostent *host_address;
host_address = gethostbyname( argv[1] );
startPort = atoi(argv[2]);
endPort = atoi(argv[3]);
for(port = startPort;port<=endPort;port++)
{
if(scanPort(host_address,port)==1){
printf("Port %d is open\n",port);
}
}
}
In the example you can see how i tried to resolve this problem. But i don't see a method to check only the TCP and UDP ports. Please help me with this.
Regards,
Badea Sorin!

There is a plenty ways to do it. I recommend you to install nmap and read the manual.
Many scan methods are implemented there and described in the manual.
You can also refer to the source code if you need more details.
Good luck.

Related

Transfer HTTP connection to HTTPS in Pure C

I am having a serious problem transferring my HTTP connection socket program over to HTTPS connection socket code, how do I make only an HTTPS connection in pure C?
I am working on a package manager and am rewriting the connection.c file, the only thing this file contains is the code used to make the initial connection to the server containg packages, it does nothing else. I had this working 100% with an HTTP connection, however I need to move to an HTTPS connection and need to use LibreSSL; at the moment I am trying to use OpenSSL as I can't find anything on LibreSSL. The HTTP code I had is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include "repos.h"
#include "resolv.h"
short connection()
{
short socket_desc;
socket_desc = socket(AF_INET, SOCK_STREAM, 0); /* create socket with IPv4 and TCP protocol */
char host[17];
if (socket_desc == -1)
printf("could not create socket\n");
struct sockaddr_in *serv_addr = calloc(1, sizeof(struct sockaddr_in));
serv_addr->sin_family = AF_INET;
serv_addr->sin_port = htons(80);
resolv(DEFAULT_HOST, host); /* set repository to use */
if (inet_pton(AF_INET, host, &serv_addr->sin_addr) <= 0) {
printf("error");
free(serv_addr);
return -1;
}
if (connect(socket_desc, (struct sockaddr *)serv_addr, sizeof(*serv_addr)) < 0) {
printf("connection failed\n");
return 1;
}
else {
printf("connection initialized\n");
return 0;
}
/* close the connection */
free(serv_addr);
close(socket_desc);
return 0;
}
This works 100% and I want to just port this over to HTTPS. After looking at the horribly formatted OpenSSL client.c example (see here: https://wiki.openssl.org/index.php/SSL/TLS_Client) I got that code working on my system (had to make some changes to it), and then went off to port over my HTTP code to HTTPS. I worked on it for a bit and thought I got it working, I have been debugging it but can't figure out why it keeps failing. The code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include "repos.h"
#include "resolv.h"
SSL *cSSL;
void initssl()
{
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
}
void destroyssl()
{
ERR_free_strings();
EVP_cleanup();
}
void shutdownssl()
{
SSL_shutdown(cSSL);
SSL_free(cSSL);
}
int main()
{
short socket_desc;
short socket_ssl;
char host[17];
socklen_t sock_size;
SSL_CTX *sslctx;
initssl();
socket_desc = socket(AF_INET, SOCK_STREAM, 0); /* create socket with IPv4 and TCP protocol */
if (socket_desc == -1)
printf("could not create socket\n");
struct sockaddr_in *serv_addr = calloc(1, sizeof(struct sockaddr_in));
serv_addr->sin_family = AF_INET;
serv_addr->sin_port = htons(443);
resolv(DEFAULT_HOST, host); /* resolve DEFAULT_HOST and store the ip in host */
if (inet_pton(AF_INET, host, &serv_addr->sin_addr) <= 0) {
printf("error");
free(serv_addr);
return -1;
}
bind(socket_desc, (struct sockaddr *)serv_addr, sizeof(struct sockaddr_in));
listen(socket_desc, 5);
sock_size = sizeof(struct sockaddr_in);
socket_ssl = accept(socket_desc, (struct sockaddr *)serv_addr, &sock_size); /* this is where hang occurs, however I am usnure why. I am reading docs and such and if I figure this out I will post the fix; however I would love some advice/help if anyone sees my error */
sslctx = SSL_CTX_new(SSLv23_server_method());
SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_DH_USE);
short use_cert = SSL_CTX_use_certificate_file(sslctx, "/serverCertificate.pem" , SSL_FILETYPE_PEM);
short use_prv = SSL_CTX_use_PrivateKey_file(sslctx, "/serverCertificate.pem", SSL_FILETYPE_PEM);
cSSL = SSL_new(sslctx);
SSL_set_fd(cSSL, socket_ssl);
char ssl_err = SSL_accept(cSSL);
if(ssl_err <= 0) {
printf("connection failed\n");
shutdownssl();
}
else
printf("connected\n");
return 0;
}
Now I know it is missing some obvious things such as writing my own initssl (I am unsure why that isn't already in the lib, but I am starting to see why OpenBSD decided to fork). I left those out as I am more interested in this working with LibreSSL and don't believe you need them with LibreSSL. I tried using print statements to debug but they never get printed even when given at the top of main(). I am unsure why this isn't working and need some help getting this ported. The other files I wrote, repos.h and resolv.c can be seen below:
/* repos.h */
char DEFAULT_HOST[11] = "gitlab.com";
char DEFAULT_PAGE[24] = "Puffles_the_Dragon/core";
/* resolv.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h>
short resolv(char *host, char *ip)
{
struct hostent *hp = calloc(1, sizeof(struct hostent));
hp = gethostbyname(host);
if (hp == NULL) {
fprintf(stderr, "gethostbyname() failed\n");
exit(1);
}
else {
short i = 0;
while (hp->h_addr_list[i] != NULL) {
inet_ntoa(*(struct in_addr *)(hp->h_addr_list[i]));
i++;
}
strlcpy(ip, inet_ntoa(*(struct in_addr *)(hp->h_addr_list[0])), 16);
}
return 0;
}
I know some of these calls are outdated due to IPv6, but I am going to add for IPv6 after I get this all working and port from BSD libc to musl libc.
I expected the HTTPS code to run and connect to the server thus printing connected, but it just runs and doesn't fail or print anything.

C programming having trouble creating files in Linux

I'm programming a simple Load Balancer as part of a course, and in order to inform the servers and browser of the ports I bind to, I save them as a simple file in the same directory, which they can then read. The issue is that even though both ports i'm creating are using the same function, one of the files is not being created. I've gone over the code over and over and I cannot find the issue.
Basically, only the file http_port is being created.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include "LB.h"
int main() {
srand(time(NULL));
int i, server_socket, http_socket, client_socket, servers[3];
char *server_port = "server_port", *http_port = "http_port";
http_socket = Get_Socket(http_port);
server_socket = Get_Socket(server_port); //continues to load balancer
//inside functions.c
int Get_Socket(char* filename)
{
int port, bind_state = -1;
int new_socket;
struct sockaddr_in socket_address;
socket_address.sin_family = AF_INET;
socket_address.sin_addr.s_addr = INADDR_ANY;
do
{
port = get_random_port(PORT_MIN, PORT_MAX);
socket_address.sin_port = htons(port);
new_socket = socket(AF_INET, SOCK_STREAM, 0);
bind_state = bind(new_socket, (struct sockaddr*) &socket_address, sizeof(socket_address));
} while (bind_state < 0);
Write_Port2File(filename, port);
return new_socket;
}
void Write_Port2File(char* filename, int port)
{
printf("%s", filename);
FILE* fp = fopen(filename, "w");
if (fp == NULL)
exit(1);
fprintf(fp, "%d", port);
fclose(fp);
}
I'd appreciate any and all advice you can provide towards solving this issue.
P.S. It seems the problem only occurs after I enable the permissions for the folder with chmod 755 * and chmod 777 . (which is part of the course requirements).
Thank you in advance.

C / Linux - How to connect and read the answer of a mail server like gmail or outlook with sockets?

I would like to connect to a mail server to read the mail. For example, I have an outlook address toto#outlook.com, and I want to get all the mail of this mailbox and be able to read it. So I believe I only have to do a client, but : How do I contact and connect to this type of servers, and how do I listen the answer?
Here is my current client code :
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
int main()
{
struct protoent *pe;
int fd_client;
struct sockaddr_in s_in;
int port;
char *ip;
char buff[4096];
ip = strdup("157.56.242.251"); // I get it while calling "ping outlook.com"
port = 210;
pe = getprotobyname("TCP");
fd_client = socket(AF_INET, SOCK_STREAM, pe->p_proto);
s_in.sin_family = AF_INET;
s_in.sin_port = htons(port);
s_in.sin_addr.s_addr = inet_addr(ip);
if (connect(fd_client, (struct sockaddr *)&s_in, sizeof(s_in)) == -1)
{
if (close(fd_client) == -1)
return (-1);
fprintf(stderr, "Failed to connect\n");
return (-1);
}
//From here I don't know what to do, so I tried this
recv(fd_client, buff, 4096, 0);
printf("%s\n",buff);
write(fd_client, "Hello !\n", strlen("Hello !\n"));
//To Here
if (close(fd_client) == -1)
return (-1);
return (0);
}
Thanks in advance.

SIGPIPE error in a TCP based Concurrent Echo Cleint-Sever

I am new to network programming, and have been learning this by writing small programs that make use of the Socket API. Currently, I am writing a simple echo server, that uses fork to create a copy of it, as soon as it gets a connect request, this adds up as in improvement over the previous Iterative server (here). However, after I start the server and fire up the client, and type a message on its console, it quits unexpectedly. Running the program under Gdb shows that SIGPIPE was delivered. But as far as I know as the socket is still valid, a SIGPIPE shouldn't have occured. Any kind of help involved is appreciated.
Here is the client code
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#define MAXCOUNT 1024
int main(int argc, char* argv[])
{
int sfd,i;
struct sockaddr_in saddr;
char buff[MAXCOUNT];
char mesg[MAXCOUNT];
sfd = socket(AF_INET,SOCK_STREAM,0);
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr);
saddr.sin_port = htons(5008);
connect(sfd,(struct sockaddr*) &saddr,sizeof(saddr));
fgets(buff,MAXCOUNT,stdin);
send(sfd,buff,strlen(buff),0);
if (recv(sfd,mesg,MAXCOUNT,0) == -1) {
perror("Nothing to read\n");
exit(1);
}
printf("%s\n",mesg);
exit(0);
}
Here is the server code
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#define MAXCOUNT 1024
int main(int argc, char* argv[])
{
int sfd,nsfd,cn;
pid_t c;
char buf[MAXCOUNT];
socklen_t clen;
struct sockaddr_in caddr,saddr;
sfd = socket(AF_INET,SOCK_STREAM,0);
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
saddr.sin_port = htons(5008);
bind(sfd,(struct sockaddr*) &saddr,0);
listen(sfd,2);
for (; ;) {
clen = sizeof(caddr);
nsfd = accept(sfd,(struct sockaddr*) &caddr, &clen);
if( (c = fork()) == 0) {
close(sfd);
memset(buf,0,sizeof(buf));
cn = recv(nsfd,buf,sizeof(buf),0);
if ( cn == 0) {
perror("Reading from the client socket failed\n PROGRAM CRASH :\n");
exit(1);
}
buf[cn] = '\0';
send(nsfd,buf,strlen(buf),0);
close(nsfd);
exit(0);
}
}
return 0;
}
send(sfd,buff,strlen(buff),0);
if (recv(sfd,mesg,MAXCOUNT,0) == -1) {
perror("Nothing to read\n");
exit(1);
}
printf("%s\n",mesg);
The %s format specifier is for C-style strings, not arbitrary data. And since you throw away the return value from recv, you have no way to know how many bytes you got.
Your client also doesn't shut down the socket gracefully or make sure it has received all the data the server may send. So it's possible that you're triggering an abnormal termination. The server closes the connection when it's done sending, so the client should keep trying to receive until it detects that the connection has closed.

Get list of devices on LAN in C

I'd like to get a list of available devices (their IP address or hostname should be fine) connected to my local network. I've got some examples in C#, but I couldn't find any sample using C/C++. I'm familiar with the BSD socket API, just to clarify.
I have a "stub" kind of idea: maybe I should determine the range of the IP addresses that the devices on my LAN can potentially belong to, and then determine if they e. g. respond to PING, or something like that. How could I achieve these?
I want my application to run on Linux and iOS. That's why I'd prefer BSD sockets, or at a maximum, Foundation/GNUstep (although they are written in Objective-C).
You can also e.g. send an ICMP echo request packet to 224.0.0.1. This is a special all-nodes multicast address every node should respond to (except if a firewall rule or network policy setting prevents it).
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/ip_icmp.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
// Define the Packet Constants
// ping packet size
#define PING_PKT_S 64
// Automatic port number
#define PORT_NO 0
// Automatic port number
#define PING_SLEEP_RATE 1000000
// Gives the timeout delay for receiving packets
// in seconds
#define RECV_TIMEOUT 1
// Performs a DNS lookup
char *dns_lookup(char *addr_host, struct sockaddr_in *addr_con)
{
//printf("\nResolving DNS..\n");
struct hostent *host_entity;
char *ip=(char*)malloc(NI_MAXHOST*sizeof(char));
int i;
if ((host_entity = gethostbyname(addr_host)) == NULL)
{
// No ip found for hostname
return NULL;
}
//filling up address structure
strcpy(ip, inet_ntoa(*(struct in_addr *)
host_entity->h_addr));
(*addr_con).sin_family = host_entity->h_addrtype;
(*addr_con).sin_port = htons (PORT_NO);
(*addr_con).sin_addr.s_addr = *(long*)host_entity->h_addr;
return ip;
}
// Resolves the reverse lookup of the hostname
char* reverse_dns_lookup(char *ip_addr)
{
struct sockaddr_in temp_addr;
socklen_t len;
char buf[NI_MAXHOST], *ret_buf;
temp_addr.sin_family = AF_INET;
temp_addr.sin_addr.s_addr = inet_addr(ip_addr);
len = sizeof(struct sockaddr_in);
if (getnameinfo((struct sockaddr *) &temp_addr, len, buf,
sizeof(buf), NULL, 0, NI_NAMEREQD))
{
//printf("Could not resolve reverse lookup of hostname\n");
return NULL;
}
ret_buf = (char*)malloc((strlen(buf) +1)*sizeof(char) );
strcpy(ret_buf, buf);
return ret_buf;
}
// Driver Code
int main(int argc, char *argv[])
{
int sockfd;
char *ip_addr, *reverse_hostname;
struct sockaddr_in addr_con;
int addrlen = sizeof(addr_con);
char net_buf[NI_MAXHOST];
int i=0;
for(int i=1;i<255;++i)
{
char ip[80];
sprintf(ip, "192.168.2.%d", i);
ip_addr = dns_lookup(ip, &addr_con);
if(ip_addr==NULL)
{
//printf("\nDNS lookup failed! Could not resolve hostname!\n");
continue;
}
reverse_hostname = reverse_dns_lookup(ip_addr);
if(reverse_hostname==NULL)
{
//printf("\nDNS lookup failed! Could not resolve hostname!\n");
continue;
}
//printf("\nTrying to connect to '%s' IP: %s\n",ip, ip_addr);
printf("\nReverse Lookup domain: %s",
reverse_hostname);
printf("\n %s \n", ip);
}
return 0;
}

Resources