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

📄 agentadv.c

📁 mobile ip 在linux下的一种实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: agentadv.c,v 1.82 2001/09/29 18:29:51 jm Exp $ * ICMP Agent Advertisement/Solicitation routines * * 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 "config.h"#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netdb.h>#include <netinet/ip_icmp.h>#ifdef DYN_TARGET_LINUX#include <netinet/udp.h>#endif#include <arpa/inet.h>#include <assert.h>#include <string.h>#include <errno.h>#include <net/if.h>#include <asm/types.h>#include <unistd.h>#include <features.h>    /* for the glibc version number */#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1#include <netpacket/packet.h>#include <net/ethernet.h>     /* the L2 protocols */#include <netinet/if_ether.h>#else#ifdef DYN_TARGET_LINUX#include <linux/if_packet.h>#include <linux/if_ether.h>   /* The L2 protocols */#endif#endif#include "owntypes.h"#ifdef DYN_TARGET_LINUX#include <linux/filter.h>#endif#ifndef ETHERTYPE_IP#define ETHERTYPE_IP 0x0800 /* IP */#endif#include "message.h"#include "agentadv.h"#include "dyn_ip.h"#include "util.h"#include "debug.h"#define DEBUG_FLAG 'a'/* couple of definitions from <linux/icmp.h> if they are not available * from the netinet/ip_icmp.h */#ifndef ICMP_FILTER#define ICMP_FILTER                     1struct icmp_filter {        __u32           data;};#endif#ifndef SOL_RAW#define SOL_RAW 255#endif#ifndef SO_BINDTODEVICE#define SO_BINDTODEVICE 25#endif/* RFC 2002, sec. 2.1: * the IP destination address of an Agent Advertisement MUST be either the * "all systems on this link" multicast address (224.0.0.1) [5] or the * "limited broadcast" address (255.255.255.255) */#define AGENT_ADV_DEST_IP "255.255.255.255"#define AGENT_SOL_DEST_IP "255.255.255.255"static struct agentadv_setup_data data;/** * set_agent_adv_data: * @_max_lifetime:  * @_highest_fa_addr:  * @_agent_own_addr:  * @_agent_adv_opt:  * @_own_agent_adv_opt:  * @_adv_lifetime:  * @hfa_pubkey_hash:  * @hfa_pubkey_hash_len:  *  *  */void set_agent_adv_data(__u16 _max_lifetime, struct in_addr _highest_fa_addr,			struct in_addr _agent_own_addr, __u16 _agent_adv_opt,			__u8 _own_agent_adv_opt, __u16 _adv_lifetime,			unsigned char *hfa_pubkey_hash,			int hfa_pubkey_hash_len){	data.max_lifetime = htons(_max_lifetime);	data.adv_lifetime = htons(_adv_lifetime);	data.highest_fa_addr = (__u32)_highest_fa_addr.s_addr;	data.agent_own_addr = (__u32)_agent_own_addr.s_addr;	data.agent_adv_opt = htons(_agent_adv_opt);	data.own_agent_adv_opt = _own_agent_adv_opt;	data.hfa_pubkey_hash = hfa_pubkey_hash;	data.hfa_pubkey_hash_len = hfa_pubkey_hash_len;	data.fa_nai_extension = NULL;	data.challenge = NULL;}/** * set_agent_adv_nai: * @nai_ext:  *  *  */void set_agent_adv_nai(struct fa_nai_ext *nai_ext){	data.fa_nai_extension = nai_ext;}void set_agent_adv_challenge(struct challenge_ext *challenge){	data.challenge = challenge;}#ifdef INCLUDE_IPAY/** * set_agent_adv_ipay: * @timePrice:  * @bytePrice:  *  *  */void set_agent_adv_ipay(__u32 timePrice, __u32 bytePrice){	data.timePrice = htonl(timePrice);	data.bytePrice = htonl(bytePrice);}#endifstatic int user_space_filter = AGENTADV_FILTER_NONE;static int ok_buf(char *buf){	__u8 proto;#ifdef DYN_TARGET_LINUX	struct iphdr *_ip = (struct iphdr *) buf;	struct router_adv *_radv =		(struct router_adv *) (buf + sizeof(struct iphdr));#else	struct iphdr *_ip =		(struct iphdr *) (buf + sizeof(struct ethhdr));	struct router_adv *_radv =		(struct router_adv *) (buf + sizeof(struct ethhdr)				       + sizeof(struct iphdr));#endif	memcpy(&proto, &_ip->protocol, 1);	if (proto != IPPROTO_ICMP)		return 0;	if (user_space_filter == AGENTADV_FILTER_ADV &&	    _radv->type != ICMP_ROUTERADVERT)		return 0;	if (user_space_filter == AGENTADV_FILTER_SOL &&	    _radv->type != ICMP_ROUTERSOLICIT)		return 0;	return 1;}#ifdef DYN_TARGET_LINUX/* iphdr - 20 octets */static struct sock_filter agentadv_filter[] = {	/* A <- P[9:1] - load byte - IP protocol */	BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 9),	/* pc += (A == IPPROTO_ICMP) ? 0 : 3 */	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_ICMP, 0, 3),	/* A <- P[20:1] - load byte - ICMP type */	BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 20),	/* pc += (A == 9) ? 0 : 1 (agentadv) */	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 9, 0, 1),	BPF_STMT(BPF_RET+BPF_K, (__u32)-1), /* accept the packet */	BPF_STMT(BPF_RET+BPF_K, 0) /* filter packet */};static struct sock_fprog agentadv_fprog = {	sizeof(agentadv_filter) / sizeof(struct sock_filter),	agentadv_filter};/* iphdr - 20 octets */static struct sock_filter agentsol_filter[] = {	/* A <- P[9:1] - load byte - IP protocol */	BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 9),	/* pc += (A == IPPROTO_ICMP) ? 0 : 3 */	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_ICMP, 0, 3),	/* A <- P[20:1] - load byte - ICMP type */	BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 20),	/* pc += (A == 10) ? 0 : 1 (agentsol) */	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 10, 0, 1),	BPF_STMT(BPF_RET+BPF_K, (__u32)-1), /* accept the packet */	BPF_STMT(BPF_RET+BPF_K, 0) /* filter packet */};static struct sock_fprog agentsol_fprog = {	sizeof(agentsol_filter) / sizeof(struct sock_filter),	agentsol_filter};static struct sock_filter udp434_filter[] = {	/* A <- P[9:1] - load byte - IP protocol */	BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 9),	/* pc += (A == IPPROTO_ICMP) ? 0 : 3 */	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_UDP, 0, 3),	/* A <- P[20:1] - load half word - dest port */	BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 22),	/* pc += (A == 434) ? 0 : 1 (agentadv) */	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 434, 0, 1),	BPF_STMT(BPF_RET+BPF_K, (__u32)-1), /* accept the packet */	BPF_STMT(BPF_RET+BPF_K, 0) /* filter packet */};static struct sock_fprog udp434_fprog = {	sizeof(udp434_filter) / sizeof(struct sock_filter),	udp434_filter};#endif/** * open_agent_icmp_adv_socket: * @dev:  *  *  *  * Returns:  */int open_agent_icmp_adv_socket(char *dev, int filter){#ifdef DYN_TARGET_LINUX	int s, i;	struct sockaddr_ll sa;	struct ifreq ifr;	memset(&ifr, 0, sizeof(ifr));	memset(&sa, 0, sizeof(sa));	s = socket(PF_PACKET, SOCK_DGRAM, htons(ETHERTYPE_IP));	if (s < 0) {		if (errno == EPERM)			DEBUG(DEBUG_FLAG, "Must be run as root\n");		DEBUG(DEBUG_FLAG, "open_agent_icmp_adv_socket - socket: %s\n",		      strerror(errno));		return -1;	}	if (filter == AGENTADV_FILTER_ADV &&	    setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER,		       &agentadv_fprog, sizeof(agentadv_fprog)) < 0) {		DEBUG(DEBUG_FLAG, "open_agent_icmp_adv_socket - setsockopt: "		      "%s\n", strerror(errno));		user_space_filter = filter;	} else if (filter == AGENTADV_FILTER_SOL &&		   setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER,			      &agentsol_fprog, sizeof(agentsol_fprog)) < 0) {		DEBUG(DEBUG_FLAG, "open_agent_icmp_adv_socket - setsockopt: "		      "%s\n", strerror(errno));		user_space_filter = filter;	} else if (filter == UDP_FILTER_PORT434 &&		   setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER,			      &udp434_fprog, sizeof(udp434_fprog)) < 0) {		DEBUG(DEBUG_FLAG, "open_agent_icmp_adv_socket - setsockopt: "		      "%s\n", strerror(errno));	}	i = strlen(dev);	if (i >= sizeof(ifr.ifr_name)) {		DEBUG(DEBUG_FLAG, "open_agent_icmp_adv_socket: too long "		      "interface parameter\n");		return -1;	}	memcpy(ifr.ifr_name, dev, i + 1);	if (ioctl(s, SIOCGIFINDEX, &ifr) != 0) {		DEBUG(DEBUG_FLAG, "open_agent_icmp_adv_socket(%s): ioctl: "		      "%s\n", dev, strerror(errno));		close(s);		return -1;	}	sa.sll_family = AF_PACKET;	sa.sll_ifindex = ifr.ifr_ifindex;	if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) {		DEBUG(DEBUG_FLAG, "open_agent_icmp_adv_socket - bind: %s\n",		      strerror(errno));		return -1;	}	return s;#endif#ifdef DYN_TARGET_WINDOWS	struct sockaddr_in addr;	int s;	/* FIX: should use something to get the real ICMP packets with ethernet	 * header.. */	DEBUG(DEBUG_FLAG, "ICMP adv socket as a UDP kludge\n");        if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {		DEBUG(DEBUG_FLAG, "open_agent_icmp_socket - socket: %s\n",		      strerror(errno));		return -1;        }	memset(&addr, 0, sizeof(addr));	addr.sin_family = AF_INET;	addr.sin_addr.s_addr = htonl(INADDR_ANY);	addr.sin_port = htons(4344);	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {		DEBUG(DEBUG_FLAG, "bind: %s\n", strerror(errno));		close(s);		return -1;	}	return s;#endif}/** * open_agent_icmp_socket: * @dev: if != NULL then the socket will be bound to a local address * used for the device in order to send the broadcast messages to the * specified device  * @filter: *  * Returns:  */int open_agent_icmp_socket(char *dev, __u32 filter){	int s;#ifdef DYN_TARGET_LINUX        struct protoent *proto;	struct icmp_filter ifilter;	struct ip_mreq imr;	if (!(proto = getprotobyname("icmp"))) {		DEBUG(DEBUG_FLAG,		      "getprotobyname - unknown protocol icmp - %s\n",		      strerror(errno));		return -1;        }        if ((s = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) {		if (errno == EPERM)			DEBUG(DEBUG_FLAG, "Must be run as root\n");		DEBUG(DEBUG_FLAG, "open_agent_icmp_socket - socket: %s\n",		      strerror(errno));		return -1;        }

⌨️ 快捷键说明

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