summaryrefslogtreecommitdiff
path: root/plugins/gdbrsp/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gdbrsp/tcp.c')
-rw-r--r--plugins/gdbrsp/tcp.c280
1 files changed, 280 insertions, 0 deletions
diff --git a/plugins/gdbrsp/tcp.c b/plugins/gdbrsp/tcp.c
new file mode 100644
index 0000000..8458dc6
--- /dev/null
+++ b/plugins/gdbrsp/tcp.c
@@ -0,0 +1,280 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tcp.c - gestion des connexions TCP aux serveurs GDB.
+ *
+ * Copyright (C) 2009-2017 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide 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.
+ *
+ * Chrysalide 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 Chrysalide. 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"
+
+
+#include "../../common/net.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 : - *
+* *
+******************************************************************************/
+#if 0
+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;
+
+}
+#endif
+
+/******************************************************************************
+* *
+* Paramètres : server = nom ou adresse du serveur à contacter. *
+* port = port de connexion. *
+* owner = débogueur tributaire du canal de communication. *
+* *
+* 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, GGdbDebugger *owner)
+{
+ GGdbTcpClient *result; /* Structure à retourner */
+ int sock; /* Flux ouvert à construire */
+
+ sock = connect_via_tcp(server, port, NULL);
+ if (sock == -1) return NULL;
+
+ result = g_object_new(G_TYPE_GDB_TCP_CLIENT, NULL);
+
+ G_GDB_STREAM(result)->fd = sock;
+
+ G_GDB_STREAM(result)->owner = owner;
+ g_object_ref(G_OBJECT(owner));
+
+ 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)
+{
+ ssize_t sent; /* Quantité de données envoyée */
+
+ sent = send(G_GDB_STREAM(client)->fd, data, len, 0);
+
+ //printf(" sent '%s'\n", data);
+ //printf(" sent ? %d vs %d\n", (int)sent, (int)len);
+
+ return (sent == 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)
+{
+ ssize_t got; /* Quantité de données reçue */
+
+ got = recv(G_GDB_STREAM(client)->fd, data, 1, 0);
+
+ //printf(" got ? %d vs %d -> %c (0x%02hhx\n", (int)got, (int)1, *data, *data);
+
+ return (got == 1);
+
+}