summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2020-02-24 14:25:15 +0100
committerSimon Rettberg2020-02-24 14:25:15 +0100
commita77b33e5357278509ffde6284821682351c4d52a (patch)
treef57c48a8f3d2ff9102b1977f19867065db879fd1
parentMerge branch 'master' into openslx (diff)
parent[iscsi] Eliminate variable-length stack allocation in URI parsing (diff)
downloadipxe-a77b33e5357278509ffde6284821682351c4d52a.tar.gz
ipxe-a77b33e5357278509ffde6284821682351c4d52a.tar.xz
ipxe-a77b33e5357278509ffde6284821682351c4d52a.zip
Merge branch 'master' into openslx
-rw-r--r--.travis.yml3
-rw-r--r--src/Makefile17
-rw-r--r--src/core/settings.c9
-rw-r--r--src/drivers/net/efi/snpnet.c6
-rw-r--r--src/net/infiniband/ib_srp.c24
-rw-r--r--src/net/peerdisc.c69
-rw-r--r--src/net/peerdist.c38
-rw-r--r--src/net/tcp/iscsi.c90
-rw-r--r--src/net/udp/slam.c32
-rw-r--r--src/net/udp/tftp.c17
10 files changed, 249 insertions, 56 deletions
diff --git a/.travis.yml b/.travis.yml
index 0e75158e..43849cc5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,6 +2,9 @@ dist: trusty
sudo: false
+git:
+ depth: false
+
language: c
cache: ccache
diff --git a/src/Makefile b/src/Makefile
index c0bc45fa..a84efd6d 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -207,14 +207,27 @@ install :
#
# Version number calculations
#
+ifneq ($(wildcard ../.git),)
+VERSIONS := $(shell git describe --tags --always --long --abbrev=1 --match "v*")
+VERSION_TUPLE := $(subst ., ,$(subst -, ,$(patsubst v%,%,$(VERSIONS))))
+VERSION_MAJOR := $(word 1,$(VERSION_TUPLE))
+VERSION_MINOR := $(word 2,$(VERSION_TUPLE))
+VERSION_PATCH := $(word 3,$(VERSION_TUPLE))
+ifeq ($(word 4,$(VERSION_TUPLE)),0)
+EXTRAVERSION :=
+else
+EXTRAVERSION := +
+endif
+GITVERSION = $(word 5,$(VERSION_TUPLE))
+else
VERSION_MAJOR = 1
VERSION_MINOR = 0
VERSION_PATCH = 0
EXTRAVERSION = +
+endif
MM_VERSION = $(VERSION_MAJOR).$(VERSION_MINOR)
VERSION = $(MM_VERSION).$(VERSION_PATCH)$(EXTRAVERSION)
-ifneq ($(wildcard ../.git),)
-GITVERSION := $(shell git describe --always --abbrev=1 --match "" 2>/dev/null)
+ifneq ($(GITVERSION),)
VERSION += ($(GITVERSION))
endif
version :
diff --git a/src/core/settings.c b/src/core/settings.c
index bfe618d9..d6ab6b20 100644
--- a/src/core/settings.c
+++ b/src/core/settings.c
@@ -371,12 +371,14 @@ const char * settings_name ( struct settings *settings ) {
static struct settings *
parse_settings_name ( const char *name, get_child_settings_t get_child ) {
struct settings *settings = &settings_root;
- char name_copy[ strlen ( name ) + 1 ];
+ char *name_copy;
char *subname;
char *remainder;
/* Create modifiable copy of name */
- memcpy ( name_copy, name, sizeof ( name_copy ) );
+ name_copy = strdup ( name );
+ if ( ! name_copy )
+ return NULL;
remainder = name_copy;
/* Parse each name component in turn */
@@ -390,6 +392,9 @@ parse_settings_name ( const char *name, get_child_settings_t get_child ) {
break;
}
+ /* Free modifiable copy of name */
+ free ( name_copy );
+
return settings;
}
diff --git a/src/drivers/net/efi/snpnet.c b/src/drivers/net/efi/snpnet.c
index 88474b0b..536248bc 100644
--- a/src/drivers/net/efi/snpnet.c
+++ b/src/drivers/net/efi/snpnet.c
@@ -300,6 +300,9 @@ static int snpnet_rx_filters ( struct net_device *netdev ) {
EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST ),
( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
+ EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST |
+ EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST ),
+ ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST ),
( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST ),
};
@@ -310,7 +313,8 @@ static int snpnet_rx_filters ( struct net_device *netdev ) {
/* Try possible receive filters in turn */
for ( i = 0; i < ( sizeof ( filters ) / sizeof ( filters[0] ) ); i++ ) {
efirc = snp->snp->ReceiveFilters ( snp->snp, filters[i],
- 0, TRUE, 0, NULL );
+ EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST, TRUE,
+ 0, NULL );
if ( efirc == 0 )
return 0;
rc = -EEFI ( efirc );
diff --git a/src/net/infiniband/ib_srp.c b/src/net/infiniband/ib_srp.c
index cf1ef3bf..4913f449 100644
--- a/src/net/infiniband/ib_srp.c
+++ b/src/net/infiniband/ib_srp.c
@@ -498,14 +498,21 @@ static struct ib_srp_root_path_parser ib_srp_rp_parser[] = {
static int ib_srp_parse_root_path ( const char *rp_string,
struct ib_srp_root_path *rp ) {
struct ib_srp_root_path_parser *parser;
- char rp_string_copy[ strlen ( rp_string ) + 1 ];
char *rp_comp[IB_SRP_NUM_RP_COMPONENTS];
- char *rp_string_tmp = rp_string_copy;
+ char *rp_string_copy;
+ char *rp_string_tmp;
unsigned int i = 0;
int rc;
+ /* Create modifiable copy of root path */
+ rp_string_copy = strdup ( rp_string );
+ if ( ! rp_string_copy ) {
+ rc = -ENOMEM;
+ goto err_strdup;
+ }
+ rp_string_tmp = rp_string_copy;
+
/* Split root path into component parts */
- strcpy ( rp_string_copy, rp_string );
while ( 1 ) {
rp_comp[i++] = rp_string_tmp;
if ( i == IB_SRP_NUM_RP_COMPONENTS )
@@ -514,7 +521,8 @@ static int ib_srp_parse_root_path ( const char *rp_string,
if ( ! *rp_string_tmp ) {
DBG ( "IBSRP root path \"%s\" too short\n",
rp_string );
- return -EINVAL_RP_TOO_SHORT;
+ rc = -EINVAL_RP_TOO_SHORT;
+ goto err_split;
}
}
*(rp_string_tmp++) = '\0';
@@ -527,11 +535,15 @@ static int ib_srp_parse_root_path ( const char *rp_string,
DBG ( "IBSRP could not parse \"%s\" in root path "
"\"%s\": %s\n", rp_comp[i], rp_string,
strerror ( rc ) );
- return rc;
+ goto err_parse;
}
}
- return 0;
+ err_parse:
+ err_split:
+ free ( rp_string_copy );
+ err_strdup:
+ return rc;
}
/**
diff --git a/src/net/peerdisc.c b/src/net/peerdisc.c
index 20ac2427..55e3f7fa 100644
--- a/src/net/peerdisc.c
+++ b/src/net/peerdisc.c
@@ -37,6 +37,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/netdevice.h>
#include <ipxe/timer.h>
#include <ipxe/fault.h>
+#include <ipxe/settings.h>
#include <ipxe/pccrd.h>
#include <ipxe/peerdisc.h>
@@ -72,6 +73,9 @@ static LIST_HEAD ( peerdisc_segments );
*/
unsigned int peerdisc_timeout_secs = PEERDISC_DEFAULT_TIMEOUT_SECS;
+/** Hosted cache server */
+static char *peerhost;
+
static struct peerdisc_segment * peerdisc_find ( const char *id );
static int peerdisc_discovered ( struct peerdisc_segment *segment,
const char *location );
@@ -442,6 +446,7 @@ static struct peerdisc_segment * peerdisc_create ( const char *id ) {
char *uuid_copy;
char *id_copy;
unsigned int i;
+ int rc;
/* Generate a random message UUID. This does not require high
* quality randomness.
@@ -458,7 +463,7 @@ static struct peerdisc_segment * peerdisc_create ( const char *id ) {
/* Allocate and initialise structure */
segment = zalloc ( sizeof ( *segment ) + id_len + uuid_len );
if ( ! segment )
- return NULL;
+ goto err_alloc;
id_copy = ( ( ( void * ) segment ) + sizeof ( *segment ) );
memcpy ( id_copy, id, id_len );
uuid_copy = ( ( ( void * ) id_copy ) + id_len );
@@ -469,14 +474,30 @@ static struct peerdisc_segment * peerdisc_create ( const char *id ) {
INIT_LIST_HEAD ( &segment->peers );
INIT_LIST_HEAD ( &segment->clients );
timer_init ( &segment->timer, peerdisc_expired, &segment->refcnt );
- DBGC2 ( segment, "PEERDISC %p discovering %s\n", segment, segment->id );
- /* Start discovery timer */
- start_timer_nodelay ( &segment->timer );
+ /* Add hosted cache server or initiate discovery */
+ if ( peerhost ) {
+
+ /* Add hosted cache server to list of peers */
+ if ( ( rc = peerdisc_discovered ( segment, peerhost ) ) != 0 )
+ goto err_peerhost;
+
+ } else {
+
+ /* Start discovery timer */
+ start_timer_nodelay ( &segment->timer );
+ DBGC2 ( segment, "PEERDISC %p discovering %s\n",
+ segment, segment->id );
+ }
/* Add to list of segments, transfer reference to list, and return */
list_add_tail ( &segment->list, &peerdisc_segments );
return segment;
+
+ err_peerhost:
+ ref_put ( &segment->refcnt );
+ err_alloc:
+ return NULL;
}
/**
@@ -579,3 +600,43 @@ void peerdisc_close ( struct peerdisc_client *peerdisc ) {
if ( list_empty ( &peerdisc_segments ) )
peerdisc_socket_close ( 0 );
}
+
+/******************************************************************************
+ *
+ * Settings
+ *
+ ******************************************************************************
+ */
+
+/** PeerDist hosted cache server setting */
+const struct setting peerhost_setting __setting ( SETTING_MISC, peerhost ) = {
+ .name = "peerhost",
+ .description = "PeerDist hosted cache",
+ .type = &setting_type_string,
+};
+
+/**
+ * Apply PeerDist discovery settings
+ *
+ * @ret rc Return status code
+ */
+static int apply_peerdisc_settings ( void ) {
+
+ /* Free any existing hosted cache server */
+ free ( peerhost );
+ peerhost = NULL;
+
+ /* Fetch hosted cache server */
+ fetch_string_setting_copy ( NULL, &peerhost_setting, &peerhost );
+ if ( peerhost ) {
+ DBGC ( &peerhost, "PEERDISC using hosted cache %s\n",
+ peerhost );
+ }
+
+ return 0;
+}
+
+/** PeerDist discovery settings applicator */
+struct settings_applicator peerdisc_applicator __settings_applicator = {
+ .apply = apply_peerdisc_settings,
+};
diff --git a/src/net/peerdist.c b/src/net/peerdist.c
index 48933f95..3210ac0e 100644
--- a/src/net/peerdist.c
+++ b/src/net/peerdist.c
@@ -25,6 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdio.h>
#include <ipxe/http.h>
+#include <ipxe/settings.h>
#include <ipxe/peermux.h>
/** @file
@@ -35,6 +36,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* misfortune to encounter, and I've encountered multicast TFTP.
*/
+/** PeerDist is globally enabled */
+static long peerdist_enabled = 1;
+
/**
* Check whether or not to support PeerDist encoding for this request
*
@@ -43,6 +47,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*/
static int http_peerdist_supported ( struct http_transaction *http ) {
+ /* Allow PeerDist to be globally enabled/disabled */
+ if ( ! peerdist_enabled )
+ return 0;
+
/* Support PeerDist encoding only if we can directly access an
* underlying data transfer buffer. Direct access is required
* in order to support decryption of data received via the
@@ -143,3 +151,33 @@ struct http_content_encoding peerdist_encoding __http_content_encoding = {
.supported = http_peerdist_supported,
.init = http_peerdist_init,
};
+
+/** PeerDist enabled setting */
+const struct setting peerdist_setting __setting ( SETTING_MISC, peerdist ) = {
+ .name = "peerdist",
+ .description = "PeerDist enabled",
+ .type = &setting_type_int8,
+};
+
+/**
+ * Apply PeerDist settings
+ *
+ * @ret rc Return status code
+ */
+static int apply_peerdist_settings ( void ) {
+
+ /* Fetch global PeerDist enabled setting */
+ if ( fetch_int_setting ( NULL, &peerdist_setting,
+ &peerdist_enabled ) < 0 ) {
+ peerdist_enabled = 1;
+ }
+ DBGC ( &peerdist_enabled, "PEERDIST is %s\n",
+ ( peerdist_enabled ? "enabled" : "disabled" ) );
+
+ return 0;
+}
+
+/** PeerDist settings applicator */
+struct settings_applicator peerdist_applicator __settings_applicator = {
+ .apply = apply_peerdist_settings,
+};
diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c
index f8379b28..3a44b90f 100644
--- a/src/net/tcp/iscsi.c
+++ b/src/net/tcp/iscsi.c
@@ -980,18 +980,26 @@ static int iscsi_handle_chap_i_value ( struct iscsi_session *iscsi,
*/
static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi,
const char *value ) {
- uint8_t buf[ strlen ( value ) ]; /* Decoding never expands data */
+ uint8_t *buf;
unsigned int i;
int len;
int rc;
+ /* Allocate decoding buffer */
+ len = strlen ( value ); /* Decoding never expands data */
+ buf = malloc ( len );
+ if ( ! buf ) {
+ rc = -ENOMEM;
+ goto err_alloc;
+ }
+
/* Process challenge */
- len = iscsi_large_binary_decode ( value, buf, sizeof ( buf ) );
+ len = iscsi_large_binary_decode ( value, buf, len );
if ( len < 0 ) {
rc = len;
DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
iscsi, value, strerror ( rc ) );
- return rc;
+ goto err_decode;
}
chap_update ( &iscsi->chap, buf, len );
@@ -1009,7 +1017,13 @@ static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi,
}
}
- return 0;
+ /* Success */
+ rc = 0;
+
+ err_decode:
+ free ( buf );
+ err_alloc:
+ return rc;
}
/**
@@ -1050,7 +1064,7 @@ static int iscsi_handle_chap_n_value ( struct iscsi_session *iscsi,
*/
static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
const char *value ) {
- uint8_t buf[ strlen ( value ) ]; /* Decoding never expands data */
+ uint8_t *buf;
int len;
int rc;
@@ -1059,7 +1073,7 @@ static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
iscsi, strerror ( rc ) );
- return rc;
+ goto err_chap_init;
}
chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] );
if ( iscsi->target_password ) {
@@ -1070,31 +1084,47 @@ static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
( sizeof ( iscsi->chap_challenge ) - 1 ) );
chap_respond ( &iscsi->chap );
+ /* Allocate decoding buffer */
+ len = strlen ( value ); /* Decoding never expands data */
+ buf = malloc ( len );
+ if ( ! buf ) {
+ rc = -ENOMEM;
+ goto err_alloc;
+ }
+
/* Process response */
- len = iscsi_large_binary_decode ( value, buf, sizeof ( buf ) );
+ len = iscsi_large_binary_decode ( value, buf, len );
if ( len < 0 ) {
rc = len;
DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
iscsi, value, strerror ( rc ) );
- return rc;
+ goto err_decode;
}
/* Check CHAP response */
if ( len != ( int ) iscsi->chap.response_len ) {
DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
iscsi );
- return -EPROTO_INVALID_CHAP_RESPONSE;
+ rc = -EPROTO_INVALID_CHAP_RESPONSE;
+ goto err_response_len;
}
if ( memcmp ( buf, iscsi->chap.response, len ) != 0 ) {
DBGC ( iscsi, "iSCSI %p incorrect CHAP response \"%s\"\n",
iscsi, value );
- return -EACCES_INCORRECT_TARGET_PASSWORD;
+ rc = -EACCES_INCORRECT_TARGET_PASSWORD;
+ goto err_response;
}
/* Mark session as authenticated */
iscsi->status |= ISCSI_STATUS_AUTH_REVERSE_OK;
- return 0;
+ err_response:
+ err_response_len:
+ err_decode:
+ free ( buf );
+ err_alloc:
+ err_chap_init:
+ return rc;
}
/** An iSCSI text string that we want to handle */
@@ -1918,15 +1948,22 @@ const struct setting reverse_password_setting __setting ( SETTING_AUTH_EXTRA,
*/
static int iscsi_parse_root_path ( struct iscsi_session *iscsi,
const char *root_path ) {
- char rp_copy[ strlen ( root_path ) + 1 ];
+ char *rp_copy;
char *rp_comp[NUM_RP_COMPONENTS];
- char *rp = rp_copy;
+ char *rp;
int skip = 0;
int i = 0;
int rc;
+ /* Create modifiable copy of root path */
+ rp_copy = strdup ( root_path );
+ if ( ! rp_copy ) {
+ rc = -ENOMEM;
+ goto err_strdup;
+ }
+ rp = rp_copy;
+
/* Split root path into component parts */
- strcpy ( rp_copy, root_path );
while ( 1 ) {
rp_comp[i++] = rp;
if ( i == NUM_RP_COMPONENTS )
@@ -1935,7 +1972,8 @@ static int iscsi_parse_root_path ( struct iscsi_session *iscsi,
if ( ! *rp ) {
DBGC ( iscsi, "iSCSI %p root path \"%s\" "
"too short\n", iscsi, root_path );
- return -EINVAL_ROOT_PATH_TOO_SHORT;
+ rc = -EINVAL_ROOT_PATH_TOO_SHORT;
+ goto err_split;
} else if ( *rp == '[' ) {
skip = 1;
} else if ( *rp == ']' ) {
@@ -1947,21 +1985,31 @@ static int iscsi_parse_root_path ( struct iscsi_session *iscsi,
/* Use root path components to configure iSCSI session */
iscsi->target_address = strdup ( rp_comp[RP_SERVERNAME] );
- if ( ! iscsi->target_address )
- return -ENOMEM;
+ if ( ! iscsi->target_address ) {
+ rc = -ENOMEM;
+ goto err_servername;
+ }
iscsi->target_port = strtoul ( rp_comp[RP_PORT], NULL, 10 );
if ( ! iscsi->target_port )
iscsi->target_port = ISCSI_PORT;
if ( ( rc = scsi_parse_lun ( rp_comp[RP_LUN], &iscsi->lun ) ) != 0 ) {
DBGC ( iscsi, "iSCSI %p invalid LUN \"%s\"\n",
iscsi, rp_comp[RP_LUN] );
- return rc;
+ goto err_lun;
}
iscsi->target_iqn = strdup ( rp_comp[RP_TARGETNAME] );
- if ( ! iscsi->target_iqn )
- return -ENOMEM;
+ if ( ! iscsi->target_iqn ) {
+ rc = -ENOMEM;
+ goto err_targetname;
+ }
- return 0;
+ err_targetname:
+ err_lun:
+ err_servername:
+ err_split:
+ free ( rp_copy );
+ err_strdup:
+ return rc;
}
/**
diff --git a/src/net/udp/slam.c b/src/net/udp/slam.c
index c165b4fb..47f60080 100644
--- a/src/net/udp/slam.c
+++ b/src/net/udp/slam.c
@@ -655,35 +655,49 @@ static struct interface_descriptor slam_xfer_desc =
*/
static int slam_parse_multicast_address ( struct slam_request *slam,
const char *path,
- struct sockaddr_in *address ) {
- char path_dup[ strlen ( path ) /* no +1 */ ];
+ struct sockaddr_tcpip *address ) {
+ char *path_dup;
char *sep;
char *end;
+ int rc;
/* Create temporary copy of path, minus the leading '/' */
assert ( *path == '/' );
- memcpy ( path_dup, ( path + 1 ) , sizeof ( path_dup ) );
+ path_dup = strdup ( path + 1 );
+ if ( ! path_dup ) {
+ rc = -ENOMEM;
+ goto err_strdup;
+ }
/* Parse port, if present */
sep = strchr ( path_dup, ':' );
if ( sep ) {
*(sep++) = '\0';
- address->sin_port = htons ( strtoul ( sep, &end, 0 ) );
+ address->st_port = htons ( strtoul ( sep, &end, 0 ) );
if ( *end != '\0' ) {
DBGC ( slam, "SLAM %p invalid multicast port "
"\"%s\"\n", slam, sep );
- return -EINVAL;
+ rc = -EINVAL;
+ goto err_port;
}
}
/* Parse address */
- if ( inet_aton ( path_dup, &address->sin_addr ) == 0 ) {
+ if ( sock_aton ( path_dup, ( ( struct sockaddr * ) address ) ) == 0 ) {
DBGC ( slam, "SLAM %p invalid multicast address \"%s\"\n",
slam, path_dup );
- return -EINVAL;
+ rc = -EINVAL;
+ goto err_addr;
}
- return 0;
+ /* Success */
+ rc = 0;
+
+ err_addr:
+ err_port:
+ free ( path_dup );
+ err_strdup:
+ return rc;
}
/**
@@ -701,7 +715,7 @@ static int slam_open ( struct interface *xfer, struct uri *uri ) {
};
struct slam_request *slam;
struct sockaddr_tcpip server;
- struct sockaddr_in multicast;
+ struct sockaddr_tcpip multicast;
int rc;
/* Sanity checks */
diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c
index 6ce27497..a0dac1ec 100644
--- a/src/net/udp/tftp.c
+++ b/src/net/udp/tftp.c
@@ -545,8 +545,7 @@ static void tftp_timer_expired ( struct retry_timer *timer, int fail ) {
* @v value Option value
* @ret rc Return status code
*/
-static int tftp_process_blksize ( struct tftp_request *tftp,
- const char *value ) {
+static int tftp_process_blksize ( struct tftp_request *tftp, char *value ) {
char *end;
tftp->blksize = strtoul ( value, &end, 10 );
@@ -567,8 +566,7 @@ static int tftp_process_blksize ( struct tftp_request *tftp,
* @v value Option value
* @ret rc Return status code
*/
-static int tftp_process_tsize ( struct tftp_request *tftp,
- const char *value ) {
+static int tftp_process_tsize ( struct tftp_request *tftp, char *value ) {
char *end;
tftp->tsize = strtoul ( value, &end, 10 );
@@ -589,13 +587,11 @@ static int tftp_process_tsize ( struct tftp_request *tftp,
* @v value Option value
* @ret rc Return status code
*/
-static int tftp_process_multicast ( struct tftp_request *tftp,
- const char *value ) {
+static int tftp_process_multicast ( struct tftp_request *tftp, char *value ) {
union {
struct sockaddr sa;
struct sockaddr_in sin;
} socket;
- char buf[ strlen ( value ) + 1 ];
char *addr;
char *port;
char *port_end;
@@ -604,8 +600,7 @@ static int tftp_process_multicast ( struct tftp_request *tftp,
int rc;
/* Split value into "addr,port,mc" fields */
- memcpy ( buf, value, sizeof ( buf ) );
- addr = buf;
+ addr = value;
port = strchr ( addr, ',' );
if ( ! port ) {
DBGC ( tftp, "TFTP %p multicast missing port,mc\n", tftp );
@@ -662,7 +657,7 @@ struct tftp_option {
* @v value Option value
* @ret rc Return status code
*/
- int ( * process ) ( struct tftp_request *tftp, const char *value );
+ int ( * process ) ( struct tftp_request *tftp, char *value );
};
/** Recognised TFTP options */
@@ -682,7 +677,7 @@ static struct tftp_option tftp_options[] = {
* @ret rc Return status code
*/
static int tftp_process_option ( struct tftp_request *tftp,
- const char *name, const char *value ) {
+ const char *name, char *value ) {
struct tftp_option *option;
for ( option = tftp_options ; option->name ; option++ ) {