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

📄 agentadv_test.c

📁 mobile ip 在linux下的一种实现
💻 C
字号:
/* $Id: agentadv_test.c,v 1.34 2001/08/11 20:01:43 jm Exp $ * ICMP Agent Adv/Sol tests * * 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 <stdio.h>#include <string.h>#include <netinet/in.h>#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <unistd.h>#include <arpa/inet.h>#include <netinet/ip.h>#include <netinet/ip_icmp.h>#include <time.h>#include "message.h"#include "agentadv.h"#include "debug.h"#include "dyn_ip.h"#include "util.h"#include "fixed_fd_zero.h"/* waiting times for FA and MN */#define FA_WAIT 5#define MN_WAIT 7static void test_checksum(void){	struct router_adv radv;	char kokeilu[sizeof(struct router_adv) + 2];	struct router_adv *radv2;	int checksum;	printf("test_checksum\n");	/* fill in some test data */        radv.type = 9;        radv.code = 0;        radv.checksum = 0; /* set to zero for checksum calculation */	radv.num_addr = 1;	radv.entry_size = 2;	radv.lifetime = 300;	radv.checksum = ip_checksum((unsigned char *) &radv, sizeof(radv));	printf("Checksum: %04x\n", radv.checksum);	checksum = ip_checksum((unsigned char *) &radv, sizeof(radv));	printf("Checksum checking: %04x => ", checksum);	if (checksum != 0)		printf("FAILED!\n");	else		printf("OK\n");	/* Test case: checksum starting from even memory address */	radv2 = (struct router_adv *) kokeilu;	memcpy(radv2, &radv, sizeof(struct router_adv));	radv2->checksum = 0;	((char *) radv2)[sizeof(struct router_adv)] = -1;	radv2->checksum = ip_checksum((unsigned char *) radv2,				      sizeof(struct router_adv));	printf("Checksum: %04x\n", radv2->checksum);	checksum = ip_checksum((unsigned char *) radv2,			       sizeof(struct router_adv));	printf("Checksum checking: %04x => ", checksum);	if (checksum != 0)		printf("FAILED!\n");	else		printf("OK\n");	/* Test case: checksum starting from odd memory address */	radv2 = (struct router_adv *) (kokeilu + 1);	memcpy(radv2, &radv, sizeof(struct router_adv));	radv2->checksum = 0;	((char *) radv2)[sizeof(struct router_adv)] = -1;	radv2->checksum = ip_checksum((unsigned char *) radv2,				      sizeof(struct router_adv));	printf("Checksum: %04x\n", radv2->checksum);	checksum = ip_checksum((unsigned char *) radv2,			       sizeof(struct router_adv));	printf("Checksum checking: %04x => ", checksum);	if (checksum != 0)		printf("FAILED!\n");	else		printf("OK\n");}static void test_checksum2(char *dev){	fd_set rfds;	int retval, s;	char buf[1024];	int len, icmplen, chksum, chksum2;	struct sockaddr_in from;	unsigned int fromlen;	struct iphdr *ip;	struct icmphdr *icmp;	printf("test the checksums of every incoming ICMP message\n");	s = open_agent_icmp_socket(dev, 0);	if (s < 0) {		fprintf(stderr, "open_agent_icmp_socket() failed: ret=%i\n",			s);		return;	}	for(;;) {		FD_ZERO(&rfds);		FD_SET(s, &rfds);		retval = select(s + 1, &rfds, NULL, NULL, NULL);		if (retval <= 0) {			printf("select returned %i\n", retval);			exit(1);		}		if (!FD_ISSET(s, &rfds)) {			printf("!FD_ISSET?\n");			exit(1);		}		fromlen = sizeof(from);		len = recvfrom(s, buf, sizeof(buf), 0,			       (struct sockaddr *) &from, &fromlen);		printf("ICMP from %s, len=%i\n", inet_ntoa(from.sin_addr),		       len);		if (len < sizeof(struct iphdr) + sizeof(struct icmphdr)) {			printf("   too short message\n");			continue;		}		icmplen = len - sizeof(struct iphdr);		ip = (struct iphdr *) buf;		icmp = (struct icmphdr *) (buf + sizeof(struct iphdr));		printf("   type=%i, code=%i, checksum=%04x\n",		       icmp->type, icmp->code, ntohs(icmp->checksum));		chksum = ip_checksum((unsigned char *)icmp, icmplen);		printf("   checksum check => %04x", chksum);		if (chksum == 0)			printf(" => OK\n");		else			printf(" => FAILED!\n");		chksum = icmp->checksum;		icmp->checksum = 0;		chksum2 = ip_checksum((unsigned char *)icmp, icmplen);		printf("   own checksum calculation: %04x", ntohs(chksum2));		if (chksum2 != chksum)			printf(" => checksums differ!\n");		else			printf(" => OK\n");	}}static void test_FA(char *dev){	fd_set rfds;	struct timeval tv;	int retval, s, ifindex;	time_t last_adv;	struct in_addr h_fa, own;	printf("test FA functions\n");	ifindex = dyn_ip_get_ifindex(dev);	if (ifindex < 0) {		fprintf(stderr, "dyn_ip_get_ifindex(%s) failed\n", dev);		return;	}	s = open_agent_icmp_adv_socket(dev, AGENTADV_FILTER_SOL);	if (s < 0) {		fprintf(stderr, "open_agent_icmp_adv_socket() failed: "			"ret=%i\n", s);		return;	}	inet_aton("130.233.192.239", &own);	inet_aton("130.233.192.237", &h_fa);	last_adv = 0;	FD_ZERO(&rfds);	set_agent_adv_data(300, h_fa, own,			   AGENT_ADV_REGISTRATION_REQUIRED |			   AGENT_ADV_FOREIGN_AGENT, 0, 3 * FA_WAIT, NULL, 0);	for (;;) {		int tdiff;		/* send advertisement to broadcast address about		 * every FA_WAIT-th second */		if (time(NULL) - last_adv > FA_WAIT) {			if (send_agent_advertisement(s, NULL, NULL, ifindex) <			    0) {				printf("send_agent_advertisement failed!\n");			}			time(&last_adv);		}		/* wait for possible solicitations with timeout */		FD_SET(s, &rfds);		tdiff = time(NULL) - last_adv;		if (tdiff > FA_WAIT || tdiff < 0)			tv.tv_sec = FA_WAIT;		else			tv.tv_sec = tdiff;		tv.tv_usec = 0;		retval = select(s + 1, &rfds, NULL, NULL, &tv);		if (retval > 0) {			if (FD_ISSET(s, &rfds)) {				/* reply to a possible solicitation */				handle_icmp_sol(s);			}		}	}}static void test_HA(char *dev){	fd_set rfds;	struct timeval tv;	int retval, s, ifindex;	time_t last_adv;	struct in_addr own;	printf("test HA functions\n");	ifindex = dyn_ip_get_ifindex(dev);	if (ifindex < 0) {		fprintf(stderr, "dyn_ip_get_ifindex(%s) failed\n", dev);		return;	}	s = open_agent_icmp_adv_socket(dev, AGENTADV_FILTER_SOL);	if (s < 0) {		fprintf(stderr, "open_agent_icmp_socket() failed: ret=%i\n",			s);		return;	}	inet_aton("192.168.1.1", &own);	last_adv = 0;	FD_ZERO(&rfds);	set_agent_adv_data(300, own, own,			   AGENT_ADV_REGISTRATION_REQUIRED |			   AGENT_ADV_HOME_AGENT, 0, 3 * FA_WAIT, NULL, 0);	for (;;) {		int tdiff;		/* send advertisement to broadcast address about		 * every FA_WAIT-th second */		if (time(NULL) - last_adv > FA_WAIT) {			if (send_agent_advertisement(s, NULL, NULL, ifindex) <			    0) {				printf("send_agent_advertisement failed!\n");			}			time(&last_adv);		}		/* wait for possible solicitations with timeout */		FD_SET(s, &rfds);		tdiff = time(NULL) - last_adv;		if (tdiff > FA_WAIT || tdiff < 0)			tv.tv_sec = FA_WAIT;		else			tv.tv_sec = tdiff;		tv.tv_usec = 0;		retval = select(s + 1, &rfds, NULL, NULL, &tv);		if (retval > 0) {			if (FD_ISSET(s, &rfds)) {				/* reply to a possible solicitation */				handle_icmp_sol(s);			}		}	}}static void print_adv(struct router_adv *radv, struct agent_adv_ext *ext){	struct in_addr ia, *addr;	int i;	struct router_adv_router *r;	printf("Got advertisement message:\n"	       "router_adv: "	       "type=%i, code=%i, checksum=%i, num_addr=%i, entry_size=%i, "	       "lifetime=%i",	       radv->type, radv->code, radv->checksum, radv->num_addr,	       radv->entry_size, ntohs(radv->lifetime));	r = (struct router_adv_router *) (radv + 1);	for (i = 0; i < radv->num_addr; i++) {		ia.s_addr = r->router_addr;		printf(" {router=%s, pref=%u}", inet_ntoa(ia),		       (unsigned int) ntohl(r->pref_level));		r++;	}	printf("\nagent adv. ext: "	       "type=%i, length=%i, seq=%i, reg_lifetime=%i, opts=0x%04x, "	       "co_addrs=",	       ext->type, ext->length, ntohs(ext->seq),	       ntohs(ext->reg_lifetime), ntohs(ext->opts));	addr = (struct in_addr *) (ext + 1);	for (i = 0; i < (ext->length - 6) / 4; i++) {		if (i > 0) printf(", ");		printf("%s", inet_ntoa(*addr));		addr++;	}	printf("\n");}#define MAX_ADV_RADDRS 10#define MAX_ADV_COADDRS 10static void test_MN(char *dev){	char buf[MAX_ADV_MSG];	struct adv_extensions adv;	fd_set rfds;	struct timeval tv;	int retval, adv_s, s;	time_t last_sol;	printf("test MN functions\n");	s = open_agent_icmp_socket(dev, ICMP_FILTER_MN);	if (s < 0) {		fprintf(stderr, "open_agent_icmp_socket() failed: ret=%i\n",			s);		return;	}	adv_s = open_agent_icmp_adv_socket(dev, AGENTADV_FILTER_ADV);	if (adv_s < 0) {		fprintf(stderr, "open_agent_icmp_adv_socket() "			"failed: ret=%i\n", s);		return;	}	time(&last_sol);	FD_ZERO(&rfds);	for (;;) {		time_t tdiff;		FD_SET(adv_s, &rfds);		tdiff = time(NULL) - last_sol;		if (tdiff > MN_WAIT || tdiff < 0)			tv.tv_sec = MN_WAIT;		else			tv.tv_sec = tdiff;		tv.tv_usec = 0;		retval = select(adv_s + 1, &rfds, NULL, NULL, &tv);		if (retval > 0 && FD_ISSET(adv_s, &rfds)) {			if (handle_icmp_adv(adv_s, buf, MAX_ADV_MSG, &adv) ==			    1)				print_adv(adv.radv, adv.ext);		}		/* send solicitation to broadcast address about		 * every MN_WAIT th second		 */		if (time(NULL) - last_sol > MN_WAIT) {			if (send_agent_solicitation(s) < 0) {				printf("send_agent_solicitation failed!\n");			}			time(&last_sol);		}	}}void test_sol(void){	int s, one = 1, len, n;	char buf[1024];	struct iphdr *ip;	struct icmphdr *icmp;	struct in_addr src;	struct sockaddr_in addr;	s = socket(PF_INET, SOCK_RAW, htons(IPPROTO_ICMP));	if (s < 0) {		perror("socket");		return;	}	if (setsockopt(s,  SOL_IP, IP_HDRINCL, &one, sizeof(one)) < 0) {		perror("setsockopt - IP_HDRINCL");		return;	}	memset(&addr, 0, sizeof(addr));	addr.sin_family = AF_INET;	inet_aton("192.168.1.1", &addr.sin_addr);	inet_aton("192.168.1.123", &src);	ip = (struct iphdr *) buf;	memset(ip, 0, sizeof(struct iphdr));	ip->ihl = 5;	ip->version = 4;	ip->ttl = 1;	ip->protocol = IPPROTO_ICMP;	ip->saddr = src.s_addr;	ip->daddr = addr.sin_addr.s_addr;	len = sizeof(struct iphdr);	icmp = (struct icmphdr *) (ip + 1);	memset(icmp, 0, sizeof(struct icmphdr));	icmp->type = 10;	icmp->code = 0;	icmp->checksum = ip_checksum((unsigned char *) icmp,				     sizeof(struct icmphdr));	len += sizeof(struct icmphdr);	n = sendto(s, buf, len, 0, (struct sockaddr *) &addr,		   sizeof(addr));	if (n < 0)		perror("sendto");	close(s);}extern int opt_debug;int main(int argc, char *argv[]){	int test = 0;	char *dev = NULL;	opt_debug = 1;	if (argc >= 2) {		if (strcmp(argv[1], "-checksum") == 0)			test = 1;		else if (strcmp(argv[1], "-FA") == 0)			test = 2;		else if (strcmp(argv[1], "-MN") == 0)			test = 3;		else if (strcmp(argv[1], "-checksum2") == 0)			test = 4;		else if (strcmp(argv[1], "-HA") == 0)			test = 5;		else if (strcmp(argv[1], "-sol") == 0)			test = 6;		else			fprintf(stderr, "Invalid option: %s\n", argv[1]);	}	if (test == 0) {		fprintf(stderr, "agentadv_test <test option> [interface]\n"			"options:\n"			"   -checksum = test IP/ICMP checksum calculation\n"			"   -checksum2 = check incoming ICMP message "			"checksums\n"			"   -FA = test foreign agent functions (send "			"advertisements, reply to solicitations)\n"			"   -HA = test home agent functions (send "			"advertisements, reply to solicitations)\n"			"   -MN = test mobile node functions (receive "			"advertisements, send solicitations)\n"			"   -sol = send agent soliciations with spoofed IP "			"srcaddr\n"			"\n"			"-FA, -HA, and -MN options needs an additional "			"interface "			"argument\nthat will force the broadcast messages "			"to specified interface\n");		exit(1);	}	if (test == 2 || test == 3 || test == 4 || test == 5) {		__u32 filter = 0;		if (argc > 2) {			dev = argv[2];			printf("Binding socket to a local address on device "			       "%s\n", dev);		} else {			printf("Interface name (arg 2) needed.\n");			exit(1);		}		switch (test) {		case 2: filter = ICMP_FILTER_FA; break;		case 3: filter = ICMP_FILTER_MN; break;		case 5: filter = ICMP_FILTER_FA; break;		}	}	switch (test) {	case 1: test_checksum(); break;	case 2: test_FA(dev); break;	case 3: test_MN(dev); break;	case 4: test_checksum2(dev); break;	case 5: test_HA(dev); break;	case 6: test_sol(); break;	}	return 0;}

⌨️ 快捷键说明

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