/*
 * libsysactivity
 * http://sourceforge.net/projects/libsysactivity/
 * Copyright (c) 2009, 2010 Carlos Olmedo Escobar <carlos.olmedo.e@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

/**
 * \defgroup network Network interface
 * @{
 */
#ifndef SA_NET_H_
#define SA_NET_H_

/** \struct sa_net_interface network.h
 * This structure gathers the details about the activity of one network interface.
 */
struct sa_net_interface {
#ifdef SA_NET_INTERFACE_NAME
	char name[SA_NET_INTERFACE_NAME]; //!< Interface's name. It's used as the unique identifier of the interface.
#endif
#ifdef SA_NET_INTERFACE_RECEIVED_BYTES
	uint64_t received_bytes; //!< Total number of received bytes.
#endif
#ifdef SA_NET_INTERFACE_RECEIVED_PACKETS
	uint64_t received_packets; //!< Total number of received packets.
#endif
#ifdef SA_NET_INTERFACE_RECEIVED_ERRORS
	uint64_t received_errors; //!< Amount of received errors.
#endif
#ifdef SA_NET_INTERFACE_RECEIVED_DROP
	uint64_t received_drop; //!< Total number of received packets that had been dropped.
#endif
#ifdef SA_NET_INTERFACE_RECEIVED_FIFO
	uint64_t received_fifo; //!< The number of fifo buffer errors received.
#endif
#ifdef SA_NET_INTERFACE_RECEIVED_COMPRESSED
	uint64_t received_compressed; //!< The number of compressed packets received by the device driver.
#endif
#ifdef SA_NET_INTERFACE_RECEIVED_MULTICAST
	uint64_t received_multicast; //!< Number of packets received which were sent by link-layer multicast.
#endif
#ifdef SA_NET_INTERFACE_SENT_BYTES
	uint64_t sent_bytes; //!< Total number of transmitted bytes.
#endif
#ifdef SA_NET_INTERFACE_SENT_PACKETS
	uint64_t sent_packets; //!< Total number of sent packets.
#endif
#ifdef SA_NET_INTERFACE_SENT_ERRORS
	uint64_t sent_errors; //!< Amount of sent errors.
#endif
#ifdef SA_NET_INTERFACE_SENT_DROP
	uint64_t sent_drop; //!< Total number of sent packets that had been dropped.
#endif
#ifdef SA_NET_INTERFACE_SENT_FIFO
	uint64_t sent_fifo; //!< The number of fifo buffer errors sent.
#endif
#ifdef SA_NET_INTERFACE_SENT_COMPRESSED
	uint64_t sent_compressed; //!< The number of compressed packets transmitted by the device driver.
#endif
#ifdef SA_NET_INTERFACE_SENT_MULTICAST
	uint64_t sent_multicast; //!< Number of packets sent by link-layer multicast.
#endif
};

#ifdef SA_OPEN_NET
/**
 * Prepares the resources needed for retrieving network statistics. This function exists (and is needed) only when SA_OPEN_NET is defined.
 * @return If successful 0 is returned, otherwise an error code is returned. If the operating system is not supported the return value will be ENOTSUP.
 * @see sa_close_net()
 * @since 0.6.0
 */
int sa_open_net(void) SA_EXPORT;
#endif

#ifdef SA_CLOSE_NET
/**
 * This function closes the resources used for retrieving network statistics. You should call it even when there was a previous error in another function of this API. This function exists (and is needed) only when SA_CLOSE_NET is defined.
 * @return If successful 0 is returned, otherwise an error code is returned.
 * @see sa_open_net()
 * @since 0.6.0
 */
int sa_close_net(void) SA_EXPORT;
#endif

/**
 * Gives the total number of network interfaces.
 * You don't need to call sa_reset_net_interfaces() before this function.
 * @param number The number will be stored here
 * @return If successful 0 is returned, otherwise an error code is returned.
 * @since 0.6.0
 */
int sa_count_net_interfaces(uint16_t* number) SA_EXPORT SA_NONNULL;

/**
 * Refreshes the underlying operating system cache.
 * @return If successful 0 is returned, otherwise an error code is returned.
 * @since 0.6.0
 */
int sa_reset_net_interfaces() SA_EXPORT;

/**
 * Returns a list of the existing the network interfaces ids. The array will be fully populated even if it's not big enough (but ENOMEM is returned).
 * sa_reset_net_interfaces() should be called at least once before this function and everytime you need fresh values.
 * @param dst Where the statistics will be stored.
 * @param dst_size The number of ids that fits on the dst pointer.
 * @param written The number of network interfaces ids written.
 * @return If successful 0 is returned, otherwise an error code is returned. ENODEV is returned when there are no more disks available.
 * @since 0.6.0
 */
int sa_get_net_interfaces_ids(char* dst, uint16_t dst_size, uint16_t* written) SA_EXPORT SA_NONNULL;

/**
 * Retrieves statistics from a network interface identified by its name.
 * sa_reset_net_interfaces() should be called at least once before this function and everytime you need fresh values.
 * @param name The name of the network interface.
 * @param dst Where the statistics will be stored.
 * @return If successful 0 is returned, otherwise an error code is returned. ENODEV is returned when the requested device was not found.
 * @since 0.6.0
 */
int sa_get_net_interface(char* name, struct sa_net_interface* dst) SA_EXPORT SA_NONNULL;

/**
 * Retrieves statistics about all the network interfaces' activity.
 * sa_reset_net_interfaces() should be called at least once before this function and everytime you need fresh values.
 * @param dst A buffer where the statistics will be stored.
 * @param dst_size The number of interfaces that fits in the dst buffer. If it's not big enough dst will be filled but ENOMEM will be returned.
 * @param written The amount of interface statistics written.
 * @return If successful 0 is returned, otherwise an error code is returned.
 * @since 0.6.0
 */
int sa_get_net_interfaces(struct sa_net_interface* dst, uint16_t dst_size, uint16_t* written) SA_EXPORT SA_NONNULL;

/*@}*/
#endif /* SA_NET_H_ */
