diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2009-09-06 15:47:08 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2009-09-06 15:47:08 (GMT) |
commit | 3173b904d5d56a8b5e6bf549c97e3fc49da6c5ba (patch) | |
tree | f5ea74177fcbc05558b85b9f2e6db36aa1ca3b86 /src/debug/remgdb/tcp.c | |
parent | ef3b996ad359e0da5e93184dab9200fad9105faf (diff) |
Provided some methods to interact with a GDB server.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@110 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/debug/remgdb/tcp.c')
-rw-r--r-- | src/debug/remgdb/tcp.c | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/src/debug/remgdb/tcp.c b/src/debug/remgdb/tcp.c new file mode 100644 index 0000000..fa97f8c --- /dev/null +++ b/src/debug/remgdb/tcp.c @@ -0,0 +1,261 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * tcp.c - gestion des connexions TCP aux serveurs GDB. + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "tcp.h" + + +#include <netdb.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/socket.h> +#include <sys/types.h> + + +#include "stream-int.h" + + + +/* Flux de communication TCP avec un serveur GDB (instance) */ +struct _GGdbTcpClient +{ + GGdbStream parent; /* A laisser en premier */ + +}; + + +/* Flux de communication TCP avec un serveur GDB (classe) */ +struct _GGdbTcpClientClass +{ + GGdbStreamClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des flux de communication TCP avec GDB. */ +static void g_gdb_tcp_client_class_init(GGdbTcpClientClass *); + +/* Initialise une instance de flux de communication avec GDB. */ +static void g_gdb_tcp_client_init(GGdbTcpClient *); + +/* Ouvre une connexion TCP à un serveur GDB. */ +static int connect_via_tcp(const char *, const char *); + +/* Envoie des données à un serveur GDB. */ +static bool g_gdb_tcp_client_send_data(GGdbTcpClient *, const char *, size_t); + +/* Réceptionne un octet de donnée d'un serveur GDB. */ +static bool g_gdb_tcp_client_recv_byte(GGdbTcpClient *, char *); + + + +/* Indique le type défini pour un flux de communication TCP avec un serveur GDB. */ +G_DEFINE_TYPE(GGdbTcpClient, g_gdb_tcp_client, G_TYPE_GDB_STREAM); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des flux de communication TCP avec GDB. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_tcp_client_class_init(GGdbTcpClientClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : client = instance à initialiser. * +* * +* Description : Initialise une instance de flux de communication avec GDB. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_tcp_client_init(GGdbTcpClient *client) +{ + GGdbStream *stream; /* Version parente */ + + stream = G_GDB_STREAM(client); + + stream->send_data = (send_gdb_data_fc)g_gdb_tcp_client_send_data; + stream->recv_byte = (recv_gdb_byte_fc)g_gdb_tcp_client_recv_byte; + +} + + +/****************************************************************************** +* * +* Paramètres : server = nom ou adresse du serveur à contacter. * +* port = port de connexion. * +* * +* Description : Ouvre une connexion TCP à un serveur GDB. * +* * +* Retour : Flux ouvert en lecture/écriture ou -1 en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int connect_via_tcp(const char *server, const char *port) +{ + int result; /* Bilan à retourner */ + struct addrinfo hints; /* Type de connexion souhaitée */ + struct addrinfo *infos; /* Informations disponibles */ + int ret; /* Bilan d'un appel */ + struct addrinfo *iter; /* Boucle de parcours */ + struct sockaddr_in addr; /* Infos de connexion distante */ + + memset(&hints, 0, sizeof(struct addrinfo)); + + hints.ai_family = AF_UNSPEC; /* IPv4 ou IPv6 */ + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = 0; + hints.ai_protocol = 0; /* N'importe quel protocole */ + + ret = getaddrinfo(server, port, &hints, &infos); + if (ret != 0) + { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret)); + return -1; + } + + for (iter = infos; iter != NULL; iter = iter->ai_next) + { + result = socket(iter->ai_family, iter->ai_socktype, iter->ai_protocol); + if (result == -1) continue; + + ret = connect(result, iter->ai_addr, iter->ai_addrlen); + if (ret == 0) break; + + perror("connect"); + close(result); + + } + + freeaddrinfo(infos); + + if (iter == NULL) return -1; + + ret = getpeername(result, (struct sockaddr *)&addr, (socklen_t []){ sizeof(struct sockaddr_in) }); + if (ret == -1) + { + perror("getpeername"); + close(result); + return -1; + } + + printf("Connecté à %s:%hd\n", server, ntohs(addr.sin_port)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : server = nom ou adresse du serveur à contacter. * +* port = port de connexion. * +* * +* Description : Crée une nouvelle connexion TCP à un serveur GDB. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGdbStream *g_gdb_tcp_client_new(const char *server, const char *port) +{ + GGdbTcpClient *result; /* Structure à retourner */ + int sock; /* Flux ouvert à construire */ + + sock = connect_via_tcp(server, port); + if (sock == -1) return NULL; + + result = g_object_new(G_TYPE_GDB_TCP_CLIENT, NULL); + + G_GDB_STREAM(result)->fd = sock; + + if (!g_gdb_stream_listen(G_GDB_STREAM(result))) + goto ggtcn_error; + + return G_GDB_STREAM(result); + + ggtcn_error: + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : client = flux ouvert en écriture à utiliser. * +* data = données à envoyer. * +* len = quantité de ces données. * +* * +* Description : Envoie des données à un serveur GDB. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_tcp_client_send_data(GGdbTcpClient *client, const char *data, size_t len) +{ + return (send(G_GDB_STREAM(client)->fd, data, len, 0) == len); + +} + + +/****************************************************************************** +* * +* Paramètres : client = flux ouvert en lecture à utiliser. * +* data = donnée à recevoir. * +* * +* Description : Réceptionne un octet de donnée d'un serveur GDB. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_tcp_client_recv_byte(GGdbTcpClient *client, char *data) +{ + return (recv(G_GDB_STREAM(client)->fd, data, 1, 0) == 1); + +} |