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

📄 agentapi.c

📁 mobile ip 在linux下的一种实现
💻 C
字号:
/* $Id: agentapi.c,v 1.15 2001/09/08 16:51:58 jm Exp $ * API support routines for agents * * 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. */#define DEBUG_FLAG 'P'#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <sys/un.h>#include <unistd.h>#include <fcntl.h>#include <grp.h>#include <pwd.h>#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#include <assert.h>#include "debug.h"#include "agentapi.h"/* defines */#define ASSERT assert/* Open unix domain socket for API using given parameters. * Parameters: *  path        - path for UNIX domain socket or NULL to assign unique *                address in the abstract namespace *  group_name  - group for the socket *  owner       - owner of the socket *  permissions - permissions for to socket * Returns socket descriptor or -1 on error. */int api_open_socket(char *path, char *group_name, char *owner, int permissions){#ifdef DYN_TARGET_LINUX	struct group *grp;	struct passwd *pwd;	int s;	dyn_api_sockaddr addr;	socklen_t addrlen;	int flags;	/* create socket */	s = socket(AF_LOCAL, SOCK_DGRAM, 0);	if (s < 0) {		DEBUG(DEBUG_FLAG, "api_open_socket: socket failed %s\n",		      strerror(errno));		return s;	}	/* Set non-blocking */	flags = fcntl(s, F_GETFL, 0);	if (flags == -1) {		DEBUG(DEBUG_FLAG, "api_open_socket: fcntl F_GETFL failed: "		      "%s\n", strerror(errno));		return -1;	}	if (fcntl(s, F_SETFL, flags | O_NDELAY) == -1) {		DEBUG(DEBUG_FLAG, "api_open_socket: fcntl F_SETFL failed: "		      "%s\n", strerror(errno));		return -1;	}	/* remove old api socket */	if (path != NULL && unlink(path) < 0 && errno != ENOENT) {		DEBUG(DEBUG_FLAG, "api_open_socket: unlink failed: %s\n",		      strerror(errno));		return -1;	}	/* bind to address */	memset((char *) &addr, 0, sizeof(addr));	addr.sun_family = AF_LOCAL;	if (path == NULL) {		addr.sun_path[0] = '\0';		snprintf(addr.sun_path + 1, sizeof(addr.sun_path) - 1,			 "dynamics-%i-%i", getpid(), (int) random());		addrlen = sizeof(addr.sun_family) + 1 +			strlen(addr.sun_path + 1);	} else {		snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path);		addrlen = sizeof(addr.sun_family) + strlen(addr.sun_path);	}	if (bind(s, (struct sockaddr *) &addr, addrlen) < 0) {		DEBUG(DEBUG_FLAG, "api_open_socket: bind failed: %s\n",		      strerror(errno));		return -1;	}	if (path == NULL)		return s;	if (permissions != 0) {		/* Set permissions */		if (chmod(path, (mode_t) permissions) < 0) {			DEBUG(DEBUG_FLAG, "api_open_socket: chmod failed: "			      "%s\n", strerror(errno));			return -1;		}	}	if (group_name != NULL && owner != NULL) {		grp = getgrnam(group_name);		if (grp == NULL) {			DEBUG(DEBUG_FLAG, "api_open_socket: getgrnam failed "			      "(group=%s)\n", group_name);			return -1;		}		pwd = getpwnam(owner);		if (pwd == NULL) {			DEBUG(DEBUG_FLAG, "api_open_socket: getpwnam failed "			      "(user=%s)\n", owner);			return -1;		}		if (chown(path, pwd->pw_uid, grp->gr_gid) < 0) {			DEBUG(DEBUG_FLAG, "api_open_socket: chown failed: "			      "%s\n", strerror(errno));			return -1;		}	}	return s;#else	return -1;#endif}/* Receive API message from socket s. * Paramters: *  s       - socket *  addr    - storage for source address *  addrlen - length of addr *  msg     - buffer for the message * Source address is stored in addr and message in msg. * Size of receive buffer for msg is in sz. * Returns 0 on success and -1 on error. */int api_receive(int s, dyn_api_sockaddr *addr, socklen_t *addrlen,		struct api_msg *msg){	int n;#ifndef DYN_TARGET_WINDOWS	int i;	char *c;#endif	ASSERT(s != -1);	ASSERT(addr != NULL);	ASSERT(msg != NULL);	*addrlen = sizeof(dyn_api_sockaddr);	n = recvfrom(s, (void *) msg, sizeof(struct api_msg), 0,		     (struct sockaddr *) addr, addrlen);	if (n < 0) {		DEBUG(DEBUG_FLAG, "api_receive: recvfrom failed: %s\n",		      strerror(errno));		return -1;	}#ifndef DYN_TARGET_WINDOWS	c = (char *) addr->sun_path;	DEBUG(DEBUG_FLAG, "API Received %d bytes from ", n);	for (i = 0; i < *addrlen; i++) {		if (*c >= 32 && *c <= 126) {			DEBUG(DEBUG_FLAG, "%c", *c);		} else {			DEBUG(DEBUG_FLAG, "<%02x>", *c);		}		c++;	}	DEBUG(DEBUG_FLAG, "\n");#endif	if (n < API_MSG_FIXED_LEN ||	    n < API_MSG_FIXED_LEN + msg->length ||	    (msg->type != 1 && msg->type != 0 )) {		/* message is not valid */		DEBUG(DEBUG_FLAG, "api_receive: invalid message\n");		return -1;	}	return 0;}/* Send an API message msg through socket s to addr. * Return -1 on error and 0 on success */int api_send(int s, dyn_api_sockaddr *addr, socklen_t addrlen,	     struct api_msg *msg){	int n;	ASSERT(s != -1);	ASSERT(addr != NULL);	ASSERT(msg != NULL);	ASSERT(msg->length < API_DATA_SIZE);	n = sendto(s, (void *) msg, API_MSG_FIXED_LEN + msg->length, 0,		   (struct sockaddr *) addr, addrlen);	if (n < 0) {		DEBUG(DEBUG_FLAG, "api_send: sendto failed: %s\n",		      strerror(errno));		return -1;	}#ifdef DYN_TARGET_LINUX	DEBUG(DEBUG_FLAG, "API Sent %d/%d bytes to %s\n", n,	      API_MSG_FIXED_LEN + msg->length, addr->sun_path);#endif#ifdef DYN_TARGET_WINDOWS	DEBUG(DEBUG_FLAG, "API Sent %d/%d bytes to %s:%d\n", n,	      API_MSG_FIXED_LEN + msg->length, inet_ntoa(addr->sin_addr),	      ntohs(addr->sin_port));#endif	if (n != msg->length + API_MSG_FIXED_LEN) {		return -1;	}	return 0;}int api_send_reply(int s, dyn_api_sockaddr *addr, socklen_t addrlen, int code,		   unsigned char *data, int datalen){	struct api_msg msg;	ASSERT(datalen < API_DATA_SIZE);	msg.type = API_REPLY_MSG;	msg.code = code;	msg.length = datalen;	memcpy(msg.params, data, msg.length);	return api_send(s, addr, addrlen, &msg);}/* Close a unix domain socket and unlink it */void api_close_socket(int s){#ifdef DYN_TARGET_LINUX	dyn_api_sockaddr name;	unsigned int len;#endif	if (s < 0) return;#ifdef DYN_TARGET_LINUX	len = sizeof(name);	if (getsockname(s, (struct sockaddr *)&name, &len) == 0)		unlink(name.sun_path);#endif	close(s);}

⌨️ 快捷键说明

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