/*
 * Simple HP-UX Network Interface Statistics Example
 * 
 * This is a minimal example showing how to get bytes in/out for a 
 * specified network interface on HP-UX using the same approach as net-snmp.
 * 
 * Based on net-snmp's HP-UX implementation in:
 * - agent/mibgroup/mibII/interfaces.c (lines 1914-1945)
 * - Uses nmapi_phystat structure and get_physical_stat() function
 * 
 * Compile with: cc -o hpux_simple_interface_stats hpux_simple_interface_stats.c -lnm
 * 
 * Usage: ./hpux_simple_interface_stats <interface_name>
 * Example: ./hpux_simple_interface_stats lan0
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mib.h>
#include <netinet/mib_kern.h>

int main(int argc, char *argv[])
{
    int fd;
    struct nmparms p;
    int val;
    unsigned int ulen;
    int ret;
    int count;
    nmapi_phystat *if_list;
    int i;
    char *interface_name;
    unsigned long bytes_in, bytes_out;

    if (argc != 2) {
        printf("Usage: %s <interface_name>\n", argv[0]);
        printf("Example: %s lan0\n", argv[0]);
        return 1;
    }

    interface_name = argv[1];

    /* Step 1: Get the number of interfaces */
    if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) < 0) {
        fprintf(stderr, "Error: Cannot open /dev/ip\n");
        return 1;
    }

    p.objid = ID_ifNumber;
    p.buffer = (void *) &val;
    ulen = sizeof(int);
    p.len = &ulen;
    
    if ((ret = get_mib_info(fd, &p)) != 0) {
        fprintf(stderr, "Error: get_mib_info failed\n");
        close_mib(fd);
        return 1;
    }
    
    count = val;
    close_mib(fd);

    if (count <= 0) {
        printf("No network interfaces found\n");
        return 1;
    }

    /* Step 2: Allocate memory for interface list */
    if_list = (nmapi_phystat *) malloc(sizeof(nmapi_phystat) * count);
    if (if_list == NULL) {
        fprintf(stderr, "Error: Memory allocation failed\n");
        return 1;
    }

    /* Step 3: Get physical statistics for all interfaces */
    ulen = (unsigned int) count * sizeof(nmapi_phystat);
    if ((ret = get_physical_stat(if_list, &ulen)) < 0) {
        fprintf(stderr, "Error: get_physical_stat failed with return code %d\n", ret);
        free(if_list);
        return 1;
    }

    /* Step 4: Find the specified interface and get its statistics */
    for (i = 0; i < count; i++) {
        if (strcmp(if_list[i].nm_device, interface_name) == 0) {
            /* Found the interface! */
            bytes_in = if_list[i].if_entry.ifInOctets;
            bytes_out = if_list[i].if_entry.ifOutOctets;
            
            printf("Interface: %s\n", if_list[i].nm_device);
            printf("Bytes In:  %lu\n", bytes_in);
            printf("Bytes Out: %lu\n", bytes_out);
            printf("Packets In:  %lu\n", if_list[i].if_entry.ifInUcastPkts);
            printf("Packets Out: %lu\n", if_list[i].if_entry.ifOutUcastPkts);
            printf("Errors In:   %lu\n", if_list[i].if_entry.ifInErrors);
            printf("Errors Out:  %lu\n", if_list[i].if_entry.ifOutErrors);
            printf("MTU:         %lu\n", if_list[i].if_entry.ifMtu);
            printf("Speed:       %lu bps\n", if_list[i].if_entry.ifSpeed);
            printf("Admin Status: %s\n", (if_list[i].if_entry.ifAdmin == 1) ? "UP" : "DOWN");
            printf("Oper Status:  %s\n", (if_list[i].if_entry.ifOper == 1) ? "UP" : "DOWN");
            
            free(if_list);
            return 0;
        }
    }

    /* Interface not found */
    printf("Interface '%s' not found.\n", interface_name);
    printf("Available interfaces:\n");
    for (i = 0; i < count; i++) {
        printf("  %s\n", if_list[i].nm_device);
    }

    free(if_list);
    return 1;
}