Error in system command traceroute c - c

I'm trying to develop a traceroute server which accepts argument from a telnet client performs traceroute and send the information back to the telnet client. I'm receiving the argument from telnet client at the server for e.g. traceroute www.google.com but somehow when I try to execute it, it gives me a weird error:
: Name or service not known
' on position 1 (argc 1)line arg `www.google.com
What I found strange is when I hard code the command at the server end it works fine, also when I receive the command at the server end and print it out, that works fine too. However, the same command received in a character array it fails to execute with the above error.
Here's my code:
int main() {
int sockfd,new_fd;
char client_arg[100];
//Create a socket and establish the connection
if (recv(new_fd,client_arg,100,0)== -1)
perror("recv");
printf("%s\n",client_arg); // prints traceroute www.google.com
system(client_arg);
return 0;
}

Many things could be wrong here:
traceroute might not be in the default PATH of /bin/sh,
the string might not be zero-terminated,
the buffer might have some unprintable characters that printf would not show to you,
you might receive a short read with partial command,
anything else ...
It is a very Bad IdeaTM to blindly pass user (or network) input for execution like that. Do explicit checking. Pass only allowed commands. Check correctness of the arguments.

Related

Execute shell command from C environment and redirect output

I have seen there are some questions about this topic, but none of the answers satisfied me. Here is the problem: I need to write two sockets (client and server), with the client having to send to the server an awk program with some lines of input. No problem in sending strings back and forth between the sockets. Supposing I have stored the program in a string command and the string I should pass to it in input, I have tried this:
execl("/usr/bin/awk", command, input, (char *)0);
And this works, the awk program runs and it writes on the server's stdout and stderr. Thing is, if there are lines with errors, I need to send these back to the client, which is pretty impossible since execl doesn't give me the chance to store its output in arrays. So, does anybody know a way to do this without using system and popen?

python socket difference noted on shell and code in file

I'm trying to build a python client to interact with my C server. Here's the code for the client:
import socket
s = socket.socket()
s.connect(("127.0.0.1", 12209))
print "preparing to send"
s.send("2")
s.send("mmm2.com")
s.send("mypwd")
s.send("5120")
print "Sent data"
root = s.recv(256)
print root
When I run this code on the interactive shell (the GUI IDLE) of course line by line, everything runs very fine. But when i save this code in a file and try to run it, it hangs and stops responding according to windows, what's it that I'm just not doing?
If you type it line by line, the sent strings are likely received by the server one after another in separate recv() calls.
When you execute it in a script, all the send() calls run immediately after each other without delay and the server will probably receive all the data in one bulk in a single recv() call. So the server will see "2mmm2.commypwd5120", and maybe not handle that correctly. It might wait for more input from the client.
You will need some explicit separation between the values, for example newline characters, so that the server can parse the received data correctly.

FTP server return code: How to connect with a host using my own TCP server and Linux built-in client

In Linux there is a built-in ftp server/client. If you go to the terminal and type "ftp localhost" (Without quotations) there is an immediate connection to the local host with a FTP server return code 220. Then you are asked to input the host's name and password (331). I'm trying to implement my own FTP server to do the exact same thing. As soon as the client receives localhost and port, it must ask for host's name and password, but as soon as I write the password my program just hangs. This is my code to handle the user/password issue:
char login_user[BUFSIZ], login_password[BUFSIZ];
send(sock, "220\r\n", 5, 0);
recv(sock, login_user, BUFSIZ);
send(sock, "331\r\n", 5, 0);
recv(sock, login_password, BUFSIZ, 0);
int x = strncmp(login_user, login_password, BUFSIZ);
if(x == 0)
{
send(sock, "230\r\n", 5, 0);
}
For a connection to be successful both host name and password must be the same. Sending the FTP server code 230 should establish a connection like it does when using the FTP built-in server. However my program just stops and hangs until I press Ctrl+Z. What am I doing wrong?
I assume it's because the FTP client does not receive the 230 response.
The recv command does not magically wait for the "username" sent by the client. It's not aware of what a piece of data (or line) looks like in the protocol you are implementing. So it does not know it has to wait and stop on the "new line". You have to implement that on your own.
Depending on whether the connection is set as blocking or not, the code you have can either:
not read anything from the socket at all, on either recv calls, never entering the if block.
can read both username and password in the first recv call (the client likely sends both at once, possibly in a single TCP/IP packet).
You have to real read a lot about sockets before endeavoring in implementing something as complex as FTP server is.
What you receive in login_user is not just the name, but the FTP access control command USER …\r\n, and what you receive in login_password is not just the password, but the FTP access control command PASS …\r\n; so the strncmp(login_user, login_password, BUFSIZ) will never return 0 (a fortiori since the strings are not '\0'-terminated) and the 230\r\n will never be sent.

