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

📄 agent_utils.c

📁 mobile ip 在linux下的一种实现
💻 C
字号:
/* $Id: agent_utils.c,v 1.13 2001/06/23 22:23:51 jm Exp $ * Independent help routines for FA and HA * * 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. */#include <stdlib.h>#include <syslog.h>#include <string.h>#include <errno.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include "agent_utils.h"#include "message.h"#include "rsa_dyn.h"#include "debug.h"#include "md5_mac.h"#include "binding.h"#include "util.h"#define DEBUG_FLAG 'u'/** * dynamics_do_rsa_encrypt: * @sk: pointer to session key * @sk_len: session key length in bytes * @pubkey: pointer to other end-point's public key extension * * Encrypt session key @sk (@sk_len bytes) for another FA using its public * key (@pubkey). This function allocates memory and the caller must take care * of releasing the returned memory area. * * Returns: *   A pointer to initialized FA pubkey reply extension of %NULL on failure. */struct msg_key *dynamics_do_rsa_encrypt(unsigned char const *sk, int sk_len,			const struct msg_key *pubkey){	unsigned int e_len;	unsigned char *e_sk;	struct msg_key *keyrep;	e_sk = rsa_encrypt_session_key(sk, sk_len, MSG_KEY_DATA(pubkey),				       GET_KEY_LEN(pubkey), &e_len);	if (e_sk == NULL || e_len <= 0 || e_len > (255 - SPI_LEN)) {		DEBUG(DEBUG_FLAG, "RSA encryption failed\n");		if (e_sk != NULL)			free(e_sk);		return NULL;	}	keyrep = (struct msg_key *) malloc(sizeof(struct msg_key) + e_len);	if (keyrep == NULL) {		DEBUG(DEBUG_FLAG, "Not enough memory for keyrep\n");	} else {		init_key_extension(keyrep, VENDOR_EXT_DYNAMICS_FA_PUBKEYREP,				   pubkey->spi, e_len);		memcpy(MSG_KEY_DATA(keyrep), e_sk, e_len);	}	free(e_sk);	return keyrep;}/** * dynamics_check_sendto: * @ret: The return value of a sendto system call or -2 if error was already *       reported * @len: The number of bytes that was intended to be sent *       by sendto() * @error: String to include in error message *  * Prints an error message if len != ret. This function is meant * to be called after a sendto system call.  *  * Returns: 0 if there was no error in the original sendto call, *          else -1 */intdynamics_check_sendto(int ret, int len, char *error){	if (ret == -2)		return -1; /* send address not OK - already reported */	if (ret < 0) {		syslog(LOG_INFO, "%s: sendto(%i/%i): %s", error, ret, len,		       strerror(errno));		DEBUG(DEBUG_FLAG, "%s: sendto(%i/%i): %s\n", error, ret, len,		      strerror(errno));		return -1;	} else if (ret != len) {		syslog(LOG_INFO, "%s: sendto: only %i/%i bytes sent", error,		       ret, len);		DEBUG(DEBUG_FLAG, "%s: sendto: only %i/%i bytes sent\n", error,		      ret, len);		return -1;	}	return 0;}/** * dynamics_open_udp_socket: * @socket_priority: Set the socket priority, -1 for default priority * @addr: If set, only listen to the given address * @port: Port number to listen to * @dev: If set, force the use of the given device * * Sets up a UDP socket with the IP_RECVTTL and IP_PKTINFO socket options; * see ip(7) for details. * If a socket priority is given, the SO_PRIORITY option is set. If * dev is non-NULL the socket is bound to the given device name with * SO_BINDTODEVICE. See socket(7) for details. *  * Returns: If successful, the file descriptor for the socket, else -1 */intdynamics_open_udp_socket(int socket_priority, struct in_addr addr,			 short int port, char *dev){	struct sockaddr_in serv_addr;	int s, one = 1;	/* Socket for registration request and updates */	s = socket(AF_INET, SOCK_DGRAM, 0);	if (s < 0) {		perror("socket");		return -1;	}	if (dev != NULL &&	    setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, dev, IFNAMSIZ)) {		DEBUG(DEBUG_FLAG, "dynamics_open_udp_socket - "		      "setsockopt(SOL_SOCKET, SO_BINDTODEVICE): %s\n",		      strerror(errno));		close(s);		return -1;	}	/* bind the address and port to listen to registration	 * requests (usually UDP port 434) */	memset((char *) &serv_addr, 0, sizeof(serv_addr));	serv_addr.sin_family = AF_INET;	serv_addr.sin_addr.s_addr = addr.s_addr;	serv_addr.sin_port = htons(port);	if (bind(s, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {		char error[20];		snprintf(error, 20, "bind[UDP%d]", port);		perror(error);		close(s);		return -1;	}	if (setsockopt(s, SOL_IP, IP_RECVTTL, 		       (const void *)&one, sizeof(one)) < 0) {		DEBUG(DEBUG_FLAG,		     "dynamics_open_udp_socket - setsockopt(SOL_IP, "		      "IP_RECVTTL): %s\n", strerror(errno));		/* continue without IP_RECVTTL */	}	if (setsockopt(s, SOL_IP, IP_PKTINFO, 		       (const void *)&one, sizeof(one)) < 0) {		DEBUG(DEBUG_FLAG,		     "dynamics_open_udp_socket - setsockopt(SOL_IP, "		      "IP_PKTINFO): %s\n", strerror(errno));		/* continue without IP_PKTINFO */	}	if (socket_priority > -1 &&	    setsockopt(s, SOL_SOCKET, SO_PRIORITY,		       (const void *)&socket_priority,		       sizeof(socket_priority)) < 0) {		DEBUG(DEBUG_FLAG,		      "dynamics_open_udp_socket - setsockopt SO_PRIORITY: "		      "%s\n", strerror(errno));		/* continue without SO_PRIORITY */	}	DEBUG(DEBUG_FLAG, "Listening UDP on %s:%i dev[%s]\n",	      inet_ntoa(serv_addr.sin_addr),	      ntohs(serv_addr.sin_port),	      dev != NULL ? dev : "N/A");	return s;}/* glibc 2.1 seems to have more or less too strict checking of message length * bug? >= should be == ? * Well... using these routines from kernel headers.. */static struct cmsghdr * dynamics_cmsg_nxthdr2(void *__ctl, size_t __size,					      struct cmsghdr *__cmsg){        struct cmsghdr * __ptr;        __ptr = (struct cmsghdr *) (((unsigned char *) __cmsg) +				    CMSG_ALIGN(__cmsg->cmsg_len));        if ((unsigned long) ((char *) (__ptr+1) - (char *) __ctl) > __size)                return NULL;        return __ptr;}struct cmsghdr * dynamics_cmsg_nxthdr(struct msghdr *__msg,				      struct cmsghdr *__cmsg){        return dynamics_cmsg_nxthdr2(__msg->msg_control, __msg->msg_controllen,				     __cmsg);}

⌨️ 快捷键说明

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