#include "mnic.h"

typedef struct net_info{
	NETCARD_INFO info[MAXNICNUM];
}SHM;

void get_sem(int semid)
{
        struct sembuf lock;

        lock.sem_num = 0;
        lock.sem_op = -1;
        lock.sem_flg = SEM_UNDO;

        while(semop(semid, &lock, 1)){
                if (errno == EINTR) {
                        continue;
                }
                perror("semop()");
        }
}

void release_sem(int semid)
{
        int ret;
        struct sembuf unlock;

        unlock.sem_num = 0;
        unlock.sem_op = 1;
        unlock.sem_flg = SEM_UNDO;

        if((ret = semop(semid, &unlock, 1)) == -1){
                perror("semop()");
        }
}


int main(void)
{
	int fd = -1;
	int i;
	int semid;
	key_t key;
	SHM *p;
	struct timespec s_time, os_time;
	char shm_path[1024];
        char sem_path[1024];

        memset(shm_path, 0, sizeof(shm_path));
        memset(sem_path, 0, sizeof(sem_path));

        strcpy(shm_path, "/tmp/sys_netcard_shm_path");
        strcpy(sem_path, "/tmp/sys_netcard_sem_path");

	s_time.tv_sec = 1;
        s_time.tv_nsec = 0;

	if ((key=ftok(sem_path, SEM_PROJ_ID)) == -1) {
		perror("ftok()");
		exit(1);
	}
	if((semid = semget(key, 1, IPC_CREAT)) == -1){
		fprintf(stderr, "Create semaphore error\n");
		exit(1);
	}

	if((fd = open(shm_path, O_RDWR)) == -1){
		fprintf(stderr, "open():%s\n", strerror(errno));
		return -1;
	}
        p = mmap(NULL, sizeof(SHM), PROT_READ, MAP_SHARED, fd, 0);
	if(p == MAP_FAILED){
		perror("mmap");
		return -1;
	}
		perror("mmap");
	while(1){
		get_sem(semid);
		for(i = 0; p->info[i].charname[0] != 0; i++){
			fprintf(stdout, "==========================网卡信息 [%d]==============================\n", (i + 1));
			fprintf(stdout,"KEYID = %ld\nBONDING:%s\nDEVICE NAME : %s\nIPADDR : %d.%d.%d.%d\nBROADCAST : %d.%d.%d.%d\nNETMASK : %d.%d.%d.%d\nHWADDR : %02x:%02x:%02x:%02x:%02x:%02x\nFLAGS = %d\nMTU = %d\nTx_queue_len = %d\nTime_stamp = %d\n\nReceive bytes:%llu\nReceive packets:%llu\nReceive errors:%lu\nReceive dropped:%lu\nReceive multicast:%lu\nReceive fifo:%lu\n\nTransmit bytes:%llu\nTransmit packets:%llu\nTransmit errors:%lu\nTransmit dropped:%lu\nTransmit fifo:%lu\nTransmit collisions:%lu\nTransmit carrier:%lu\nAverage flow : %lld\n",
					p->info[i].ID,
					p->info[i].descr,
					p->info[i].charname,
					(unsigned char)p->info[i].addr.sa_data[2],
					(unsigned char)p->info[i].addr.sa_data[3],
					(unsigned char)p->info[i].addr.sa_data[4],
					(unsigned char)p->info[i].addr.sa_data[5],
					(unsigned char)p->info[i].broadaddr.sa_data[2],
					(unsigned char)p->info[i].broadaddr.sa_data[3],
					(unsigned char)p->info[i].broadaddr.sa_data[4],
					(unsigned char)p->info[i].broadaddr.sa_data[5],
					(unsigned char)p->info[i].netmask.sa_data[2],
					(unsigned char)p->info[i].netmask.sa_data[3],
					(unsigned char)p->info[i].netmask.sa_data[4],
					(unsigned char)p->info[i].netmask.sa_data[5],
					(unsigned char)p->info[i].hwaddr.sa_data[0],
					(unsigned char)p->info[i].hwaddr.sa_data[1],
					(unsigned char)p->info[i].hwaddr.sa_data[2],
					(unsigned char)p->info[i].hwaddr.sa_data[3],
					(unsigned char)p->info[i].hwaddr.sa_data[4],
					(unsigned char)p->info[i].hwaddr.sa_data[5],
					p->info[i].flags,
					p->info[i].mtu,
					p->info[i].tx_queue_len,
					p->info[i].time_stamp,
					p->info[i].rx_bytes,
					p->info[i].rx_packets,
					p->info[i].rx_errors,
					p->info[i].rx_dropped,
					p->info[i].rx_multicast,
					p->info[i].rx_fifo_errors,
					p->info[i].tx_bytes,
					p->info[i].tx_packets,
					p->info[i].tx_errors,
					p->info[i].tx_dropped,
					p->info[i].tx_fifo_errors,
					p->info[i].collisions,
					p->info[i].tx_carrier_errors,
					p->info[i].average_flow);
		}
		nanosleep(&s_time, &os_time);
		release_sem(semid);
	}
	close(fd);
	return 0;
}
