From: short <> Date: Thu, 20 May 2004 07:54:46 +0000 (+0000) Subject: Network probing connected with the packet assembly module. X-Git-Tag: udpgate-1_0~58 X-Git-Url: http://git.jankratochvil.net/?p=udpgate.git;a=commitdiff_plain;h=75d48312f938ebe055459e9be96cdd1c3c4279be Network probing connected with the packet assembly module. --- diff --git a/src/main.h b/src/main.h index e69de29..acc6e0a 100644 --- a/src/main.h +++ b/src/main.h @@ -0,0 +1,32 @@ +/* $Id$ + * Include file for UDP Gateway utility + * Copyright (C) 2004 Jan Kratochvil + * + * This program 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; exactly version 2 of June 1991 is required + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _UDPGATE_MAIN_H +#define _UDPGATE_MAIN_H 1 + + +#include + + +G_BEGIN_DECLS + +G_END_DECLS + + +#endif /* _UDPGATE_MAIN_H */ diff --git a/src/network.c b/src/network.c index c4dbfeb..e39dfc1 100644 --- a/src/network.c +++ b/src/network.c @@ -34,8 +34,10 @@ #include #include #include +#include #include "network.h" +#include "packet.h" /* Config: */ @@ -50,6 +52,9 @@ #define PROBE_TIMEOUT_SEC (5) +void (*network_notify_hostip)(guint32 hostip_guint32,const gchar *hostip_string); + + struct client { GPollFD gpollfd; struct sockaddr_in sockaddr_in_from; @@ -59,8 +64,9 @@ struct client { static GSource *sock_gsource; static GList *sock_client_list; /* of 'struct client *', incl. 'master' and 'probe' */ -struct client *master; /* no 'timeout' permitted */ -struct client *probe; /* 'timeout' permitted */ +static struct client *master; /* no 'timeout' permitted */ +static struct client *probe; /* 'timeout' permitted */ +static guint32 probe_unique; static gboolean write_daemon_running(pid_t pid); @@ -151,6 +157,12 @@ static gboolean client_touch_timeout(struct client *client) g_return_val_if_fail(client!=NULL,FALSE); /* FALSE=>should be removed */ g_return_val_if_fail(client!=master,FALSE); /* FALSE=>should be removed */ + if (client==probe) { + network_stop(); + if (network_notify_hostip) + (*network_notify_hostip)(0,NULL); + } + client_destroy(client); return FALSE; /* GSource should be removed */ @@ -165,21 +177,21 @@ struct sockaddr_in sockaddr_in_from; char packet[0x10000]; struct client *client; struct sockaddr_in sockaddr_in_server; -socklen_t sockaddr_in_from_len; +socklen_t sockaddr_in_from_length; g_return_if_fail(master!=NULL); - sockaddr_in_from_len=sizeof(sockaddr_in_from); + sockaddr_in_from_length=sizeof(sockaddr_in_from); while (-1!=(gotlen=recvfrom( master->gpollfd.fd, /* s */ packet, /* buf */ sizeof(packet), /* len */ 0, /* flags */ (struct sockaddr *)&sockaddr_in_from, /* from */ - &sockaddr_in_from_len))) { /* fromlen */ + &sockaddr_in_from_length))) { /* fromlen */ GList *clientl; - if (sockaddr_in_from_len!=sizeof(sockaddr_in_from)) /* FIXME: errors reporting */ + if (sockaddr_in_from_length!=sizeof(sockaddr_in_from)) /* FIXME: errors reporting */ continue; /* FIXME: Performance: Ugly search... */ for (clientl=sock_client_list;clientl;clientl=clientl->next) { @@ -217,21 +229,55 @@ static void handle_probe(struct client *probe) ssize_t gotlen; struct sockaddr_in sockaddr_in_from; char packet[0x10000]; -socklen_t sockaddr_in_from_len; +socklen_t sockaddr_in_from_length; g_return_if_fail(probe!=NULL); - sockaddr_in_from_len=sizeof(sockaddr_in_from); + sockaddr_in_from_length=sizeof(sockaddr_in_from); while (-1!=(gotlen=recvfrom( master->gpollfd.fd, /* s */ packet, /* buf */ sizeof(packet), /* len */ 0, /* flags */ (struct sockaddr *)&sockaddr_in_from, /* from */ - &sockaddr_in_from_len))) { /* fromlen */ + &sockaddr_in_from_length))) { /* fromlen */ +static GHashTable *got_hash; +static gpointer got_unique_gpointer; +static gpointer hostip_gpointer; +static guint32 hostip_guint32; - if (sockaddr_in_from_len!=sizeof(sockaddr_in_from)) /* FIXME: errors reporting */ + if (sockaddr_in_from_length!=sizeof(sockaddr_in_from)) /* FIXME: errors reporting */ + continue; + if (!(got_hash=packet_disassembly(packet,gotlen))) + continue; + if (!(g_hash_table_lookup_extended( + got_hash, /* hash_table */ + GUINT_TO_POINTER(PACKET_ELEM_TYPE_DATA_GUINT32), /* lookup_key */ + NULL, /* orig_key */ + &got_unique_gpointer))) { +err_packet_disassembly_destroy_got_hash: + packet_disassembly_destroy(got_hash); continue; + } + if (GPOINTER_TO_UINT(got_unique_gpointer)!=probe_unique) + goto err_packet_disassembly_destroy_got_hash; + if (!(g_hash_table_lookup_extended( + got_hash, /* hash_table */ + GUINT_TO_POINTER(PACKET_ELEM_TYPE_CLIENT_INADDR), /* lookup_key */ + NULL, /* orig_key */ + &hostip_gpointer))) + goto err_packet_disassembly_destroy_got_hash; + hostip_guint32=GPOINTER_TO_UINT(hostip_gpointer); + packet_disassembly_destroy(got_hash); + + client_destroy(probe); + if (network_notify_hostip) + (*network_notify_hostip)(hostip_guint32, + udpgate_printf_alloca("%d.%d.%d.%d", + (hostip_guint32>>24U)&0xFFU, + (hostip_guint32>>16U)&0xFFU, + (hostip_guint32>> 8U)&0xFFU, + (hostip_guint32>> 0U)&0xFFU)); } } @@ -240,7 +286,7 @@ static void handle_client(struct client *client) ssize_t gotlen; struct sockaddr_in sockaddr_in_from; char packet [0x10000]; -socklen_t sockaddr_in_from_len; +socklen_t sockaddr_in_from_length; g_return_if_fail(client!=NULL); g_return_if_fail(master!=NULL); @@ -251,8 +297,8 @@ socklen_t sockaddr_in_from_len; sizeof(packet), /* len */ 0, /* flags */ (struct sockaddr *)&sockaddr_in_from, /* from */ - &sockaddr_in_from_len))) { /* fromlen */ - if (sockaddr_in_from_len!=sizeof(sockaddr_in_from)) /* FIXME: errors reporting */ + &sockaddr_in_from_length))) { /* fromlen */ + if (sockaddr_in_from_length!=sizeof(sockaddr_in_from)) /* FIXME: errors reporting */ continue; client_touch(client); /* FIXME: errors checking */ @@ -404,8 +450,11 @@ static void client_destroy(struct client *client) master=NULL; g_assert(client->timeout_id==0); } - else + else { + if (client==probe) + probe=NULL; client_timeout_remove(client); + } g_source_remove_poll(sock_gsource,&client->gpollfd); sock_client_list=g_list_remove(sock_client_list,client); @@ -413,31 +462,43 @@ static void client_destroy(struct client *client) g_free(client); } -static gboolean probe_send(struct client *probe) +static gboolean probe_send(struct client *probe,gint port_local) { struct sockaddr_in sockaddr_in_server; +GHashTable *probe_hash; +gpointer packet; +size_t packet_length; g_return_val_if_fail(probe!=NULL,FALSE); + probe_unique=g_random_int(); + + probe_hash=g_hash_table_new( + g_int_hash, /* hash_func */ + g_int_equal); /* key_equal_func */ + g_hash_table_insert(probe_hash,GUINT_TO_POINTER(PACKET_ELEM_TYPE_CLIENT_PORT) ,GUINT_TO_POINTER(port_local)); + g_hash_table_insert(probe_hash,GUINT_TO_POINTER(PACKET_ELEM_TYPE_DATA_GUINT32),GUINT_TO_POINTER(probe_unique)); + packet=packet_assembly(&packet_length,probe_hash); + g_hash_table_destroy(probe_hash); + if (!packet) + return FALSE; + UDPGATE_MEMZERO(&sockaddr_in_server); sockaddr_in_server.sin_family=AF_INET; sockaddr_in_server.sin_port=htons(PROBE_PORT); sockaddr_in_server.sin_addr.s_addr=htonl(PROBE_INADDR); /* FIXME: errors checking */ -#if 0 sendto( probe->gpollfd.fd, /* s */ packet, /* msg */ - gotlen, /* len */ + packet_length, /* len */ 0, /* flags */ (struct sockaddr *)&sockaddr_in_server, /* to */ sizeof(sockaddr_in_server)); /* tolen */ -#endif return TRUE; } - gboolean network_start(gint port) { pid_t daemon_pid; @@ -468,7 +529,7 @@ err_sock_gsource_destroy: /* Setup 'probe': */ if (!(probe=client_new())) goto err_sock_gsource_destroy; - probe_send(probe); + probe_send(probe,port); client_touch(probe); /* timeout */ write_daemon_running(getpid()); diff --git a/src/network.h b/src/network.h index 9d621fc..05f5cb6 100644 --- a/src/network.h +++ b/src/network.h @@ -31,6 +31,7 @@ G_BEGIN_DECLS pid_t is_daemon_running(void); gboolean network_start(gint port); gboolean network_stop(void); +void (*network_notify_hostip)(guint32 hostip_guint32,const gchar *hostip_string); G_END_DECLS diff --git a/src/packet.c b/src/packet.c index 2f38371..82dbecb 100644 --- a/src/packet.c +++ b/src/packet.c @@ -76,7 +76,7 @@ static void packet_assembly_data_string(GString *gstring,const gchar *string) { size_t string_length; #ifndef G_DISABLE_ASSERT -size_t gstring_len_orig; +size_t gstring_length_orig; #endif /* !G_DISABLE_ASSERT */ g_return_if_fail(gstring!=NULL); @@ -85,11 +85,11 @@ size_t gstring_len_orig; string_length=strlen(string); packet_assembly_guint32(gstring,string_length); #ifndef G_DISABLE_ASSERT - gstring_len_orig=gstring->len; + gstring_length_orig=gstring->len; #endif /* !G_DISABLE_ASSERT */ g_string_append(gstring,string); #ifndef G_DISABLE_ASSERT - g_assert(gstring_len_orig+string_length==gstring->len); + g_assert(gstring_length_orig+string_length==gstring->len); #endif /* !G_DISABLE_ASSERT */ } @@ -118,11 +118,11 @@ guint32 elem_type_uint32; } } -void *packet_assembly(size_t *packet_len_pointer,GHashTable *values) +void *packet_assembly(size_t *packet_length_pointer,GHashTable *values) { GString *gstring; - g_return_val_if_fail(packet_len_pointer!=NULL,NULL); + g_return_val_if_fail(packet_length_pointer!=NULL,NULL); g_return_val_if_fail(values!=NULL,NULL); gstring=g_string_new(NULL); @@ -135,7 +135,7 @@ GString *gstring; (GHFunc)packet_assembly_foreach, /* func */ gstring); /* user_data */ - *packet_len_pointer=gstring->len; + *packet_length_pointer=gstring->len; return g_string_free(gstring, FALSE); /* free_segment */ } @@ -260,7 +260,7 @@ guint16 value_guint16; return TRUE; } -GHashTable *packet_disassembly(gconstpointer packet,size_t packet_len) +GHashTable *packet_disassembly(gconstpointer packet,size_t packet_length) { GHashTable *r; gconstpointer packet_end; @@ -273,7 +273,7 @@ GSList *items; g_int_equal, /* key_equal_func */ NULL, /* key_destroy_func */ packet_disassembly_value_destroy_func); /* value_destroy_func */ - packet_end=packet+packet_len; + packet_end=packet+packet_length; if (packet+strlen(PACKET_HEADER)>packet_end) { err_g_hash_table_destroy_r: diff --git a/src/packet.h b/src/packet.h index bb7f564..a5726db 100644 --- a/src/packet.h +++ b/src/packet.h @@ -38,8 +38,8 @@ enum packet_elem_type { PACKET_ELEM_TYPE_DATA_GUINT32 =(0x04|PACKET_ELEM_ATTR_MANDATORY), /* user data (e.g. unique id) */ }; -gpointer packet_assembly(size_t *packet_len_pointer,GHashTable *values); -GHashTable *packet_disassembly(gconstpointer packet,size_t packet_len); +gpointer packet_assembly(size_t *packet_length_pointer,GHashTable *values); +GHashTable *packet_disassembly(gconstpointer packet,size_t packet_length); void packet_disassembly_destroy(GHashTable *hash); G_END_DECLS