diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2006-01-04 12:16:58 +0100 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2006-01-04 12:16:58 +0100 |
commit | 2a6ca4f4d8c8ec86b8bb38442189c85a001a5f6c (patch) | |
tree | e729b90180c52018171acc5947b9ea18cb9bb479 | |
parent | 13c4cd343f661fae01660fa8b889c9dfac4a36ef (diff) |
Better handling of IPv4 connections in IPv6 mode. (Wrapping/Unwrapping of ::ffff:style addresses.)
-rw-r--r-- | bitlbee.c | 2 | ||||
-rw-r--r-- | bitlbee.conf | 7 | ||||
-rw-r--r-- | conf.c | 4 | ||||
-rw-r--r-- | irc.c | 5 | ||||
-rw-r--r-- | protocols/nogaim.h | 3 | ||||
-rw-r--r-- | util.c | 40 |
6 files changed, 53 insertions, 8 deletions
@@ -88,7 +88,7 @@ int bitlbee_daemon_init() #ifdef IPV6 listen_addr.sin6_family = AF_INETx; listen_addr.sin6_port = htons( global.conf->port ); - i = inet_pton( AF_INETx, global.conf->iface, &listen_addr.sin6_addr ); + i = inet_pton( AF_INETx, ipv6_wrap( global.conf->iface ), &listen_addr.sin6_addr ); #else listen_addr.sin_family = AF_INETx; listen_addr.sin_port = htons( global.conf->port ); diff --git a/bitlbee.conf b/bitlbee.conf index 919cee9d..e5e0f7de 100644 --- a/bitlbee.conf +++ b/bitlbee.conf @@ -21,8 +21,8 @@ ## DaemonPort/DaemonInterface: ## -## For RunMode=Daemon, here you can specify on what interface and port the -## daemon should be listening for connections. +## For daemon mode, you can specify on what interface and port the daemon +## should be listening for connections. ## # DaemonInterface = 0.0.0.0 # DaemonPort = 6667 @@ -54,8 +54,7 @@ ## ## Normally, BitlBee gets a hostname using getsockname(). If you have a nicer ## alias for your BitlBee daemon, you can set it here and BitlBee will identify -## itself with that name instead. Leave it commented out if you want BitlBee to -## use getsockname() to get a hostname. +## itself with that name instead. ## # HostName = localhost @@ -45,7 +45,11 @@ conf_t *conf_load( int argc, char *argv[] ) conf = g_new0( conf_t, 1 ); +#ifdef IPV6 + conf->iface = "::"; +#else conf->iface = "0.0.0.0"; +#endif conf->port = 6667; conf->nofork = 0; conf->verbose = 0; @@ -82,7 +82,7 @@ irc_t *irc_new( int fd ) if( ( peer = gethostbyaddr( (char*) &sock->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx ) ) ) irc->myhost = g_strdup( peer->h_name ); else if( inet_ntop( AF_INETx, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) - irc->myhost = g_strdup( buf ); + irc->myhost = g_strdup( ipv6_unwrap( buf ) ); } #else else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INETx ) @@ -101,7 +101,7 @@ irc_t *irc_new( int fd ) if( ( peer = gethostbyaddr( (char*) &sock->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx ) ) ) irc->host = g_strdup( peer->h_name ); else if( inet_ntop( AF_INETx, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL ) - irc->host = g_strdup( buf ); + irc->host = g_strdup( ipv6_unwrap( buf ) ); } #else if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INETx ) @@ -113,6 +113,7 @@ irc_t *irc_new( int fd ) } #endif + /* Rare, but possible. */ if( !irc->host ) irc->host = g_strdup( "localhost." ); if( !irc->myhost ) irc->myhost = g_strdup( "localhost." ); diff --git a/protocols/nogaim.h b/protocols/nogaim.h index 1c2e3beb..3d45d0a0 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -287,7 +287,6 @@ G_MODULE_EXPORT void serv_got_chat_invite( struct gaim_connection *gc, char *han G_MODULE_EXPORT struct conversation *serv_got_joined_chat( struct gaim_connection *gc, int id, char *handle ); G_MODULE_EXPORT void serv_got_chat_in( struct gaim_connection *gc, int id, char *who, int whisper, char *msg, time_t mtime ); G_MODULE_EXPORT void serv_got_chat_left( struct gaim_connection *gc, int id ); -/* void serv_finish_login( struct gaim_connection *gc ); */ /* util.c */ G_MODULE_EXPORT void strip_linefeed( gchar *text ); @@ -298,6 +297,8 @@ G_MODULE_EXPORT time_t get_time( int year, int month, int day, int hour, int min G_MODULE_EXPORT void strip_html( char *msg ); G_MODULE_EXPORT char *escape_html( const char *html ); G_MODULE_EXPORT void info_string_append(GString *str, char *newline, char *name, char *value); +G_MODULE_EXPORT char *ipv6_wrap( char *src ); +G_MODULE_EXPORT char *ipv6_unwrap( char *src ); /* prefs.c */ G_MODULE_EXPORT void build_block_list(); @@ -402,3 +402,43 @@ char *strip_newlines( char *source ) return source; } + +#ifdef IPV6 +/* Wrap an IPv4 address into IPv6 space. Not thread-safe... */ +char *ipv6_wrap( char *src ) +{ + static char dst[64]; + int i; + + for( i = 0; src[i]; i ++ ) + if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' ) + break; + + /* Hmm, it's not even an IP... */ + if( src[i] ) + return src; + + g_snprintf( dst, sizeof( dst ), "::ffff:%s", src ); + + return dst; +} + +/* Unwrap an IPv4 address into IPv6 space. Thread-safe, because it's very simple. :-) */ +char *ipv6_unwrap( char *src ) +{ + int i; + + if( g_strncasecmp( src, "::ffff:", 7 ) != 0 ) + return src; + + for( i = 7; src[i]; i ++ ) + if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' ) + break; + + /* Hmm, it's not even an IP... */ + if( src[i] ) + return src; + + return ( src + 7 ); +} +#endif |