/*

Copyright (C) 2000 - 2004 Christian Kreibich <christian@whoop.org>.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies of the Software and its documentation and acknowledgment shall be
given in the documentation and software packages that this Software was
used.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

*/
#ifndef __libnd_misc_h
#define __libnd_misc_h

#include <sys/socket.h>
#include <net/if.h>
#include <pcapnav.h>
#include <libnd_types.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * libnd_misc_writen - writes n bytes to a descriptor
 * @fd: file descriptor
 * @data: data buffer
 * @size: size of buffer
 *
 * The function tries to write n buffers to the given
 * file descriptor.
 *
 * Returns: number of bytes written, or value < 0 on error.
 */
guint     libnd_misc_writen(int fd, const guchar *data, guint size);


/**
 * libnd_misc_readn - reads n bytes from a descriptor
 * @fd: file descriptor
 * @data: data buffer
 * @size: size of buffer
 *
 * The function tries to read n buffers from the given
 * file descriptor.
 *
 * Returns: number of bytes read, or value < 0 on error.
 */
guint     libnd_misc_readn(int fd, guchar *data, guint size);


/**
 * libnd_misc_readline - reads from file descriptor until newline is found
 * @fd: file descriptor
 * @data: data buffer
 * @size: size of buffer
 *
 * The function reads from a file descriptor until a newline is encountered.
 * WARNING -- this function can BLOCK.
 *
 * Returns: number of bytes read.
 */
guint     libnd_misc_readline(int fd, guchar *data, guint size);


/**
 * libnd_misc_ones_complement_checksum - computes ones-complement checksum
 * @data: pointer to data to checksum.
 * @data_len: length of @data.
 * @sum: pre-added input.
 *
 * The function computes the ones-complement checksum of the data
 * pointed to by @data. If you want to extend the checksum over data
 * areas not included in @data, you can pre-add the sum of that data
 * in units of short ints (16bit) and pass it as @sum.
 *
 * Returns: checksum.
 */
int       libnd_misc_ones_complement_checksum(const void *data, int data_len, u_int32_t sum);

/**
 * libnd_misc_in_cksum - computes Internet checksum
 * @addr: data to checksum.
 * @addr_len: length of @addr data.
 * @preadd: pre-added input.
 *
 * The function computes the Internet checksum of @addr. Other data
 * can be included in the checksum by pre-added the sum if that data
 * in units of short ints (16bit) and passing it as @preadd.
 *
 * Returns: checksum.
 */
u_short   libnd_misc_in_cksum(u_short *addr, int addr_len, u_int preadd);


/**
 * libnd_misc_exists - checks file existance.
 * @filename: name of file.
 *
 * The function checks whether @filename exists and returns
 * the result.
 *
 * Returns: %TRUE when @filename exists, %FALSE otherwise.
 */
gboolean  libnd_misc_exists(const char *filename);


/**
 * libnd_misc_can_read - checks file read access.
 * @filename: name of file.
 *
 * The function checks whether @filename can be read and
 * returns the result.
 * 
 * Returns: %TRUE if file is readable, %FALSE if it is not or
 * if there is another error (such as @filename doesn't exist).
 */
gboolean  libnd_misc_can_read(const char *filename);


/**
 * libnd_misc_can_write - checks file write access.
 * @filename: name of file.
 *
 * The function checks whether @filename can be written to and
 * returns the result.
 * 
 * Returns: %TRUE if file is writeable, %FALSE if it is not or
 * if there is another error (such as @filename doesn't exist).
 */
gboolean  libnd_misc_can_write(const char *filename);


/**
 * libnd_misc_is_tcpdump_file - checks whether file is tcpdump savefile.
 * @filename: name of file.
 *
 * The function checks whether @filename is a tcpdump savefile
 * by looking for tcpdump's magic %0xa1b2c3d4 and its variations.
 *
 * Returns: %TRUE if test was positive, %FALSE otherwise or if
 * there was an error.
 */
gboolean  libnd_misc_is_tcpdump_file(const char *filename);

/**
 * libnd_misc_can_exec - checks file execution access.
 * @filename: name of file.
 *
 * The function checks whether @filename can be executed and
 * returns the result.
 * 
 * Returns: %TRUE if file is executable, %FALSE if it is not or
 * if there is another error (such as @filename doesn't exist).
 */
gboolean  libnd_misc_can_exec(const char *filename);

/**
 * libnd_misc_is_dir - checks if file is a directory.
 * @filename: name of file.
 *
 * The function checks whether @filename is a directory and
 * returns the result.
 * 
 * Returns: %TRUE if file is a directory, %FALSE if it is not or
 * if there is another error (such as @filename doesn't exist).
 */
