From b6a9152f8c48a3ab9a337e1f40d0cb390c7d533d Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 21 Oct 2013 14:04:06 +0100 Subject: [PATCH] [socket] Add concept of a generalised socket address converter Add sock_aton() and sock_ntoa() to allow for parsing and transcription of arbitrary socket addresses. Signed-off-by: Michael Brown --- src/include/ipxe/errfile.h | 1 + src/include/ipxe/socket.h | 36 +++++++++++++++++++++ src/net/socket.c | 65 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 src/net/socket.c diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h index 83675796..c55107a9 100644 --- a/src/include/ipxe/errfile.h +++ b/src/include/ipxe/errfile.h @@ -215,6 +215,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define ERRFILE_mount ( ERRFILE_NET | 0x00350000 ) #define ERRFILE_oncrpc_iob ( ERRFILE_NET | 0x00360000 ) #define ERRFILE_neighbour ( ERRFILE_NET | 0x00370000 ) +#define ERRFILE_socket ( ERRFILE_NET | 0x00380000 ) #define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 ) #define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 ) diff --git a/src/include/ipxe/socket.h b/src/include/ipxe/socket.h index 320dae4f..48d7ae1a 100644 --- a/src/include/ipxe/socket.h +++ b/src/include/ipxe/socket.h @@ -10,6 +10,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include +#include /** * @defgroup commtypes Communication semantics @@ -99,4 +100,39 @@ struct sockaddr { char pad[ SA_LEN - sizeof ( sa_family_t ) ]; } __attribute__ (( may_alias )); +/** + * Socket address converter + * + */ +struct sockaddr_converter { + /** Socket address family + * + * This is an AF_XXX constant. + */ + sa_family_t family; + /** Transcribe socket address + * + * @v sa Socket address + * @ret string Socket address string + */ + const char * ( * ntoa ) ( struct sockaddr *sa ); + /** Parse socket address + * + * @v string Socket address stringh + * @v sa Socket address to fill in + * @ret rc Return status code + */ + int ( * aton ) ( const char *string, struct sockaddr *sa ); +}; + +/** Socket address converter table */ +#define SOCKADDR_CONVERTERS \ + __table ( struct sockaddr_converter, "sockaddr_converters" ) + +/** Declare a socket address converter */ +#define __sockaddr_converter __table_entry ( SOCKADDR_CONVERTERS, 01 ) + +extern const char * sock_ntoa ( struct sockaddr *sa ); +extern int sock_aton ( const char *string, struct sockaddr *sa ); + #endif /* _IPXE_SOCKET_H */ diff --git a/src/net/socket.c b/src/net/socket.c new file mode 100644 index 00000000..24f6a089 --- /dev/null +++ b/src/net/socket.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2013 Michael Brown . + * + * 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; either version 2 of the + * License, or any later version. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include +#include +#include + +/** @file + * + * Sockets + * + */ + +/** + * Transcribe socket address + * + * @v sa Socket address + * @ret string Socket address string + */ +const char * sock_ntoa ( struct sockaddr *sa ) { + struct sockaddr_converter *converter; + + for_each_table_entry ( converter, SOCKADDR_CONVERTERS ) { + if ( converter->family == sa->sa_family ) + return converter->ntoa ( sa ); + } + return NULL; +} + +/** + * Parse socket address + * + * @v string Socket address string + * @v sa Socket address to fill in + * @ret rc Return status code + */ +int sock_aton ( const char *string, struct sockaddr *sa ) { + struct sockaddr_converter *converter; + + for_each_table_entry ( converter, SOCKADDR_CONVERTERS ) { + if ( converter->aton ( string, sa ) == 0 ) { + sa->sa_family = converter->family; + return 0; + } + } + return -EINVAL; +}