Following code is TCP server program just send back “HELLO!!” to client.
When I run server with port 80, bind() is returned Permission denied.
Port 12345 is OK.
How can I use port 80 for this server program?
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int
main(){
int sock0;
struct sockaddr_in addr;
struct sockaddr_in client;
int len;
int sock;
char *message;
message = "HELLO !!";
sock0 = socket(AF_INET,SOCK_STREAM,0);
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
inet_pton(AF_INET,"127.0.0.1",&addr,sizeof(addr));
bind(sock0,(struct sockaddr *)&addr,sizeof(addr));
perror("bind");
len = sizeof(client);
sock = accept(sock0,(struct sockaddr *)&client,&len);
perror("accept");
write(sock,message,sizeof(message));
perror("write");
close(sock);
return 0;
}
Ports below 1024 are considered "privileged" and can only be bound to with an equally privileged user (read: root).
Anything above and including 1024 is "free to use" by anyone.
OT: you may know this already, but the port in your example is that for HTTP web servers. Anything listening to this port should speak HTTP, too. A simple "hello world" does not suffice. ;-)
Only the root user is allowed to bind to ports <= 1024. Every ports > 1024 can be bound to by normal users.
Try executing your program as root or with sudo.
you have to run your application with super user account (root)
Run your application with sudo command
Related
I suspect this has an easy solution I'm overlooking, probably to do with the client or how this is set up.
Anyways, I'm trying to set up a simple Echo server/client to understand the basics of socket programming. I have a virtual machine running Linux Mint, and the host is running Windows 10. The virtual machine I am setting to run the server c code, and the Windows will be running the client.
I started off making the server code
//Echo Server for UNIX: Using socket programming in C, a client sends a string
//to this server, and the server responds with the same string sent back to the client
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
int main()
{
char stringBuffer[50]; //string buffer for reading incoming and resending
int listener, communicator, c; //store values returned by socket system call
if((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) //creates a new socket
puts("Could not create socket");
puts("Socket Created");
struct sockaddr_in servAddr, client; //structure from <netinet/in.h> for address of server
servAddr.sin_family = AF_INET; //addressing scheme set to IP
servAddr.sin_port = htons(8888); //server listens to port 5000
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //symbolic constant of server IP address
//binds the socket to the address of the current host and port# the server will run on
if (bind(listener, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0){
puts("Bind failed");
return 1;
}
puts("Bind Successful");
listen(listener, 5); //listens for up to 5 connections at a time
c = sizeof(struct sockaddr_in);
if ((communicator = accept(listener, (struct sockaddr*)&client, (socklen_t*)&c ))<0)
puts("accept failed");
puts("Connection Accepted");
//wait until someone wants to connect, then whatever is sent can be read from communicator, which can then be sent back
while(1){
bzero(stringBuffer, 50); //sets buffer to 0
read(communicator, stringBuffer, 50); //reads from communicator into buffer
write(communicator, stringBuffer, strlen(stringBuffer)+1); //returns back
}
return 0;
}
after that I tested it out by opening another terminal in the guest machine and typed "telnet localhost 8888" and input whatever strings I wanted.
This test worked so now, onto my Windows machine to create the client side of the socket programming:
#include <winsock.h>
#include <stdio.h>
#include <string.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
int main(int argc, char *argv[])
{
WSADATA wsadata; //variable for using sockets in windows
SOCKET sock; //socket variable for network commands
char sendString[50], recieveString[50]; //variables for sending and recieving messages to/from server
//check if WSA initialises correctly
if (WSAStartup(MAKEWORD(2,2), &wsadata) != 0)
printf("Error Code: %d", WSAGetLastError());
//creates new socket and saves into sock
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
printf("Could not create socket: %d", WSAGetLastError());
printf("Socket created\n");
struct sockaddr_in servAddr;
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //sets the IP address to the same machine as the server
servAddr.sin_family = AF_INET; //addressing scheme set to TCP/IP
servAddr.sin_port = htons(8888); //server address is on port 8888
//connects to device with specifications from servAddr
if (connect(sock, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) {
printf("Connection Error %d\n", WSAGetLastError());
return 1;
}
printf("Connection Accepted\n");
while(1){
fgets(sendString, 50, stdin); //uses stdin to get input to put into sendString
//sends sendString to server using sock's properties
if (send(sock, sendString, strlen(sendString) + 1, 0) < 0); {
printf("Send Failed");
return 0;
}
//reads from server into recieveString
if ((recv(sock, recieveString, 50, 0)) == SOCKET_ERROR)
printf("Recieve Failed");
printf("%s", recieveString); //prints out recieveString
}
}
Now, with the server still running, when I try out the client-side, I get the response "Connection Error" (from line 35). Having looked at both Unix and WinSock examples, I'm unsure as to why I would be failing the connection. I suspect it might have something to do with a windows to linux VM but I'm not sure.
---UPDATE---
Having updated the accidental semicolon and added the WSAGetLastError, it's showing an error code of 10061; This translates to
"Connection refused.
No connection could be made because the target computer actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host—that is, one with no server application running."
[after the 3rd edit:]
Sry, just re-read your question. The important thing is here:
The virtual machine I am setting to run the server c code, and the Windows will be running the client.
127.0.0.1 is an address always only local to an IP enabled box. So you your server is listening on the interface 127.0.0.1 local to the Linux VM and the client tries to connect to 127.0.0.0 local to the Windows box. Those two interfaces are not the same. The result is the obvious, namely the client does not find anything to connect to.
127.0.0.1 (the so called "IPv4 local loopback interface") can only be used for connections local to exactly one box.
if (connect(sock, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0); {
printf("Connection Error");
return 1;
}
This is just a trivial syntax mistake. You are entering the block unconditionally. Remove the first semicolon.
However there is a much more important point to be made. When you get an error from a system call such as connect(), you must print the error. Not just some message of your own devising. Otherwise you don't know whether you simply have a bug, or a temporary problem, or a long-lasting problem, or a permanent problem.
Change the printf() to:
printf("Connect error %s\n", WSAGetLastError());
and then don't continue as though the error didn't happen.
Note that this applies to all system calls, specifically including socket(), bind(), listen(), connect(), accept(), recv(), send(), and friends.
I am trying to send an array of objects to my C++ client using the code below. I originally was trying to do so with just the http library alone in which i further investigated and found this out to be not correct approach.
What i'm not clear with this is how socket.write("hello C++ client") will allow me to send this string and have it appear in my terminal C++ but using socket.emit("arrayTransfer", arrayOfObjects); or a similar variation of what i'm trying below will not allow me to receive anything, I have tried different variations of sending the array of objects but have not succeeded can someone help me understand what exactly may be going on in this code and how Nodejs handles these types of sockets?
thank you.
Here is my questions I asked before to gain a better understanding perhaps.
NodeJs server and C++ client
var server = require("net").createServer();
var io = require("socket.io")(server);
socket.emit("message", myArray[0].name);
};
io.on("connection", handleClient);
server.listen(8080);
C++ CLIENT CODE BELOW
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define LENGTH (512)
#include <errno.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#define PORT_NUMBER (8080) // port number where to port in application
int clientSocket;
char buffer[LENGTH];
struct sockaddr_in serverAddr;
socklen_t addr_size;
int main()
{
/*---- Create the socket. The three arguments are: ----*/
/* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */
clientSocket = socket(PF_INET, SOCK_STREAM, 0);
/*---- Configure settings of the server address struct ----*/
/* Address family = Internet */
serverAddr.sin_family = AF_INET;
/* Set port number, using htons function to use proper byte order */
serverAddr.sin_port = htons(PORT_NUMBER);
/* Set IP address to localhost */
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
/* Set all bits of the padding field to 0 */
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
/*---- Connect the socket to the server using the address struct ----*/
addr_size = sizeof serverAddr;
connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);
/*---- Read the message from the server into the buffer ----*/
recv(clientSocket, buffer, 1024, 0);
printf("This is your message %s", buffer);
close(clientSocket);
return 0;
}
I'm writing a very small C UDP client. I know that a random port is chosen as source port when you send data to the server. I also know that you can use bind to specify yourself the port you want a response.
However, I don't know when is the port randomly chosen? For example, I would like to rely on the sender address to keep track of users. It currently works only if the client does not shutdown, the port is still the same then a simple memcmp is enough to detect the same client.
This small code will use the same source port until it exits:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
int main(void)
{
int s, error, ch;
struct addrinfo hints, *res;
memset(&hints, 0, sizeof (struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
if ((error = getaddrinfo("localhost", "9988", &hints, &res)))
errx(1, "%s", gai_strerror(error));
if ((s = socket(res->ai_family, res->ai_socktype, 0)) < 0)
err(1, "socket");
while ((ch = fgetc(stdin)) != EOF)
sendto(s, &ch, 1, 0, res->ai_addr, res->ai_addrlen);
}
And running something like : dmesg | ./client will use the same address until the program exits. However, when you run it again, the port is different.
So is it the socket function that choose a port? Or the system? Is it sure that the port will still be the same during the client lifetime?
If the socket is not explicitly bound, then the OS will bind it (with a random port) when you send the first packet. This binding will be active as long as the socket is open, once it's closed the socket is (of course) unbound.
And due to the connectionless nature of UDP sockets, the "server" (if done correctly) should not keep the address of all "clients" that send to it indefinitely. Instead it should use the source address as received in the recvfrom call, and use that for a reply. The only reason to store the source address for more than just a simple request/response, is if you have a more advanced protocol on top of UDP with your own "connection" handling.
I'm learning from the book Hacking, the Art of Exploitation by Jon Erickson, and I am confused regarding to a simple code sample that he provided. The code is to set up a simple server, but when I complied it (no error) and ran the code, it hangs
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "hacking.h"
#define PORT 7890 // the port users will be connecting to
int main(void) {
int sockfd, new_sockfd; // listen on sock_fd, new connection on new_fd
struct sockaddr_in host_addr, client_addr; // my address information
socklen_t sin_size;
int recv_length=1, yes=1;
char buffer[1024];
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
fatal("in socket");
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
fatal("setting socket option SO_REUSEADDR");
host_addr.sin_family = AF_INET; // host byte order
host_addr.sin_port = htons(PORT); // short, network byte order
host_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(&(host_addr.sin_zero), '\0', 8); // zero the rest of the struct
if (bind(sockfd, (struct sockaddr *)&host_addr, sizeof(struct sockaddr)) == -1)
fatal("binding to socket");
if (listen(sockfd, 5) == -1)
fatal("listening on socket");
while(1) { // Accept loop
sin_size = sizeof(struct sockaddr_in);
new_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size);
if(new_sockfd == -1)
fatal("accepting connection");
printf("server: got connection from %s port %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
send(new_sockfd, "Hello World!\n", 13, 0);
recv_length = recv(new_sockfd, &buffer, 1024, 0);
while(recv_length > 0) {
printf("RECV: %d bytes\n", recv_length);
dump(buffer, recv_length);
recv_length = recv(new_sockfd, &buffer, 1024, 0);
}
close(new_sockfd);
}
return 0;
}
I did a little printf() to find out where I hangs, and it turns out to be on this line
sin_size = sizeof(struct sockaddr_in);
I'm not sure if it has to do with my environment, or there is something that I am missing. The environment that the book uses can no longer be updated (some old verson of Ubuntu). So I am currently using the latest one.
Can someone please explain to me why the program does not work?
And if there is some basic that need to know before learning the network chapter, please do tell.
This program won't proceed until accept on the line after the sizeof receives an incoming connection from a client program. Your printf shows that accept was called but was blocked.
You need to compile and run the client with the right options (IP / Port) to connect to this server program.
Update
If 192.168.42.248 is from the book, then you're probably trying to connect to the wrong IP. Try telnet 127.0.0.1 7890.
It's a server, it will "hang" until you make a connection to port 7890. That's the whole point of the program (for more detais, it blocks since accept() is waiting for a connection)
Assuming you are running unix, try to type echo "hi there" | nc localhost 7890 in a terminal from the same machine while you run it, and you will see how it "unblocks"
Telling by all the comments flying around in your thread I'd recommend to connect with telnet using the following command line: telnet localhost 7890
telnet takes as arguments the host to connect to and the port to connect to on this host. Using "localhost" is similar to using the loopback IP 127.0.0.1.
Why does connecting to the server solve the "hang"? accept is blocking as you can read in the man page or any other documentation of your programming environment. This means the function won't return until a client connects. After connecting the function returns a handle to the socket created for the connecting client which can be used to communicate.
I'd like to authenticate on ssh-server via BSD socket. I know how to initiate a connection but don't know how to actually authenticate. Thanks for your time when pointing me to the right direction.
Here is the source code:
//
#include <stdio.h> // printf()
#include <sys/types.h> // socket data types
#include <sys/socket.h> // socket(), connect(), send(), recv()
#include <arpa/inet.h> // sockaddr_in, inet_addr()
#include <stdlib.h> // free()
#include <unistd.h> // close()
int *ssh(char *host, int port, char *user, char *pass);
int main(void)
{
// create socket
int *ssh_socket = ssh("127.0.0.1", 22, "root", "password");
// close and free
close(*ssh_socket);
free(ssh_socket);
return 0;
}
int *ssh(char *host, int port, char *user, char *pass)
{
int *sock = calloc(sizeof(int), 1);
struct sockaddr_in addr = {.sin_family=AF_INET, \
.sin_port=htons(port), \
.sin_addr.s_addr=inet_addr(host)};
*sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // create socket
connect(*sock, (struct sockaddr *)&addr, sizeof(addr)); // init connection
// here is the problem
// how do I authenticate on this socket?
return sock;
}
Use libssh for adding SSH functionality to your program.
SSH is a quite complex protocol with several layers.
Before getting to the user authentication you have to initiate the protocol, check remote host credentials and start an encrypted connection.
And after that, there are several ways to authenticate an user you may want to support (public key, passwd, keyboard-interactive, etc.).
The Wikipedia page for SSH has links to all the related RFCs.
Really, use libssh or libssh2 or the code from OpenSSH!