Displaying terminal output of shell on client

I have 2 files Client Side & Server Side
I send a string over the socket from client to server. I have to execute this string as one does in a terminal. The output of the command is to be displayed on the client side.
Server Side Code : this loop runs on each thread created by pthread_create
while((n=recv(sock,client_message,2000,0))>0)
{
send(sock,server_out,n,0);
}
I need to run the string i recieve in client_message as a terminal command and fetch the output of the command and send it back via the server_out string buffer.
How do i go about this ?
So - you have two or three different tasks to accomplish.
The first one is to run the command line you received on the server. For that, you can start reading the system() function. It's very straightforward to use.
But then you need to get it's output. You can read about this two points in this question.
Lastly, send that data back to the server - once you have the output stream, it's just send()ing that via the socket. You can implement some mini-protocol for telling the other side how many bytes to expect, some error detection/correction if you want, etc.
Once the data arrives the client, then you can do whatever you want with it - print it on the screen, save to a file, you name it.
Read about this things, take your chances, and come back to continue asking if you need it - good luck!

Linux C TCP Socket client/server with redirected output application

Let me start out by saying that this is a homework assignment for an operating systems class and I am not a programmer, especially not in C. I've been at this for a week now and I am simply stuck and I need help. I have to create TCP client and server applications where linux commands are typed into the client, executed on the server and the output is redirected back to the client. I understand the concept and I have it 90+% working. Commands like "ls", "ls -lpq", "cat somefile", "man somecommand" all work fine. Where I run into trouble is with commands that do not return any information like "mkdir newdir" (if the directory already exists it works fine because I get a response). This is all new to me but it seems to me that my problem is with the servers recv command blocking because there is no information to receive. I don't know how to get past this, I have been working this one issue for a week. I'm running out of time and I also have to implement file upload and download and I don't know where to begin there but I can't even start to work on that until I get past this issue.
Thanks
// this is where I think the problem is
while ((rcvd_bytes = recv(sock_fd, recv_str, sizeof(recv_str), 0)) > 0 ) {
// Zero out the inputCopy buffer
memset(&inputCopy, 0, sizeof(inputCopy)+1);
// Copy the recv_str into a new string so that
// we can work with it.
strcpy(inputCopy, recv_str);
argcount = parsecommand(inputCopy, args);
//Send the message back to client
dup2(sock_fd, 1);
if((status = forkAndExecute(args)) != 0) {
//printf("Command %s returned %d.\n", args[0], status);
}
// as a test is I uncomment the following line mkdir newdir
// returns but the following commands are messed up - as I expect.
//printf("\n");
memset(&recv_str, 0, sizeof(recv_str)+1);
fflush(stdout);
}
if(rcvd_bytes == 0) {
puts("Client disconnected");
fflush(stdout);
}
else if(rcvd_bytes == -1) {
perror("recv failed");
exit(0);
}
Sounds like you need to use select .
if(select(fdmax+1, &my_fdset, 0, 0, NULL) > 0) // there is data available to be read
recv(...)
where fdmax is the largest file descriptor (select wants that +1) and my_fdset is a file descriptor set that you add file descriptors to using FD_SET(sockfd, &my_fdset);.
This will only receive when there is data available. Hope that helps.
EDIT :
I asked a similar question when I was writing a simple client/server program to send/recv strings over a TCP socket. I posted the code that I ended up using on that thread here. Mine is different in that I wanted one program to send and recv but if you look at my sender or receiver functions, you may be able to adapt something to make your program do what you want.
Given your problem description, my suspicion is the client code rather than the server code -- or, actually, the protocol you've implicitly created between the two.
It looks like you're just sending the output of the command directly back to the client by using dup2 to point standard output at the socket. Presumably, the client then reads from the socket to get the output from the command? What does the client do when it sends a command to the server and then gets no reply? A command like mkdir will send nothing back. Is it waiting forever for the server to send command output?
In general, for a synchronous client/server protocol (one where the client sends a command and the server sends a response before the client sends another command), you have to agree on a protocol between the client and the server to clearly indicate when the server is done sending data back and the client should send its next command. You may need to add some way for the server to tell the client that the command completed but sent no output.

Resources