⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common.c

📁 wdiag-0.10.gz ( Diagnostic source )
💻 C
字号:
/* Westell 6100 multicast data collection utility. * Shared code for wstart and wstop. * * Copyright: Josh Carroll (josh.carroll@gmail.com) * 10/13/2004 * * common.c is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2. *  * This program 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 General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA **/#include "common.h"wmodel_t models[MAX_MODEL_NUMBER+1] = {	{ /* Westell 610010 */		"610010",		{4, 4},		{8, 2},		{10, 2},		{12, 2},		{14, 2},		{16, 2},		{18, 2},		{20, 2},		{22, 2},		{24, 2},		{28, 4},		{32, 4},		{36, 4},		{40, 4},		{44, 4},		{48, 4},		{52, 4},		/* skipped data, not sure what resides there */		{98, 4},		{102, 4},		{106, 4},		/* server port */		1875,		/* udp packet size */		120,		/* multicast group to join */		"224.73.193.62"	}, { /* Westell 610030 */		"610030",		{4, 4},		{8, 2},		{10, 2},		{12, 2},		{14, 2},		{16, 2},		{18, 2},		{20, 2},		{22, 2},		{24, 2},		{28, 4},		{32, 4},		{36, 4},		{40, 4},		{44, 4},		{48, 4},		{52, 4},		/* skipped data, not sure what resides there */		{98, 4},		{102, 4},		{106, 4},		/* server port */		1875,		/* udp packet size */		120,		/* multicast group to join */		"224.73.193.62"	}, { /* Westell 36R516 */		"36R516",		{4, 4},		{8, 2},		{10, 2},		{12, 2},		{14, 2},		{16, 2},		{18, 2},		{20, 2},		{22, 2},		{24, 2},		{28, 4},		{32, 4},		{36, 4},		{40, 4},		{44, 4},		{48, 4},		{52, 0},		/* skipped data, not sure what resides there */		{98, 4},		{102, 4},		{106, 4},		/* server port */		1875,		/* udp packet size */		120,		/* multicast group to join */		"224.73.193.62"	}, { /* Westell 2200 */		"2200",		{4, 4},		{8, 2},		{10, 2},		{12, 2},		{14, 2},		{16, 2},		{18, 2},		{20, 2},		{22, 2},		{24, 2},		{28, 4},		{32, 4},		{36, 4},		{40, 4},		{44, 4},		{48, 4},		{52, 4},		/* skipped data, not sure what resides there */		{98, 4},		{102, 4},		{106, 4},		/* server port */		1875,		/* udp packet size */		120,		/* multicast group to join */		"224.73.193.62"	}, { /* Westell 7400 series */		"7400",		{4, 4},		{8, 2},		{10, 2},		{12, 2},		{14, 2},		{16, 2},		{18, 2},		{20, 2},		{22, 2},		{24, 2},		{28, 4},		{32, 4},		{36, 4},		{40, 4},		{44, 4},		{48, 4},		{52, 4},		/* skipped data, not sure what resides there */		{98, 4},		{102, 4},		{106, 4},		/* server port */		1875,		/* udp packet size */		120,		/* multicast group to join */		"224.73.193.62"	}};/* calc the checksum for the ip or igmp header */unsigned short chksum(unsigned short *hdr, int len) {	long sum = 0;	while(len > 1) {		sum += *hdr++;		len -= 2;	}	if(len > 0) {		sum += *hdr;	}	while(sum >> 16) {		sum = (sum >> 16) + (sum & 0xffff);	}	/* truncate to 16 bits */	sum = ~sum;	return sum;}int send_packet(wpacket_t *pkt, char *bcast) {	char errmsg[80];	struct in_addr broadcast;	struct sockaddr_in server, thishost;	int udp_socket,optval = 1;	char *buffer;	/* pkt->data holds the 8-bit decimal value of the	 * consecutive packets, so we should be able to	 * memcpy the appropriate number of bits to the	 * buffer character array, and pass that to the sento	 * function later */	buffer = malloc(sizeof(char) * pkt->packet_length);	if(buffer == NULL) {		perror("Could not allocate buffer memory for socket packet data");		exit(1);	}	memcpy(buffer, pkt->data, pkt->packet_length);	/* create the socket */	if ((udp_socket = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {		perror("Could not create socket");		/* clean up buffer */		wfree(buffer);		exit(1);	}	if(setsockopt(udp_socket, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) < 0) {		perror("Setting socket options failed");		close(udp_socket);		/* clean up buffer */		wfree(buffer);		exit(1);	}		inet_aton(bcast, &broadcast);	server.sin_family = AF_INET;	server.sin_addr.s_addr = broadcast.s_addr;	thishost.sin_family = AF_INET;	thishost.sin_addr.s_addr = INADDR_ANY;	thishost.sin_port = htons(pkt->src_port);	server.sin_port = htons(pkt->dst_port);	if(bind(udp_socket, (struct sockaddr *) &thishost, sizeof(thishost)) < 0) {		sprintf(errmsg, "Could not bind to local port: %d", pkt->src_port);		perror(errmsg);		close(udp_socket);		/* clean up buffer */		wfree(buffer);		exit(1);	}	if(sendto(udp_socket, buffer, pkt->packet_length, 0, (struct sockaddr *) &server, sizeof(server)) < 0) {		perror("Could not send data to socket");		close(udp_socket);		/* clean up buffer */		wfree(buffer);		exit(1);	}	/* close the socket now */	close(udp_socket);	/* free up the memory from buffer */	wfree(buffer);	return(0);}/* sends the multicast subscription packets */void multicast_subscribe(char dest[16], char group[16]) {	int sock, retval, optval;	struct ip *iphdr;	struct igmp *igmphdr;	struct sockaddr_in server;	unsigned char *packet;	/* allocate memory for the packet */	packet = malloc(IGMP_PKT_SIZE);	/* create the server socket */	inet_aton(dest, &server.sin_addr);	server.sin_family = AF_INET;	/* initialize ip header */	iphdr = (struct ip *)packet;	/* zero out the packet */	memset((char *)iphdr,'\0',sizeof(struct ip));	iphdr->ip_hl = 5;	iphdr->ip_v = 4;	iphdr->ip_len = IGMP_PKT_SIZE;	iphdr->ip_id = htons(getpid());	iphdr->ip_ttl = 1;	iphdr->ip_p = IPPROTO_IGMP;	iphdr->ip_src.s_addr = INADDR_ANY;	/* destination is the same as our socket */	iphdr->ip_dst = server.sin_addr;	iphdr->ip_sum = (unsigned short)chksum((unsigned short *)iphdr, sizeof(struct ip));	/* now build the igmp header */    igmphdr = (struct igmp *)(packet + sizeof(struct ip));	igmphdr->igmp_type = IGMP_V2_MEMBERSHIP_REPORT;	igmphdr->igmp_code = 0;	igmphdr->igmp_cksum = (unsigned short)chksum((unsigned short *)igmphdr, sizeof(struct igmp));	inet_aton(group, &igmphdr->igmp_group);	/* create the raw socket */	if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {		perror("Could not create raw socket");		/* cleanup before we exit */		wfree(packet);		exit(1);	}	if((setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(optval))) < 0) {		perror("Could not set socket options");		close(sock);		/* cleanup before we exit */		wfree(packet);		exit(1);	}	if((setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval))) < 0) {		perror("Could not set additional socket options");		close(sock);		/* cleanup before we exit */		wfree(packet);		exit(1);	}	if((retval = sendto(sock, packet, IGMP_PKT_SIZE, 0, (struct sockaddr *) &server, sizeof(server))) < 0) {		perror("Failed to send igmp membership packet");		close(sock);		/* cleanup before we exit */		wfree(packet);		exit(1);	}	close(sock);	wfree(packet);}/* sends the multicast leave group packets */void multicast_leave(char dest[16], char group[16]) {	int sock, retval, optval;	struct ip *iphdr;	struct igmp *igmphdr;	struct sockaddr_in server;	unsigned char *packet;	/* allocate memory for the packet */	packet = malloc(IGMP_PKT_SIZE);	/* create the server socket */	inet_aton(dest, &server.sin_addr);	server.sin_family = AF_INET;	/* initialize ip header */	iphdr = (struct ip *)packet;	/* zero out the packet */	memset((char *)iphdr,'\0',sizeof(struct ip));	iphdr->ip_hl = 5;	iphdr->ip_v = 4;	iphdr->ip_len = IGMP_PKT_SIZE;	iphdr->ip_id = htons(getpid());	iphdr->ip_ttl = 1;	iphdr->ip_p = IPPROTO_IGMP;	iphdr->ip_src.s_addr = INADDR_ANY;	/* destination is the same as our socket */	iphdr->ip_dst = server.sin_addr;	iphdr->ip_sum = (unsigned short)chksum((unsigned short *)iphdr, sizeof(struct ip));	/* now build the igmp header */    igmphdr = (struct igmp *)(packet + sizeof(struct ip));	igmphdr->igmp_type = IGMP_V2_LEAVE_GROUP;	igmphdr->igmp_code = 0;	igmphdr->igmp_cksum = (unsigned short)chksum((unsigned short *)igmphdr, sizeof(struct igmp));	inet_aton(group, &igmphdr->igmp_group);	/* create the raw socket */	if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {		perror("Could not create raw socket");		/* clean up packet buffer */		wfree(packet);		exit(1);	}	if((setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(optval))) < 0) {		perror("Could not set socket options");		close(sock);		/* clean up packet buffer */		wfree(packet);		exit(1);	}	if((setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval))) < 0) {		perror("Could not set additional socket options");		close(sock);		/* clean up packet buffer */		wfree(packet);		exit(1);	}	if((retval = sendto(sock, packet, IGMP_PKT_SIZE, 0, (struct sockaddr *) &server, sizeof(server))) < 0) {		perror("Failed to send igmp membership packet");		close(sock);		/* clean up packet buffer */		wfree(packet);		exit(1);	}	close(sock);	wfree(packet);}void usage(char *prog) {	int i;	printf("Usage: %s -m <model>\n", prog);	printf("Valid models:\n");	for(i=0; i <= MAX_MODEL_NUMBER; i++) {		printf("\t%d\t%s\n", i, models[i].model_number);	}	exit(1);}/* print the individual records */void print_info(const char *prefix, int32_t val, int divisor, int decimal_print) {	if(val < 0) {		printf("%s: %s\n", prefix, W_NO_DATA);	} else {		if(divisor == -1 || decimal_print != 1) {			printf("%s: %u\n", prefix, val);		} else {			printf("%s: %.1f\n", prefix, val/(float)divisor);		}	}}/* takes the westell data struct and prints the fields out */void print_data(struct modemdata data, int decimal_print) {	/* currently hard-coded. Remove what you want or modify to	 * product mrtg-friendly results here. For now it's just	 * dumping ALL the stats */	print_info("Uptime Counter", data.timectr, TIMECTR, decimal_print);	print_info("Upstream SNR", data.snr_up, SNR_UP, decimal_print);	print_info("Upstream Power", data.pwr_up, PWR_UP, decimal_print);	print_info("Upstream Attenuation", data.attn_up, ATTN_UP, decimal_print);	print_info("Upstream Sync Rate", data.syncrate_up, SYNCRATE_UP, decimal_print);	print_info("Downstream SNR", data.snr_down, SNR_DOWN, decimal_print);	print_info("Downstream Power", data.pwr_down, PWR_DOWN, decimal_print);	print_info("Downstream Attenuation", data.attn_down, ATTN_DOWN, decimal_print);	print_info("Downstream Sync Rate", data.syncrate_down, SYNCRATE_DOWN, decimal_print);	print_info("FEC Errors", data.fec_errors, FEC_ERRORS, decimal_print);	print_info("CRC Errors", data.crc_errors, CRC_ERRORS, decimal_print);	print_info("HEC Errors", data.hec_errors, HEC_ERRORS, decimal_print);	print_info("Signal Lost", data.signal_lost, SIGNAL_LOST, decimal_print);	print_info("Frame Lost", data.frame_lost, FRAME_LOST, decimal_print);	print_info("Tx Cell", data.tx_cells, TX_CELLS, decimal_print);	print_info("Rx Cells", data.rx_cells, RX_CELLS, decimal_print);	print_info("Dropped Cells", data.dropped_cells, DROPPED_CELLS, decimal_print);	print_info("Rx Ethernet", data.ethernet_rx, ETHERNET_RX, decimal_print);	print_info("Tx Ethernet", data.ethernet_tx, ETHERNET_TX, decimal_print);	print_info("Discarded Ethernet", data.ethernet_discard, ETHERNET_DISCARD, decimal_print);}int32_t getfield(const unsigned char *packet, const field_t *pkt_field) {	int32_t i32;	int16_t i16;	int8_t i8;	switch(pkt_field->size) {		case 1:			memcpy(&i8, packet + pkt_field->offset, pkt_field->size);			return i8;		case 2:			memcpy(&i16, packet + pkt_field->offset, pkt_field->size);			return i16;		case 4:			memcpy(&i32, packet + pkt_field->offset, pkt_field->size);			return i32;		default:			return -1;	}}int listen_for_mcast(int model, unsigned char *packet, int packet_size, char *listen_addr) {	char errmsg[80];	/* socket handle, and various flow control and	 * testing variables */	int socket_handle, retval;	/* socket variables for establishing the multicast socket */	struct ip_mreq mreq;	struct sockaddr_in client, server;	struct in_addr mcast_addr;	struct hostent *mcast_host;	socklen_t client_len;	int server_port;	char mcast_group[16];	struct in_addr laddr;	/* to hold the timeout value */	struct timeval read_timeout;	/* for read/rhwrite/exception handling with timeout */	int select_val;	fd_set read_fd, write_fd, exception_fd;	/* read the values of the model's parameters */	strcpy(mcast_group,models[model].mcast_group);	server_port = models[model].server_port;	/* use the specified listen address if requested */	if(listen_addr == NULL) {		laddr.s_addr = INADDR_ANY;	} else {		inet_aton(listen_addr, &laddr);	}	/* get mcast address to listen to */	mcast_host=gethostbyname(models[model].mcast_group);	if(mcast_host==NULL) {		sprintf(errmsg, "Unknown multicast group: %s\n", mcast_group);		perror(errmsg);		return 1;	}	memcpy(&mcast_addr, mcast_host->h_addr_list[0],mcast_host->h_length);  	/* check given address is multicast */	if(!IN_MULTICAST(ntohl(mcast_addr.s_addr))) {		printf("Address is not multicast: %s\n", inet_ntoa(mcast_addr));		return 1;	}	/* create socket */	if( (socket_handle = socket(AF_INET,SOCK_DGRAM,0)) < 0) {		perror("Cannot create socket");		return 1;	}		/* bind port */	server.sin_family=AF_INET;	server.sin_addr.s_addr = INADDR_ANY;	server.sin_port=htons(server_port);  	if(bind(socket_handle, (struct sockaddr *) &server, sizeof(server))<0) {		sprintf(errmsg, "Unable to bind to port %d", server_port);		perror(errmsg);		return 1;	}	/* join multicast group */	mreq.imr_multiaddr.s_addr=mcast_addr.s_addr;	mreq.imr_interface.s_addr=laddr.s_addr;  	/* continue only if we successfully joined the multicast group */	if((retval = setsockopt(socket_handle,IPPROTO_IP,IP_ADD_MEMBERSHIP,			(void *) &mreq, sizeof(mreq))) == -1) {		sprintf(errmsg, "Cannot join multicast group %s\n", inet_ntoa(mcast_addr));		perror(errmsg);		return 1;	} else {		/* infinite server loop could go here */		client_len=sizeof(client);		/* select setup */		FD_ZERO(&read_fd);		FD_ZERO(&write_fd);		FD_ZERO(&exception_fd);				read_timeout.tv_sec = POLL_TIMEOUT;		read_timeout.tv_usec = 0;		FD_SET(socket_handle, &read_fd);		FD_SET(socket_handle, &write_fd);		FD_SET(socket_handle, &exception_fd);		if((select_val = select(socket_handle+1, &read_fd, 0, 0, &read_timeout)) == -1) {			perror("Select failed for socket");			/* free the memory in the packet buffer */			wfree(packet);			return 1;		} else {			if(! FD_ISSET(socket_handle, &read_fd)) {				printf("Could not find multicast stream. Please try again.\n");				/* free the memory in the packet buffer */				wfree(packet);				return 1;			}		}					/* read the data from the multicast packet of size packet_size */		if(recvfrom(socket_handle, packet, packet_size, 0, (struct sockaddr *) &client, &client_len) == -1) {			perror("Could not receive on socket");			return 1;		}		/* successful recvfrom, return packet */		return 0;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -