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

📄 device_info.c

📁 mobile ip 在linux下的一种实现
💻 C
字号:
/* $Id: device_info.c,v 1.12 2001/09/08 14:29:40 jm Exp $ * Device information daemon in a unix domain socket * * Dynamic hierarchial IP tunnel * Copyright (C) 1998-2001, Dynamics group * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. *//* * Device info daemon can be used to query device priorities. It uses * configuration file by default in /etc/device_info.conf. The file * contains MAC addresses of devices and priorities to them.  */#ifndef _GNU_SOURCE#define _GNU_SOURCE#endif#include <stdio.h>#include <stdarg.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <time.h>#include <getopt.h>#include <unistd.h>#include <signal.h>#include <arpa/inet.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#include <sys/param.h>#include <sys/ioctl.h>#include <linux/if.h>#include "util.h"#include "dyn_mnlib.h"#include "agentapi.h"#include "fixed_fd_zero.h"#include "device_info.h"#include "dyn_ip.h"#define PID_FILE "/var/run/device_info.pid"#define MAXLINE 100static char *default_socket_path = DEFAULT_DEVICE_INFO_PATH;static char *default_config_file_path = "/etc/device_info.conf";static char *config_file_path = NULL;static char *socket_path = NULL;static fd_set set;static int debug = 0;static struct device_info_config *config = NULL;struct device_info_config {	unsigned char hw[ETH_ALEN];	int priority;	int line;	struct device_info_config *next;};void DEBUG(char *format, ...){	va_list ap;	if (!debug)		return;	va_start(ap, format);	vfprintf(stdout, format, ap);	fflush(stdout);	va_end(ap);}static int open_socket(char *path){	if (!path) {		fprintf(stderr, "open_socket: path is NULL\n");		return -1;	}	return api_open_socket(path, NULL, NULL, (int)0666);}static void clean_up(int sig){	unlink(PID_FILE);	exit(sig);}static struct device_info_config *find_entry(char *hw){	struct device_info_config *conf = config;	if (hw == NULL)		return NULL;	while (conf != NULL) {		if (!memcmp(hw, conf->hw, ETH_ALEN))			return conf;		conf = conf->next;	}	return NULL;} static int send_reply(int sock, struct sockaddr_un *addr,		      struct device_info_query *query){	int r;	if (addr == NULL || query == NULL) {		fprintf(stderr, "send_reply: NULL argument\n");		return -1;	}	DEBUG("\tsending reply: index = %d, prio %d\n",	      query->device_index, query->priority);	r = sendto(sock, query, sizeof(struct device_info_query), 0,		   (struct sockaddr *)addr, sizeof(struct sockaddr_un));	if (r != sizeof(struct device_info_query)) {		fprintf(stderr, "send_reply: sendto %d/%d bytes: %s\n",			r, sizeof(query), strerror(errno));		return -1;	}		return r;}static int handle_request(int sock){	struct sockaddr_un addr;	struct device_info_query query;	struct device_info_config *config;	struct idxmap *idxmap, *idx;	struct ifreq ifr;	int n, len, found = 0, s;	len = sizeof(addr);	n = recvfrom(sock, &query, sizeof(query), 0, (struct sockaddr *) &addr,		     (unsigned int *)&len);	if (n != sizeof(query)) {		fprintf(stderr, "handle_request: couldn't receive whole "			"message %d/%d\n", n, sizeof(query));		return -1;	}		DEBUG("received query\n\tquery.device_index = %d\n", 	      query.device_index);	memset(&ifr, 0, sizeof(ifr));	/* find interface name for the index */	idxmap = dyn_ip_get_interface_map();	idx = idxmap;	while (idx != NULL) {		if (idx->index == query.device_index) {			memcpy(ifr.ifr_name, idx->name, sizeof(ifr.ifr_name));			DEBUG("\tdevice name: %s\n", ifr.ifr_name);			found = 1;			break;		}		idx = idx->next;	}	dyn_ip_free_interface_map(idxmap);	if (!found) {		fprintf(stderr, "handle_request: Couldn't find ifname\n");		return -1;	} 	ifr.ifr_ifindex = query.device_index;	s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);	if (s < 0) {		fprintf(stderr, "handle_request: socket failed: %s\n",		      strerror(errno));		return -1;	}	if (ioctl(s, SIOCGIFHWADDR, &ifr) != 0) {		fprintf(stderr, "handle_request: SIOCGIFHWADDR ioctl: %s\n",			strerror(errno));		return -1;	}	config = find_entry(ifr.ifr_hwaddr.sa_data);	found = 1;	if (!config) {		DEBUG("handle_request: entry not found (%s)\n", 		       ether_hwtoa((unsigned char *)&ifr.ifr_hwaddr.sa_data));		found = 0;		query.priority = -2; /* entry not found */	} else {		query.priority = config->priority;		DEBUG("\tquery.priority = %d\n", query.priority);	}		/* reply */	n = send_reply(sock, &addr, &query);	if (n < 0) {		fprintf(stderr, "handle_request: Couldn't send reply\n");		return -1;	}	return 0;}static void parse_config(int sig){	FILE *file;	char buffer[MAXLINE];	struct device_info_config *conf = config, *first = config;	int line = 0, n;	unsigned int hw[6];	if (debug && sig == SIGHUP)		DEBUG("HUP signal received. Rereading config file\n");	if (config_file_path == NULL) {		fprintf(stderr, "parse_config: path is NULL\n");		return;	}	file = fopen(config_file_path, "r");	if (file == NULL) {		fprintf(stderr, "parse_config: Can't open file %s\n",			strerror(errno));		return;	}		while (fgets(buffer, MAXLINE, file) != NULL) {		buffer[strlen(buffer)-1]='\0';		++line;		if (buffer[0] == '#' || 		    buffer[0] == '\n' || 		    buffer[0] == '\t' ||		    buffer[0] == ' ' ||		    strlen(buffer) == 0) {			continue;		}		if (conf == NULL) {			DEBUG("Reading first time the configuration file\n");			conf = malloc(sizeof(struct device_info_config));			first = conf;		}		else {			conf->next = malloc(sizeof(struct device_info_config));			conf = conf->next;		}		if (conf == NULL) {			fprintf(stderr, "parse_config: Memory allocation "				"failed\n");			fclose(file);			return;		}		n = sscanf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x %d", 			   &hw[0], &hw[1], &hw[2], &hw[3], &hw[4], &hw[5], 			   &conf->priority);		if (n != 7) {			fprintf(stderr, "parse_config: Couldn't parse "				"line %d '%s'\n", line, buffer);			fclose(file);			return;		}		conf->line = line;		conf->hw[0] = (unsigned char)hw[0];		conf->hw[1] = (unsigned char)hw[1];		conf->hw[2] = (unsigned char)hw[2];		conf->hw[3] = (unsigned char)hw[3];		conf->hw[4] = (unsigned char)hw[4];		conf->hw[5] = (unsigned char)hw[5];		DEBUG("%s prio %d (line %d)\n", 		      ether_hwtoa((unsigned char *)conf->hw), 		      conf->priority, conf->line);	}	fclose(file);	config = first;	return;}int main(int argc, char *argv[]){	int s, foreground = 0, c, n;	socket_path = default_socket_path;	config_file_path = default_config_file_path;	while (1) {		int option_index = 0;		static struct option long_options[] = {			{"fg", no_argument, NULL, 'f'},			{"debug", no_argument, NULL, 'd'},			{0, 0, 0, 0}		};				c = getopt_long (argc, argv, "fdc:s:",				 long_options, &option_index);		if (c == -1)			break;				switch (c) {		case 'f':			switch (option_index) {			case 0:				fprintf(stderr,"Option: %s\n",				      long_options[option_index].name);				foreground = 1;			}			break;		case 'c':			config_file_path = malloc(MAXPATHLEN);			if (config_file_path == NULL) {				fprintf(stderr, "malloc for config: %s\n",					strerror(errno));				exit(1);			}			dynamics_strlcpy(config_file_path, optarg, MAXPATHLEN);			break;		case 's':			socket_path = malloc(MAXPATHLEN);			if (socket_path == NULL) {				fprintf(stderr, "malloc for path: %s\n",					strerror(errno));				exit(1);			}			dynamics_strlcpy(socket_path, optarg, MAXPATHLEN);			break;		case 'd':			debug = 1;			break;		case '?':			fprintf(stderr, "device_info -c <configuration file> "				"[-s <API socket>] [--fg]\n");			exit(1);		default:			fprintf(stderr, "?? getopt returned character code "				"0%o ??\n", c);		}	}	parse_config(0);	if (config == NULL) {		fprintf(stderr, "Configuration file parsing failed\n");		exit(1);	}	s = open_socket(socket_path);	if (s < 0) {		fprintf(stderr, "Open socket failed\n");		exit(1);	}	DEBUG("Initializing mn admin socket path\n");	c = dynamics_mn_init(NULL);	if (c == API_FAILED || c == API_ERROR) {		fprintf(stderr, "MN admin socket path initialization "			"failed\n");		exit(1);	}	DEBUG("Registering device info socket path\n");	if (dynamics_mn_register_dev_info_socket(socket_path, 3) 	    != API_SUCCESS) {		fprintf(stderr, "API device info socket initialization "			"failed\n");		exit(1);	}	DEBUG("\tregistered\n");	if (!foreground && dynamics_fork_daemon() < 0) {		fprintf(stderr, "fork failed\n");		exit(1);	}	dynamics_write_pid_file(PID_FILE);	signal(SIGHUP, parse_config);	signal(SIGTERM, clean_up);	signal(SIGINT, clean_up);	for (;;) {		FD_ZERO(&set);		FD_SET(s, &set);		n = select(FD_SETSIZE, &set, NULL, NULL, NULL);		if (n < 0 && errno != EINTR)			fprintf(stderr, "select: %s\n",				strerror(errno));	  		if (n == 1 && FD_ISSET(s, &set))			handle_request(s);	}	return 0;}

⌨️ 快捷键说明

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