From 80b8b606c5d77b43bf748e523ccf49cd5b8b97cf Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 31 May 2011 23:42:20 +0200 Subject: osmo-pcap-server: Accept the client connection from a given host We now read from a given system. --- include/osmo-pcap/osmo_pcap_server.h | 8 +++ src/osmo_server_network.c | 113 ++++++++++++++++++++++++++++++++++- src/osmo_server_vty.c | 3 +- 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/include/osmo-pcap/osmo_pcap_server.h b/include/osmo-pcap/osmo_pcap_server.h index 66ec99e..fbfadfd 100644 --- a/include/osmo-pcap/osmo_pcap_server.h +++ b/include/osmo-pcap/osmo_pcap_server.h @@ -26,17 +26,25 @@ #include #include +#include +#include +#include + #include #include +struct osmo_pcap_server; + struct osmo_pcap_conn { /* list of connections */ struct llist_head entry; + struct osmo_pcap_server *server; /* name */ char *name; char *remote_host; + struct in_addr remote_addr; /* Remote connection */ struct osmo_fd rem_fd; diff --git a/src/osmo_server_network.c b/src/osmo_server_network.c index 6562829..19e5c3c 100644 --- a/src/osmo_server_network.c +++ b/src/osmo_server_network.c @@ -23,12 +23,34 @@ #include #include +#include #include +#include +#include +#include + +#include #include +#include + +static void close_connection(struct osmo_pcap_conn *conn) +{ + if (conn->rem_fd.fd != -1) { + close(conn->rem_fd.fd); + conn->rem_fd.fd = -1; + osmo_fd_unregister(&conn->rem_fd); + } + + if (conn->local_fd != -1) { + close(conn->local_fd); + conn->local_fd = -1; + } +} void osmo_pcap_server_delete(struct osmo_pcap_conn *conn) { + close_connection(conn); llist_del(&conn->entry); talloc_free(conn); } @@ -50,11 +72,100 @@ struct osmo_pcap_conn *osmo_pcap_server_find(struct osmo_pcap_server *server, return NULL; } + conn->name = talloc_strdup(conn, name); + conn->rem_fd.fd = -1; + conn->server = server; llist_add_tail(&conn->entry, &server->conn); return conn; } -int osmo_pcap_server_listen(struct osmo_pcap_server *server) +static int read_cb(struct osmo_fd *fd, unsigned int what) +{ + struct osmo_pcap_conn *conn; + char buf[4096]; + int rc; + + conn = fd->data; + rc = read(fd->fd, buf, sizeof(buf)); + if (rc < 0) { + LOGP(DSERVER, LOGL_ERROR, "Failed to read from %s\n", conn->name); + close_connection(conn); + return -1; + } + + return 0; +} + +static void new_connection(struct osmo_pcap_server *server, + struct osmo_pcap_conn *client, int new_fd) +{ + close_connection(client); + + memset(&client->file_hdr, 0, sizeof(client->file_hdr)); + client->rem_fd.fd = new_fd; + if (osmo_fd_register(&client->rem_fd) != 0) { + LOGP(DSERVER, LOGL_ERROR, "Failed to register fd.\n"); + client->rem_fd.fd = -1; + close(new_fd); + return; + } + + client->rem_fd.data = client; + client->rem_fd.when = BSC_FD_READ; + client->rem_fd.cb = read_cb; +} + +static int accept_cb(struct osmo_fd *fd, unsigned int when) { + struct osmo_pcap_conn *conn; + struct osmo_pcap_server *server; + struct sockaddr_in addr; + socklen_t size = sizeof(addr); + int new_fd; + + new_fd = accept(fd->fd, (struct sockaddr *) &addr, &size); + if (new_fd < 0) { + LOGP(DSERVER, LOGL_ERROR, "Failed to accept socket: %d\n", errno); + return -1; + } + + server = fd->data; + llist_for_each_entry(conn, &server->conn, entry) { + if (conn->remote_addr.s_addr == addr.sin_addr.s_addr) { + LOGP(DSERVER, LOGL_NOTICE, + "New connection from %s\n", conn->name); + new_connection(server, conn, new_fd); + return 0; + } + } + + LOGP(DSERVER, LOGL_ERROR, + "Failed to find client for %s\n", inet_ntoa(addr.sin_addr)); + close(new_fd); return -1; } + +int osmo_pcap_server_listen(struct osmo_pcap_server *server) +{ + int fd; + + fd = osmo_sock_init(AF_INET, SOCK_STREAM, IPPROTO_TCP, + server->addr, server->port, 1); + if (fd < 0) { + LOGP(DSERVER, LOGL_ERROR, "Failed to create the server socket.\n"); + return -1; + } + + server->listen_fd.fd = fd; + server->listen_fd.when = BSC_FD_READ; + server->listen_fd.cb = accept_cb; + server->listen_fd.data = server; + + if (osmo_fd_register(&server->listen_fd) != 0) { + LOGP(DSERVER, LOGL_ERROR, "Failed to register the socket.\n"); + close(fd); + return -1; + } + + return 0; +} diff --git a/src/osmo_server_vty.c b/src/osmo_server_vty.c index 5d7d23d..2a40ef3 100644 --- a/src/osmo_server_vty.c +++ b/src/osmo_server_vty.c @@ -107,7 +107,8 @@ DEFUN(cfg_server_client, } talloc_free(conn->remote_host); - conn->remote_host = talloc_strdup(pcap_server, argv[0]); + conn->remote_host = talloc_strdup(pcap_server, argv[1]); + inet_aton(argv[1], &conn->remote_addr); return CMD_SUCCESS; } -- cgit v1.2.3