Autor: Sefer | Publicado: 2006-03-09T22:36:00-05:00

#include "stdio.h"#include "stdlib.h"#include "unistd.h"#include "netdb.h"#include "arpa/inet.h"#include "netinet/ip.h"#include "netinet/tcp.h"#include "netinet/in.h"#include "sys/socket.h"#include "sys/types.h"#include "sys/select.h"#include "sys/time.h"#define TCPHDRSZ sizeof(struct tcphdr)#define IPHDRSZ sizeof(struct iphdr)#define LOCALHOST 127.0.0.1struct card {        char *saddr;        char *daddr;        char *data;        int sport;        int dport;        };// N necessita de nenhum argumento gera um socket af_inet, stream, ip.int GenStreamSocket();// Requer uma o ponteiro para uma struct card previamente preenchida.char *GenSynPacket(struct card *c);// N necessita de nenhum argumento gera um socket af_inet, raw, ip.int GenRawSocket();// Requer um socket previamente conectado, um ponteiro para o buffer a ser enviado, e o tamanho do buffer.int SendAll(int socketfd, char *buffer, int tamanho);// Requer um socket previamente conectado, um ponteiro para o buffer a recebido, e o tamanho m\uffffximo da recep\uffff\uffffoint Recv(int socketfd, char *buffer, int tamanho);// Requer a familia do socket, tipo do socket, e dominio(ip, :P)int Socket(int family, int type);// Conecta um socket necessitando de uma estrutura sockaddr_inint Connect(int sockfd, struct sockaddr_in server, size_t tamanho);// Bind() um socket necessitando de uma estrutura sockaddr_inint Bind(int sockfd, struct sockaddr_in server);// Listen() a socket with a backlogint Listen(int sock, int backlog);//Executa perror() depois saivoid Die(char *msg);// Executa herror() depois saivoid Dieh(char *msg);// Resolve um determinado nome e retorna uma estrutura in_addrstruct in_addr GetSinAddr(char *name);// Utilizando read(), le do socket "size" dados e retorna o numero de bytes lidosint GetData(int sock, char *buff, int size);//Utilizando select(), espera at'e que dados estejam disponiveis em sock, entao le com read data, senao retorna -1int GetDataT(int sock, char *buff, int size, int timeout);// Utilizando write(), escreve em socket "size" dados e retorna o numero de bytes escritosint PutData(int sock, char *buff, int size);// connect to a server using a tcp sockstream connection, *name = server, port = port we want to connectint GetConn(char *name, int port);unsigned short in_cksum(unsigned short *addr, int len)        {        register int sum = 0;        u_short answer = 0;        register u_short *w = addr;        register int nleft = len;        while (nleft > 1)        {        sum += *w++;        nleft -= 2;        }        if (nleft == 1)        {        *(u_char *) (&answer) = *(u_char *) w;        sum += answer;        }        sum = (sum >> 16) + (sum & 0xffff);        sum += (sum >> 16);        answer = ~sum;        return (answer);        }void Die(char *msg)        {        perror(msg);        exit(1);        }void Dieh(char *msg)        {        herror(msg);        exit(1);        }// No need of any arguments, generates a pure Stream Socket for ip networksint GenStreamSocket()        {        int sock;        sock = Socket(AF_INET, SOCK_STREAM);        if(sock < 0) Die("Socket");        return sock;        }// Incluir a op\uffff\uffffo de campo data.char *GenSynPacket(struct card *c)        {        char *packet;        struct tcphdr *tcp;        struct iphdr *ip;        packet = malloc(IPHDRSZ+TCPHDRSZ);        if(packet == NULL)                {                printf("GenSocket(): malloc(packet)\n");                return NULL;                }        ip = (struct iphdr *)packet;        tcp = (struct tcphdr *)(packet + IPHDRSZ);        ip->version = 4;        ip->tot_len = IPHDRSZ + TCPHDRSZ;        ip->ttl = 128;        ip->id = htons(654);        ip->protocol = IPPROTO_TCP;        ip->saddr = inet_addr(c->saddr);        ip->daddr = inet_addr(c->daddr);        ip->ihl = 5;        ip->check = in_cksum((unsigned short *)ip, IPHDRSZ);        tcp->source = htons(c->sport);        tcp->dest = htons(c->dport);        tcp->seq = htonl(321);        tcp->ack_seq = htonl(0);        tcp->doff = 5;        tcp->fin = 0;        tcp->syn = 1;        tcp->ack = 0;        tcp->rst = 0;        tcp->psh = 0;        tcp->window = htonl(4000);        tcp->check = in_cksum((unsigned short *)&tcp, IPHDRSZ+TCPHDRSZ);        return packet;        }int GenRawSocket()        {        int sock;        int set=1;// Setting        sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);        if(sock < 0) Die("GenRawSocket()");        if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &set, sizeof(int)) < 0) Die("GenRawSocket - setsockopt:");        return sock;        }int SendAll(int socketfd, char *buffer, int tamanho)        {        int total = 0;        int resto = tamanho;        int n;        while(total < tamanho)                {                n = send(socketfd, buffer, resto, 0);                if(n==-1)                        {                        break;                        }                total += n;                resto -= n;                }        tamanho = total;        return n==-1?-1:0;        }int Recv(int socketfd, char *buffer, int tamanho)        {        int received=0;        received = recv(socketfd, buffer, tamanho, 0);        if(received == -1) Die("Recv - recv()");        return received;        }int Socket(int family, int type)        {        int error=0;        error = socket(AF_INET, SOCK_STREAM, 0);        if (error < 0) Die("Socket - socket()");        return error;        }int Connect(int sockfd, struct sockaddr_in server, size_t tamanho)        {        int error=0;        if ((error = connect(sockfd, (struct sockaddr *)&server, tamanho)) == -1) Die("Connect - connect()");        return error;        }int Bind(int sockfd, struct sockaddr_in server)        {        int error=0;        if ((error = bind(sockfd, (struct sockaddr *)&server, sizeof(struct sockaddr))) == -1) Die("Bind - bind()");        return error;        }int Listen(int sock, int backlog)        {        int error=0;        if((error == listen(sock, backlog)) == -1) Die("Listen - listen()");        return error;        }struct in_addr GetSinAddr(char *name)        {        struct hostent *h;        struct in_addr *in;        if(!(h = gethostbyname(name))) Dieh("GetSinAddr");        in = (struct in_addr *)h->h_addr;        return *in;        }int GetData(int sock, char *buff, int size)        {        int len;        len = read(sock,buff,size);        if(len == -1) Die("GetData - read()");        return len;        }int GetDataT(int sock, char *buff, int size, int timeout)        {        int retval;        int len;        fd_set rfd;        struct timeval tv;        FD_ZERO(&rfd);        FD_SET(sock, &rfd);        tv.tv_sec = timeout;        tv.tv_usec = 0;        retval = select(sock+1,&rfd,NULL,NULL, &amp;tv);        if(retval == -1) Die("Select");        if(retval)                {                len = GetData(sock, buff, size);                return len;                }        else                {                return 0;                }        }int PutData(int sock, char *buff, int size)        {        int len;        len = write(sock, buff, size);        if(len == -1) Die("PutData - write()");        return len;        }/*ts_connect() stands for TCP Socket STREAM Conectionit creates a socket of the family AF_INET and connect() it to the *name*/int GetConn(char *name, int port)        {        int sock;        struct sockaddr_in server;        server.sin_family = AF_INET;        server.sin_port = htons(port);        server.sin_addr = GetSinAddr(name);        sock = GenStreamSocket();        Connect(sock, server, sizeof(struct sockaddr));        return sock;        }void CloseConn(int sock)        {        if(close(sock) == -1) Die("close");        }