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

📄 agentadv.c

📁 mobile ip 在linux下的一种实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (dev != NULL &&	    setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, dev, IFNAMSIZ)) {		DEBUG(DEBUG_FLAG, "open_agent_icmp_socket - "		      "setsockopt(SOL_SOCKET, SO_BINDTODEVICE): %s\n",		      strerror(errno));		close(s);		return -1;	}	/* let the kernel filter out uninteresting ICMP messages */	ifilter.data = filter;	if (setsockopt(s, SOL_RAW, ICMP_FILTER, &ifilter, sizeof(ifilter)) < 0)	{		DEBUG(DEBUG_FLAG, "setsockopt: ICMP_FILTER failed: %s\n",		      strerror(errno));		/* do not send error code - the filtering is done in this		 * daemon instead */	}	/* join multicast groups 224.0.0.1 and 224.0.0.2 */	memset(&imr, 0, sizeof(imr));	if (dev != NULL) {		if (dyn_ip_get_ifaddr(dev, &imr.imr_interface) != 0) {			DEBUG(DEBUG_FLAG, "open_agent_icmp_socket - "			      "could not get ifaddr for %s; trying to "			      "continue without joining multicast groups\n",			      dev);			return s;		}	}        inet_aton("224.0.0.1", &imr.imr_multiaddr);        if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &imr,		       sizeof(struct ip_mreq)) < 0) {		DEBUG(DEBUG_FLAG, "setsockopt: IP_ADD_MEMBERSHIP failed: %s\n",		      strerror(errno));		/* try to live without multicast */        }        inet_aton("224.0.0.2", &imr.imr_multiaddr);        if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &imr,		       sizeof(struct ip_mreq)) < 0) {		DEBUG(DEBUG_FLAG, "setsockopt: IP_ADD_MEMBERSHIP failed: %s\n",		      strerror(errno));		/* try to live without multicast */        }#endif#ifdef DYN_TARGET_WINDOWS	int i;	s = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);	if (s < 0) {		DEBUG(DEBUG_FLAG, "socket(SOCK_RAW) failed: %s\n",		      strerror(errno));		return -1;	}	i = 1;	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *) &i, sizeof(i))	    < 0) {		DEBUG(DEBUG_FLAG, "socket(SOCK_RAW) failed: %s\n",		      strerror(errno));	}#endif	return s;}#ifdef DYN_TARGET_LINUX/** * send_agent_advertisement: * @s: packet socket (PF_PACKET, SOCK_DGRAM) * @dest: unicast destination address (HW) or %NULL for broadcast message * @destaddr: unicast destination address (IP) or %NULL for broadcast message * @ifindex: interface index *  * Make the agent advertisement message and send it. * If @dest is %NULL, use defined broadcast or multicast destination and * set the TTL to one. * * Returns: *    0) no errors, *   -3) send failed */int send_agent_advertisement(int s, struct sockaddr *dest,			     struct in_addr *destaddr, int ifindex){	static __u16 next_agent_adv_seq = 0; /* counter used in determining 						the advertisement sequence 						number in _host_ byte order */	unsigned char buf[MAX_ADV_MSG];	struct iphdr *ip;	struct router_adv *radv;	struct agent_adv_ext *ext;	struct agent_adv_dynamics *own_ext;	int len, i, err;	struct sockaddr_ll bc_addr;	struct in_addr *addr, ownaddr, dstaddr;	char dev[IFNAMSIZ];	DEBUG(DEBUG_FLAG, "sending agent advertisement\n");	if (dest == NULL) {		dest = (struct sockaddr *) &bc_addr;		memset((char *) &bc_addr, 0, sizeof(bc_addr));		bc_addr.sll_family = AF_PACKET;		bc_addr.sll_protocol = htons(ETH_P_IP);		bc_addr.sll_ifindex = ifindex;		bc_addr.sll_hatype = htons(ARPHRD_ETHER);		bc_addr.sll_halen = ETH_ALEN; /* FIX: add support for other L2					       * devices */		memset(bc_addr.sll_addr, 0xff, sizeof(bc_addr.sll_addr));	}	if (destaddr == NULL) {		inet_aton(AGENT_ADV_DEST_IP, &dstaddr);		destaddr = &dstaddr;	}	memset(buf, 0, sizeof(buf));	DEBUG(DEBUG_FLAG, " * IP header, len=%i\n", sizeof(struct iphdr));	ip = (struct iphdr *) buf;	ip->ihl = 5;	ip->version = 4;	ip->ttl = dest == NULL ? 1 : 255;	ip->protocol = IPPROTO_ICMP;	ip->daddr = destaddr->s_addr;	if (dyn_ip_get_ifname(ifindex, dev) < 0 ||	    dyn_ip_get_ifaddr(dev, &ownaddr) < 0)		DEBUG(DEBUG_FLAG, "Could not get own address for agentadv\n");	ip->saddr = ip->saddr = ownaddr.s_addr;	len = sizeof(struct iphdr);	/* ICMP Router Advertisement message - see RFC 1256 and	 * RFC 2002, chapter 2 */	DEBUG(DEBUG_FLAG, " * header, len=%i\n", sizeof(struct router_adv));	radv = (struct router_adv *) (ip + 1);        radv->type = ICMP_ROUTERADVERT;        radv->code = 16; /* no common traffic routing; could also be 0			  * if the mobility agent handles also common			  * traffic */        radv->checksum = 0; /* set to zero for checksum calculation */	radv->num_addr = 0; /* Our implementation does not advertise general			     * routers */	radv->entry_size = 2;	/* maximum time that this agent advertisement is consider valid */	radv->lifetime = data.adv_lifetime;	len += sizeof(struct router_adv);	ext = (struct agent_adv_ext *) (buf + len);	ext->type = 16;	addr = (struct in_addr *) (ext + 1);	addr->s_addr = data.agent_own_addr;	addr++;	/* FIX: remove own address and use only HFA address (?) */	if (data.highest_fa_addr == 0 ||	    data.agent_own_addr == data.highest_fa_addr) {		ext->length = 10;	} else {		ext->length = 14;		/* Change "priority". Add highest FA address as the                   first entry */		addr->s_addr = data.agent_own_addr;		addr--;		addr->s_addr = data.highest_fa_addr;	}	/* Sequence Number - see RFC 2002, section 2.3.2 */	ext->seq = htons(next_agent_adv_seq);	if (next_agent_adv_seq < 0xffff)		next_agent_adv_seq++;	else		next_agent_adv_seq = 256;	/* maximum lifetime for tunnels */	ext->reg_lifetime = data.max_lifetime;	ext->opts = data.agent_adv_opt;	DEBUG(DEBUG_FLAG, " * agentadv ext, len=%i\n",	      radv->num_addr * sizeof(struct router_adv_router) + 2 +	      ext->length);	len += radv->num_addr * sizeof(struct router_adv_router) +		2 + ext->length;	DEBUG(DEBUG_FLAG, " * Dynamics ext, len=%i\n",	      sizeof(struct agent_adv_dynamics));	own_ext = (struct agent_adv_dynamics *) (buf + len);	own_ext->type = VENDOR_EXT_TYPE2;	own_ext->length = sizeof(struct agent_adv_dynamics) - 2;	own_ext->reserved = 0;	own_ext->vendor_id = htonl(VENDOR_ID_DYNAMICS);	own_ext->sub_type = htons(VENDOR_EXT_DYNAMICS_AGENTADV);	own_ext->version = VENDOR_EXT_VERSION;	own_ext->opts = data.own_agent_adv_opt;	own_ext->reserved2 = 0;#ifdef INCLUDE_IPAY	DEBUG(DEBUG_FLAG, "ADV: timePrice=%i, bytePrice=%i\n",	      ntohl(data.timePrice), ntohl(data.bytePrice));	if (own_ext->length >= sizeof(struct agent_adv_dynamics) - 2) {		own_ext->timePrice = data.timePrice;		own_ext->bytePrice = data.bytePrice;	} else {		DEBUG(DEBUG_FLAG, " * no price in adv\n");		own_ext->timePrice = 0;		own_ext->bytePrice = 0;	}#endif	len += sizeof(struct agent_adv_dynamics);	if (data.hfa_pubkey_hash != NULL) {		struct msg_key *hashext =			(struct msg_key *) (buf + len);		init_key_extension(hashext, VENDOR_EXT_DYNAMICS_PUBKEY_HASH,				   htonl(PUBKEY_ALG_SPI_RSA),				   data.hfa_pubkey_hash_len);		MOVE_UNALIGNED(MSG_KEY_DATA(hashext), data.hfa_pubkey_hash,			       data.hfa_pubkey_hash_len);		len += GET_KEY_EXT_LEN(hashext);		DEBUG(DEBUG_FLAG, " * pubkey hash, len=%i\n",		      GET_KEY_EXT_LEN(hashext));	}	if (data.fa_nai_extension != NULL) {		if (len + GET_NAI_EXT_LEN(data.fa_nai_extension) > MAX_ADV_MSG)		{			DEBUG(DEBUG_FLAG, "send_agent_advertisement - "			      "too small buffer for FA NAI extension\n");			return -3;		}		MOVE_UNALIGNED(buf + len, data.fa_nai_extension,			       GET_NAI_EXT_LEN(data.fa_nai_extension));		len += GET_NAI_EXT_LEN(data.fa_nai_extension);		DEBUG(DEBUG_FLAG, " * FA NAI, len=%i\n",		      GET_NAI_EXT_LEN(data.fa_nai_extension));	}	if (data.challenge != NULL) {		int j;		unsigned char *c;		if (len + GET_CHALLENGE_EXT_LEN(data.challenge) > MAX_ADV_MSG)		{			DEBUG(DEBUG_FLAG, "send_agent_advertisement - "			      "too small buffer for challenge extension\n");			return -3;		}		MOVE_UNALIGNED(buf + len, data.challenge,			       GET_CHALLENGE_EXT_LEN(data.challenge));		len += GET_CHALLENGE_EXT_LEN(data.challenge);		DEBUG(DEBUG_FLAG, " * Challenge, len=%i: ",		      GET_CHALLENGE_EXT_LEN(data.challenge));		c = MSG_CHALLENGE_EXT_DATA(data.challenge);		for (j = 0; j < GET_CHALLENGE_LEN(data.challenge); j++)			DEBUG(DEBUG_FLAG, "%02X", *c++);		DEBUG(DEBUG_FLAG, "\n");	}	DEBUG(DEBUG_FLAG, " * total len: %i\n", len);	radv->checksum = ip_checksum((unsigned char *) radv,				     len - sizeof(struct iphdr));	ip->tot_len = htons(len);	ip->check = 0;	ip->check = ip_checksum(buf, sizeof(*ip));        i = sendto(s, buf, len, 0, dest, sizeof(struct sockaddr_ll));	err = errno;	if (i < 0) {		DEBUG(DEBUG_FLAG, "send_agent_advertisement - sendto: %s\n",		      strerror(err));		return -3;	}        if (i != len) {		DEBUG(DEBUG_FLAG, "agent adv: wrote %d/%d\n", i, len);		return -3;        }#ifdef PACKET_DUMP	DEBUG_HEXDUMP(DEBUG_FLAG, "Send agentadv", buf, i);#endif	return 0;}#endif /* DYN_TARGET_LINUX *//** * send_agent_solicitation: * @s: *  * Make the agent solicitation message and send it * An Agent Solicitation message is identical to an ICMP Router Solicitation * [RFC1256] with the further restriction that the IP TTL field is set to 1. * [RFC2002] * * Returns: *    0) no errors, *   -1) setsockopt IP_TTL failed, *   -2) setsockopt SO_BROADCAST failed, *   -3) send failed */int send_agent_solicitation(int s){        struct agent_sol sol;	int len;        int i, err;#ifdef DYN_TARGET_LINUX	unsigned char ttl;#endif	struct sockaddr_in bc_addr;	DEBUG(DEBUG_FLAG, "sending agent solicitation\n");	memset((char *) &bc_addr, 0, sizeof(bc_addr));	bc_addr.sin_family = AF_INET;	inet_aton(AGENT_SOL_DEST_IP, &bc_addr.sin_addr);	/* FIX: agent solicitation sending does not yet work with Windows */#ifdef DYN_TARGET_LINUX	ttl = 1;	if (setsockopt(s, IPPROTO_IP, IP_TTL, &ttl, 1) < 0) {		DEBUG(DEBUG_FLAG, "setsockopt: IP_TTL failed: %s\n",		      strerror(errno));		return -1;	}#endif	i = 1;	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *) &i, sizeof(i))	    < 0) {		DEBUG(DEBUG_FLAG, "setsockopt: SO_BROADCAST failed: %s\n",		      strerror(errno));		return -2;	}	/* ICMP Agent solicitation - see RFC 1256 and RFC 2002 */        sol.type = 10;        sol.code = 0;        sol.checksum = htons(0); /* set to zero for checksum calculation */	sol.reserved = htonl(0);	len = sizeof(sol);	sol.checksum = ip_checksum((unsigned char *) &sol, len);        i = sendto(s, &sol, len, 0, (struct sockaddr *) &bc_addr,		   sizeof(struct sockaddr));	err = errno;	if (i < 0) {		DEBUG(DEBUG_FLAG,		      "send_agent_solicitation - sendto: %s\n", strerror(err));		return -3;	}        if (i != len) {                DEBUG(DEBUG_FLAG, "agent sol: wrote %d/%d\n", len, i);		return -3;        }	return 0;}#ifdef DYN_TARGET_LINUX/** * check_icmp_sol: * @s: * @data:

⌨️ 快捷键说明

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