gboolean  libnd_misc_is_dir(const char *filename);


/**
 * libnd_misc_int_cmp - glib compare function.
 * @int1: pointer using integer value.
 * @int2: pointer using integer value.
 *
 * This is a simple compare function for pointers that can be casted
 * (not dereferenced!) to ints, returning -1/0/1 of row1 is smaller/
 * equal/larger than row2. The signature allows usage with various
 * glib functions.
 *
 * Returns: comparison result.
 */
gint      libnd_misc_int_cmp(gconstpointer int1, gconstpointer int2);


/**
 * libnd_misc_add_slash - adds slash to end of filename if necessary.
 * @filename: filename to test.
 * 
 * The function checks if @filename ends with a slash and if not,
 * reallocs the memory @filename uses and appends a slash.
 *
 * Returns: resulting string.
 */
char     *libnd_misc_add_slash(char *filename);


/**
 * libnd_misc_get_if_names - returns network interfaces satisfying given conditions.
 * @flags: flags the interface must have set (IFF_xxx values, see net/if.h).
 * 
 * The function returns an alphabetically ordered glib list of strings containing
 * the names of those network interfaces that satisfy the given flag combination.
 *
 * Returns: list of strings. You need to free this list and its entries if you
 * don't need the result any more.
 */
GList    *libnd_misc_get_if_names(int flags);

/**
 * libnd_misc_get_if_mtu - returns interface MTU.
 * @ifname: name of interface to query.
 *
 * The function returns the MTU for a given interface.
 * I have no idea whether this compiles on anything non-Linux ...
 */
int       libnd_misc_get_if_mtu(const char *ifname);

/**
 * libnd_misc_get_hardware_string - assembles string displaying hardware address.
 * @str: pointer to space filled with string.
 * @str_len: available string length.
 * @address: hardware address data.
 * @addr_len: length of hardware address in bytes.
 *
 * The function places into the space pointed to by @str
 * a string representing the hardware @address as "xx : xx : ... : xx".
 */
void      libnd_misc_get_hardware_string(char *str, guint str_len,
				      guchar *address, guint addr_len);

/**
 * libnd_misc_get_unnamed_string - returns numbered dummy file name.
 *
 * The function returns a pointer to statically allocated data
 * that gets filled with a numbered dummy file name. You need
 * to strdup() the pointer if you want to keep it around.
 *
 * Returns: new filename.
 */
char     *libnd_misc_get_unnamed_string(void);


/**
 * libnd_misc_timeval_to_string - prints ASCII version of timeval.
 * @tv: timeval to print string for.
 *
 * The function returns a static string representing @tv as a
 * time interval in the form of, for example, "2 days, 15:26:32:978560".
 *
 * Returns: ASCII version of time interval @tv.
 */
char     *libnd_misc_timeval_to_string(struct bpf_timeval *tv);


/**
 * libnd_misc_memdup - allocates and copies a chunk of memory.
 * @data: input data.
 * @data_len: number of bytes to copy.
 *
 * The function allocates a chunk of memory of size @data_len,
 * and then copies @data_len bytes over from @data into the newly
 * allocated memory region.
 *
 * Returns: new memory chunk, or %NULL if allocation failed.
 */
guchar   *libnd_misc_memdup(const guchar *data, guint data_len);


/**
 * libnd_misc_ctime - returns a configurable string representation of time.
 * @tv: timestamp to convert.
 * @buf: buffer to hold result.
 * @buflen: length of @buf in bytes.
 * @fix_gmt: whether to keep time local or make it relative to GMT.
 * @add_usec: whether to include the microseconds of @tv in the output.
 *
 * The function is similar to ctime_r(3). @fix_gmt includes the local divergence
 * from GMT, and @add_usec includes the microseconds in the timestamp.
 */
void      libnd_misc_ctime(const struct bpf_timeval *tv, char *buf, int buflen,
			   gboolean fix_gmt, gboolean add_usec);


/**
 * libnd_misc_get_gmt_deviation - GMT deviation.
 * 
 * The function returns the number of seconds our local time deviates from GMT.
 *
 * Returns: deviation in seconds.
 */
int       libnd_misc_get_gmt_deviation(void);

/**
 * libnd_misc_get_tmpname - returns a filename for a temporary trace.
 * @filename: the main file's name that the temp name is for.
 *
 * Returns: freshly allocated temporary name. You need to free this
 * memory.
 */
char     *libnd_misc_get_tmpfile(const char *filename);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif
     
