mirror of https://gerrit.osmocom.org/osmo-pcap
osmo-pcap-server: Accept the client connection from a given host
We now read from a given system.
This commit is contained in:
parent
9f6127f592
commit
80b8b606c5
|
@ -26,17 +26,25 @@
|
|||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
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;
|
||||
|
|
|
@ -23,12 +23,34 @@
|
|||
#include <osmo-pcap/osmo_pcap_server.h>
|
||||
#include <osmo-pcap/common.h>
|
||||
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue