public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Documentation or software - bug?
@ 2002-03-21 12:16 Frank Schaefer
  0 siblings, 0 replies; 3+ messages in thread
From: Frank Schaefer @ 2002-03-21 12:16 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1460 bytes --]

Hi there,

I try to set up a box without procfs, thus I've to set some kernel
parameters using _sysctl().

I wrote a little quick-n-dirty program to set at least integer and
struct ( or better array ) parameters.

I can set all struct, integer and boolean values with this program
except ip_forward.

Due to the docs ip_forward is a BOOLEAN parameter, so the length of the
value array for _sysctl should be 1.

... but ...

in ${KERNELSRC}/net/ipv4/sysctl_net_ipv4.c I find:
snip -->
<-- snap
static int ipv4_sysctl_forward_strategy(ctl_table *table ...
snip -->
<-- snap
	if (newlen != sizeof(int))
		return -EINVAL;
snip -->

If the config file for my program looks like this:
	# CTL_NET IPV4  FORWARD : YES
	3	  5     8	: 1
I get ``Invalid argument'' from my program.
If the config file for my program looks like this:
	3	  5     8	: 1 1 1 1
it works and I have a ``1'' in /proc/sys/net/ipv4/ip_forward.
... sure sizeof(int) is 4 on my machine.

My question:
Is there something wrong with the documentation, and NET_IPV4_FORWARD
awaits 4 integers to set/unset IP forwarding, or is something wrong in
sysctl_net_ipv4.c, or did I understand something wrong, and my program
has to be written in some other kind?

My program itself is in the attachment.

Thanks for every help
Frank

PS:
If the configuration file looks like this:
	3  5  16  1 : 1
(the ``3  5  8'' is due to sysctl.h only for compatibility with 2.0
kernels, and I run an 2.4.16) i get ENODIR.


[-- Attachment #2: sysctl.c --]
[-- Type: text/x-c, Size: 4491 bytes --]

/*****************************************************************************************
**											**
** sysconf.c: Version 0.1	15.03.2002						**
**											**
** Author:	Frank Schaefer <frank.schafer@setuza.cz>				**
**											**
** Purpose:										**
**  For security reasons we decided NOT to enable procfs on our firewall.		**
**  Thus we had to realize an alternative for the settings of kernel parameters.	**
**  Also for security reasons this program doesn't take any parameters, and all paths	**
**  etc. will be hardcoded into this program.						**
**											**
** Files:										**
**	Configuration file for sysctl:	/etc/sysconf.conf				**
**											**
** Configuration file syntax:								**
**	- lines starting with a whitespace and lines starting with '#' are comments	**
**	  empty lines are comnments							**
**		<#> :	integer								**
**		<ws>:	whitespace							**
**  <#>[<ws>[<ws>...[<#><ws>[<ws>...]...]]]:[<ws>...]<#>[<ws>...[<#><ws>[<ws>...]...]]	**
**  Whereas the part up to the colon is the syscontrol name as described in		**
**  /usr/include/linux/sysctl.h, and the part after the colon is the values to set	**
**											**
**  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!		**
**  !!!!!!!!!! EDIT THE CONFIGURATION FILE WITH EXTREME CAUTION !!!!!!!!!!!		**
**  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!		**
**  There isn't any possibility to check correct settings at this level. Incorrect	**
**  settings can cause a complete system crash.						**
**											**
** Return value:									**
**	0:	all settings due to the configuration file succeeded			**
**	n:	number of attempts to set parameters failed				**
**											**
*****************************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include <linux/types.h>
#include <linux/sysctl.h>
#include <errno.h>

/* read one line from the configuration file, ignore comments and store the name and
   the value in the arrays pointed to by name and value	
   INPUT: 	id	- filehandle
		name	- pointer to name array
		nlen	- where to store length of the name
		value	- pointer to value array
		vlen	- where to store length of the value
   OUTPUT:	0 : O.K. name and value contain the next parameter to set
		1 : end of configuratin file reached name and value doesn't make
		    sense								*/
int readconf( FILE* id, int* name, int* nlen, int* value, int* vlen ) {
char		*buf, *buffer;
unsigned char	indx;
int		v_indx = 0, colon = 0;
char		c;
int		*target = name;

	buf = malloc( 80 * sizeof( char ) );
	buffer = buf;
	do {
		if( ! fgets( buffer, 80 * sizeof( char ) , id ) ) {
			free( buf );
			return( 1 );
		}
	} while ( ( *buffer == ' ' ) || ( *buffer == '\t' ) || ( *buffer == '#' ) || \
		  ( *buffer == '\n') );
	do {
		indx = strspn( buffer, "0123456789" );
		if( *(buffer + indx) == ':' ) colon = 1;
		*(buffer + indx) = '\0';
		*(target + v_indx++) = atoi( buffer );
		buffer = buffer + indx + 1;
		indx = strcspn( buffer, "0123456789" );
		c = *(buffer + indx);
		*(buffer + indx) = '\0';
		if( strcspn( buffer, ":" ) != strlen( buffer ) ) colon = 1;
		*(buffer + indx) = c;
		buffer = buffer + indx;
		if( colon && ( target != value ) ) {
			target = value;
			*nlen = v_indx;
			v_indx = 0;
		}
	} while ( strlen( buffer ) > 0 );
	*vlen = v_indx;
	free( buf );
	return( 0 );
}

/* Set one parameter in the OS kernel
   INPUT:	name	- pointer to the name array
		nlen	- length of the array
		value	- pointer to the value array
		vlen	- length of the array
   OUTPUT:	0	- O.K.
		-1	- error								*/
_syscall1( int, _sysctl, struct __sysctl_args *, args );
int sysctl( int* name, int nlen, void* value, size_t vlen ) {
size_t	ovlen = 1;
	struct __sysctl_args args = { name, nlen, 0, &ovlen, value, vlen };
	return _sysctl( &args );
}

int main( ) {
int	name[5], value[16], nlen, vlen, ret = 0;
char 	cfgfile[] = "/etc/sysconf.conf";
FILE*	stream;

	stream = fopen( cfgfile, "r" );
	if( ! stream ) {
		fprintf( stderr, "Could not read configuration file: %s\n", cfgfile );
		exit( 1 );
	}
	while( readconf( stream, name, &nlen, value, &vlen ) != 1 ) {
		if( sysctl( name, nlen, (void*)value, (size_t)vlen ) ) {
			perror( "sysctl" );
			ret++;
		}
	}
	close( stream );
	exit( ret );
}


^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: Documentation or software - bug?
@ 2002-04-07  6:38 Randy.Dunlap
  2002-04-09  7:14 ` Frank Schaefer
  0 siblings, 1 reply; 3+ messages in thread
From: Randy.Dunlap @ 2002-04-07  6:38 UTC (permalink / raw)
  To: frank.schafer; +Cc: linux-kernel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1845 bytes --]


Hi,

Here's my conclusion/opinion.

All of the (networking) BOOLEAN parameters expect newlen (in the
sysctl system call) to be sizeof(int), not 1, but (your) sysctl
program executes the syscall with newlen = 1.

It ([your] sysctl program) should be modified to pass
BOOLEANs as int's.
In other words, BOOLEAN doesn't imply length = 1.

~Randy

---------- Forwarded message ----------

Hi there,

I try to set up a box without procfs, thus I've to set some kernel
parameters using _sysctl().

I wrote a little quick-n-dirty program to set at least integer and
struct ( or better array ) parameters.

I can set all struct, integer and boolean values with this program
except ip_forward.

Due to the docs ip_forward is a BOOLEAN parameter, so the length of the
value array for _sysctl should be 1.

... but ...

in ${KERNELSRC}/net/ipv4/sysctl_net_ipv4.c I find:
snip -->
<-- snap
static int ipv4_sysctl_forward_strategy(ctl_table *table ...
snip -->
<-- snap
	if (newlen != sizeof(int))
		return -EINVAL;
snip -->

If the config file for my program looks like this:
	# CTL_NET IPV4  FORWARD : YES
	3	  5     8	: 1
I get ``Invalid argument'' from my program.
If the config file for my program looks like this:
	3	  5     8	: 1 1 1 1
it works and I have a ``1'' in /proc/sys/net/ipv4/ip_forward.
... sure sizeof(int) is 4 on my machine.

My question:
Is there something wrong with the documentation, and NET_IPV4_FORWARD
awaits 4 integers to set/unset IP forwarding, or is something wrong in
sysctl_net_ipv4.c, or did I understand something wrong, and my program
has to be written in some other kind?

My program itself is in the attachment.

Thanks for every help
Frank

PS:
If the configuration file looks like this:
	3  5  16  1 : 1
(the ``3  5  8'' is due to sysctl.h only for compatibility with 2.0
kernels, and I run an 2.4.16) i get ENODIR.

[-- Attachment #2: Type: TEXT/X-C, Size: 4491 bytes --]

/*****************************************************************************************
**											**
** sysconf.c: Version 0.1	15.03.2002						**
**											**
** Author:	Frank Schaefer <frank.schafer@setuza.cz>				**
**											**
** Purpose:										**
**  For security reasons we decided NOT to enable procfs on our firewall.		**
**  Thus we had to realize an alternative for the settings of kernel parameters.	**
**  Also for security reasons this program doesn't take any parameters, and all paths	**
**  etc. will be hardcoded into this program.						**
**											**
** Files:										**
**	Configuration file for sysctl:	/etc/sysconf.conf				**
**											**
** Configuration file syntax:								**
**	- lines starting with a whitespace and lines starting with '#' are comments	**
**	  empty lines are comnments							**
**		<#> :	integer								**
**		<ws>:	whitespace							**
**  <#>[<ws>[<ws>...[<#><ws>[<ws>...]...]]]:[<ws>...]<#>[<ws>...[<#><ws>[<ws>...]...]]	**
**  Whereas the part up to the colon is the syscontrol name as described in		**
**  /usr/include/linux/sysctl.h, and the part after the colon is the values to set	**
**											**
**  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!		**
**  !!!!!!!!!! EDIT THE CONFIGURATION FILE WITH EXTREME CAUTION !!!!!!!!!!!		**
**  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!		**
**  There isn't any possibility to check correct settings at this level. Incorrect	**
**  settings can cause a complete system crash.						**
**											**
** Return value:									**
**	0:	all settings due to the configuration file succeeded			**
**	n:	number of attempts to set parameters failed				**
**											**
*****************************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include <linux/types.h>
#include <linux/sysctl.h>
#include <errno.h>

/* read one line from the configuration file, ignore comments and store the name and
   the value in the arrays pointed to by name and value	
   INPUT: 	id	- filehandle
		name	- pointer to name array
		nlen	- where to store length of the name
		value	- pointer to value array
		vlen	- where to store length of the value
   OUTPUT:	0 : O.K. name and value contain the next parameter to set
		1 : end of configuratin file reached name and value doesn't make
		    sense								*/
int readconf( FILE* id, int* name, int* nlen, int* value, int* vlen ) {
char		*buf, *buffer;
unsigned char	indx;
int		v_indx = 0, colon = 0;
char		c;
int		*target = name;

	buf = malloc( 80 * sizeof( char ) );
	buffer = buf;
	do {
		if( ! fgets( buffer, 80 * sizeof( char ) , id ) ) {
			free( buf );
			return( 1 );
		}
	} while ( ( *buffer == ' ' ) || ( *buffer == '\t' ) || ( *buffer == '#' ) || \
		  ( *buffer == '\n') );
	do {
		indx = strspn( buffer, "0123456789" );
		if( *(buffer + indx) == ':' ) colon = 1;
		*(buffer + indx) = '\0';
		*(target + v_indx++) = atoi( buffer );
		buffer = buffer + indx + 1;
		indx = strcspn( buffer, "0123456789" );
		c = *(buffer + indx);
		*(buffer + indx) = '\0';
		if( strcspn( buffer, ":" ) != strlen( buffer ) ) colon = 1;
		*(buffer + indx) = c;
		buffer = buffer + indx;
		if( colon && ( target != value ) ) {
			target = value;
			*nlen = v_indx;
			v_indx = 0;
		}
	} while ( strlen( buffer ) > 0 );
	*vlen = v_indx;
	free( buf );
	return( 0 );
}

/* Set one parameter in the OS kernel
   INPUT:	name	- pointer to the name array
		nlen	- length of the array
		value	- pointer to the value array
		vlen	- length of the array
   OUTPUT:	0	- O.K.
		-1	- error								*/
_syscall1( int, _sysctl, struct __sysctl_args *, args );
int sysctl( int* name, int nlen, void* value, size_t vlen ) {
size_t	ovlen = 1;
	struct __sysctl_args args = { name, nlen, 0, &ovlen, value, vlen };
	return _sysctl( &args );
}

int main( ) {
int	name[5], value[16], nlen, vlen, ret = 0;
char 	cfgfile[] = "/etc/sysconf.conf";
FILE*	stream;

	stream = fopen( cfgfile, "r" );
	if( ! stream ) {
		fprintf( stderr, "Could not read configuration file: %s\n", cfgfile );
		exit( 1 );
	}
	while( readconf( stream, name, &nlen, value, &vlen ) != 1 ) {
		if( sysctl( name, nlen, (void*)value, (size_t)vlen ) ) {
			perror( "sysctl" );
			ret++;
		}
	}
	close( stream );
	exit( ret );
}


^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: Documentation or software - bug?
  2002-04-07  6:38 Randy.Dunlap
@ 2002-04-09  7:14 ` Frank Schaefer
  0 siblings, 0 replies; 3+ messages in thread
From: Frank Schaefer @ 2002-04-09  7:14 UTC (permalink / raw)
  To: Randy.Dunlap; +Cc: linux-kernel

On Sun, 2002-04-07 at 08:38, Randy.Dunlap wrote:
> 
> Hi,
> 
> Here's my conclusion/opinion.
> 
> All of the (networking) BOOLEAN parameters expect newlen (in the
> sysctl system call) to be sizeof(int), not 1, but (your) sysctl
> program executes the syscall with newlen = 1.
> 
 
> ---------- Forwarded message ----------
> 
> Hi there,
> 
> I try to set up a box without procfs, thus I've to set some kernel
> parameters using _sysctl().
> 
Hi,

I've figured out this already, but thanks for you'r time

Regards
Frank


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2002-04-09  7:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-03-21 12:16 Documentation or software - bug? Frank Schaefer
  -- strict thread matches above, loose matches on Subject: below --
2002-04-07  6:38 Randy.Dunlap
2002-04-09  7:14 ` Frank Schaefer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox