底层网络编程代码总结

44 篇文章 0 订阅
17 篇文章 1 订阅
/*
 * Author:	GaoYang, <271313269@qq.com>
 * Since:	2014-7-24 ~ 2015-7-24
 */
#ifndef	COMMON_UTIL_H
#define	COMMON_UTIL_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <stddef.h>
#include <dirent.h>
#include <time.h>
#include <stdarg.h>
#include <ctype.h>
#include <math.h>
#include <limits.h>
#include <signal.h>

#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <netpacket/packet.h>
#include <linux/if_ether.h>

#define ETH_MAC_HEAD_MIN	14
#define ETH_IP_HEAD_MIN		20
#define ETH_TCP_HEAD_MIN	20
#define ETH_UDP_HEAD_MIN	8
#define ETH_ICMP_HEAD_MIN	8
#define ETH_IGMP_HEAD_MIN	8

#define ETH_MAC_DATA_MIN	54		//6+6+2 + 20 + 20
#define ETH_MAC_DATA_MAX	1518	//6+6+4+2 + 1500
#define ETH_IP_DATA_MIN		46
#define ETH_IP_DATA_MAX		1500
#define ETH_TCP_DATA_MAX	1472	//1500 - 20 - 8

#define log_error(name,stat) log_printf("%s error(%d),(%s)(%d)(%s)\n", #name,stat,__FILE__,__LINE__,__FUNCTION__)
#define COMMON_TV_SUB(tv1, tv2) (((tv2).tv_sec - (tv1).tv_sec)*1000000 + ((tv2).tv_usec - (tv1).tv_usec))

typedef unsigned char   uchar;
typedef unsigned short  ushort;
typedef unsigned int    uint;
typedef unsigned long   ulong;


/* log */
void log_printf(const char *fmt,...);

/* conf */
int common_conf_get_value(char *filename, char *key, char *value);
char *common_str_ltrim(char *str);
char *common_str_rtrim(char *str);

/* mac layer*/
int common_mac_set_promisc(char if_name[], int fd);
int common_mac_get_hwaddr(char if_name[], int fd, u_char mac[]);
int common_mac_get_index(char if_name[], int fd, int *if_index);
int common_mac_bind_if(char if_name[], int fd, short protocol);
int common_mac_get_ifall(struct ifreq *allif, int num, int *count);
char *common_mac_get_ip(char if_name[], int fd);
int common_mac_convert_addr2mac(char addr[], u_char *mac);

/* ip layer */
void print_ip(struct ip *ip);
void print_tcp(struct tcphdr *tcp);

/* socket*/
int common_sock_bind_if(int fd, char if_name[]);
int common_socket_set_sndtimeo(int fd, struct timeval *tv);
int common_socket_set_rcvtimeo(int fd, struct timeval *tv);

/* common */
void common_sleep(int milsec);
void print_str16(u_char buf[], size_t len);

/* nqa */
int common_nqa_get_value(int data[], int n, int *max, int *min, int *avg, int *std, double *var);
int common_nqa_get_jitter(int data[], int n, int jitter[]);


#endif




/*
 * Author:	GaoYang, <271313269@qq.com>
 * Since:	2014-7-24 ~ 2015-7-24
 */
#include "common_util.h"

/*
 * log function
 */
void log_printf(const char *fmt,...)
{
	char    buf[4096];
	va_list ap;
	struct timeval	tv;

	va_start(ap, fmt);
	vsprintf(buf, fmt, ap);
	va_end(ap);
	gettimeofday(&tv, NULL);
	printf("%u.%u-%u# %s", (int)tv.tv_sec, (int)tv.tv_usec, getpid(), buf);
	//printf("%u.%u-%u.%u# %s", (int)tv.tv_sec, (int)tv.tv_usec, getpid(), pthread_self(), buf);
}

/*
 * conf file function
 */
int common_conf_get_value(char *filename, char *key, char *value)
{
	FILE    *fp;
	char    buf[512], bufkey[256], bufvalue[256];
	char    *p = NULL;
	int     len, flag = -1;

	if(filename == NULL || key == NULL || value == NULL)
		return EINVAL;
	fp = fopen(filename, "r");
	if(fp == NULL)
		return errno;
	while(fgets(buf, sizeof(buf), fp) != NULL){
		common_str_ltrim(buf);
		common_str_rtrim(buf);
		if(buf[0] == '#')
			continue;
		if((p = strchr(buf, '=')) == NULL)
			return EINVAL;
		//get cfg key
		len = p - buf;
		memset(bufkey, 0, sizeof(bufkey));
		strncpy(bufkey, buf, len);
		common_str_rtrim(bufkey);
		//get cfg value
		if(strcmp(bufkey, key) == 0){
			memset(bufvalue, 0, sizeof(bufvalue));
			strcpy(bufvalue, p+1);
			common_str_ltrim(bufvalue);
			strcpy(value, bufvalue);
			flag = 1;
			break;
		}
	}
	fclose(fp);
	return flag;
}
char *common_str_ltrim(char *str)
{
	char	*p;
	if(str == NULL)
		return NULL;
	for(p=str; *p!='\0'; p++)
		if(!isspace(*p))
			break;
	memmove(str, p, strlen(p)+1);
	return str;
}       
char *common_str_rtrim(char *str)
{
	char	*p;
	if(str == NULL)
		return NULL;
	p = str + strlen(str)-1;
	while((p!=str) && isspace(*p)){
		*p = '\0'; 
		p--; 
	}       
	return str;
}

/*
 * mac layer function
 */
int common_mac_set_promisc(char if_name[], int fd)
{
	int		ret = 0;
	struct	ifreq	ifr;

	if(if_name == NULL || strlen(if_name) >= IFNAMSIZ || fd < 0)
		return EINVAL;
	strcpy(ifr.ifr_name, if_name);
	ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
	if(ret != 0){
		log_error(ioctl, errno);
		return errno;
	}
	ifr.ifr_flags |= IFF_PROMISC;
	ret = ioctl(fd, SIOCSIFFLAGS, &ifr);
	if(ret != 0){
		log_error(ioctl, errno);
		return errno;
	}
	return 0;
}
int common_mac_get_hwaddr(char if_name[], int fd, u_char mac[])
{
	int		ret = 0;
	struct	ifreq	ifr;

	if(if_name == NULL || strlen(if_name) >= IFNAMSIZ || fd < 0 || mac == NULL)
		return EINVAL;
	strcpy(ifr.ifr_name, if_name);
	ret = ioctl(fd, SIOCGIFHWADDR, &ifr);
	if(ret != 0){
		log_error(ioctl, errno);
		return errno;
	}
	memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
	return 0;
}
int common_mac_get_index(char if_name[], int fd, int *if_index)
{
	int		ret = 0;
	struct	ifreq	ifr;

	if(if_name == NULL || strlen(if_name) >= IFNAMSIZ || fd < 0 || if_index == NULL)
		return EINVAL;
	strcpy(ifr.ifr_name, if_name);
	ret = ioctl(fd, SIOCGIFINDEX, &ifr);
	if(ret != 0){
		log_error(ioctl, errno);
		return errno;
	}
	*if_index = ifr.ifr_ifindex;
	return 0;
}
int common_mac_bind_if(char if_name[], int fd, short protocol)
{
	int		ret = 0;
	struct	ifreq	ifr;
	struct	sockaddr_ll	sa;

	if(if_name == NULL || strlen(if_name) >= IFNAMSIZ || fd < 0)
		return EINVAL;
	strcpy(ifr.ifr_name, if_name);
	ret = ioctl(fd, SIOCGIFINDEX, &ifr);
	if(ret != 0){
		log_error(ioctl, errno);
		return errno;
	}
	//set addr
	memset(&sa, 0, sizeof(struct sockaddr_ll));
	sa.sll_family = PF_PACKET;
	sa.sll_protocol = htons(protocol);
	sa.sll_ifindex = ifr.ifr_ifindex;
	//bind if
	ret = bind(fd, (struct sockaddr*)&sa, sizeof(struct sockaddr_ll));
	if(ret != 0){
		log_error(bind, errno);
		return errno;
	}
	return 0;
}
int common_mac_get_ifall(struct ifreq *allif, int num, int *count)
{
	int     ret, sock;
	struct  ifconf  ifc;
	char    buf[25 * sizeof(struct ifreq)];

	if(allif == NULL || num < 1 || count == NULL)
		return EINVAL;
	sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
	if(sock == -1){
		log_error(socket, errno);
		return errno;
	}
	ifc.ifc_len = sizeof(buf);
	ifc.ifc_buf = buf;
	ret = ioctl(sock, SIOCGIFCONF, &ifc);
	if(ret == -1){
		log_error(ioctl, errno);
		return errno;
	}
	*count = ifc.ifc_len / sizeof(struct ifreq);
	if(*count > num)
		*count = num;
	memcpy(allif, ifc.ifc_req, *count * sizeof(struct ifreq));
	return 0;
}
char *common_mac_get_ip(char if_name[], int fd)
{
	int		ret = 0;
	struct	ifreq	ifr;

	if(if_name == NULL || strlen(if_name) >= IFNAMSIZ || fd < 0)
		return NULL;
	strcpy(ifr.ifr_name, if_name);
	ret = ioctl(fd, SIOCGIFADDR, &ifr);
	if(ret != 0){
		log_error(ioctl, errno);
		return NULL;
	}
	return inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
}
int common_mac_convert_addr2mac(char addr[], u_char *mac)
{
	int		i;
	char	c, *p = addr;
	//addr eg. 00:0c:29:5d:9d:e8 
	if(addr == NULL || strlen(addr) != 17 || mac == NULL)
		return EINVAL;
	for(i=0; i<6; i++, p+=3){
		c = strtol(p, NULL, 16);
		mac[i] = c;
	}
	return 0;
}

/*
 * ip layer
 */
void print_ip(struct ip *ip)
{
	if(ip == NULL)
		return;
	log_printf("ip_v[%d]hl[%d]tos[%d]len[%d]id[%x]off[%x]ttl[%d]p[%d]sum[%x]src[%x]dst[%x]\n",
			ip->ip_v, ip->ip_hl, ip->ip_tos, ntohs(ip->ip_len), ntohs(ip->ip_id), ntohs(ip->ip_off),
			ip->ip_ttl, ip->ip_p, ntohs(ip->ip_sum),
			ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr));
}
void print_tcp(struct tcphdr *tcp)
{
	if(tcp == NULL)
		return;
	log_printf("tcp_src[%d]dst[%d]seq[%x]ack[%x]doff[%d]urg[%d]ack[%d]psh[%d]rst[%d]syn[%d]fin[%d]win[%d]check[%x]ptr[%x]\n",
			ntohs(tcp->source), ntohs(tcp->dest), ntohl(tcp->seq), ntohl(tcp->ack_seq),
			tcp->doff, tcp->urg, tcp->ack, tcp->psh, tcp->rst, tcp->syn, tcp->fin,
			ntohs(tcp->window), ntohs(tcp->check), ntohs(tcp->urg_ptr));
}

/*
 * socket function
 */
int common_sock_bind_if(int fd, char if_name[])
{
	int     ret = 0;
	struct  ifreq   ifr;

	if(if_name == NULL || fd < 0)
		return EINVAL;
	memset(&ifr, 0, sizeof(struct ifreq));
	strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name)-1);
	ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(struct ifreq));
	if(ret != 0){
		log_error(setsockopt, errno);
		return errno;
	}
	return 0;
}
int common_sock_set_sndtimeo(int fd, struct timeval *tv)
{
	int	ret = 0;

	if(fd < 0 || tv == NULL)
		return EINVAL;
	ret = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, tv, sizeof(struct timeval));
	if(ret != 0){ 
		log_error(setsockopt, errno);
		return errno;
	}
	return 0;
}
int common_sock_set_rcvtimeo(int fd, struct timeval *tv)
{
	int	ret = 0;

	if(fd < 0 || tv == NULL)
		return EINVAL;
	ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, tv, sizeof(struct timeval));
	if(ret != 0){ 
		log_error(setsockopt, errno);
		return errno;
	}
	return 0;
}

/*
 * common function
 */
void common_sleep(int milsec)
{               
	struct timeval  tm;

	tm.tv_sec = milsec / 1000;
	tm.tv_usec = milsec % 1000 * 1000;
	(void) select(1, NULL, NULL, NULL, &tm);
	return ;
}

void print_str16(u_char buf[], size_t len)
{
	int		i;
	u_char	c;

	if(buf == NULL || len <= 0)
		return;
	for(i=0; i<len; i++){
		c = buf[i];
		printf("%02x ", c);
	}
	printf("\n");
}

/*
 * nqa function
 */
#ifdef _NQA_DEBUG
int common_nqa_get_value(int data[], int n, int *max, int *min, int *avg, int *std, double *var)
{
	int	i, sum = 0;

	if(data==NULL || n<=0 || max==NULL || min==NULL || avg==NULL || std==NULL || var==NULL)
		return EINVAL;
	*max = *min = data[0];
	*var = 0;
	for(i=0; i<n; i++){
		if(data[i] > *max) *max = data[i];
		if(data[i] < *min) *min = data[i];
		sum += data[i];
	}
	*avg = sum/n;
	for(i=0; i<n; i++){
		*var += pow((data[i] - *avg), 2);
	}
	*std = (int)sqrt(*var);
	return 0;
}
int common_nqa_get_jitter(int data[], int n, int jitter[])
{
	int	i;

	if(data==NULL || n<=0 || jitter==NULL)
		return EINVAL;
	for(i=0; i<n-1; i++){
		jitter[i] = abs(data[i+1] - data[i]);
	}
	return 0;
}
#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值