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

📄 netsimul.c

📁 mobile ip 在linux下的一种实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: netsimul.c,v 1.20 2001/09/18 15:16:11 jm Exp $ * Test network simulator * * Dynamic hierarchial IP tunnel * Copyright (C) 2001, Jouni Malinen * * 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 <stdlib.h>#include <stdio.h>#include <string.h>#include <fcntl.h>#include <net/if.h>#include <unistd.h>#include <sys/time.h>#include <sys/types.h>#include <sys/ioctl.h>#include <netinet/if_ether.h>#include <netinet/ip.h>#include <netinet/ip_icmp.h>#include <netinet/udp.h>#include <net/if_arp.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <errno.h>#include <time.h>#include <assert.h>#include "message.h"#include "msgparser.h"#include "auth.h"#include "util.h"#include "agentadv.h"#ifdef HAVE_LINUX_IF_TUN_H#include <linux/if_tun.h>#endif/* couple of defines from linux/if_tun.h if they cannot be included */#ifndef TUNSETIFF#if 0/* up to and including Linux 2.4.5 */#define TUNSETIFF (('T'<< 8) | 202)#else/* TUNSETIFF changed in Linux 2.4.6; at least in i386 version it is now: */#define TUNSETIFF 0x400454ca#endif#endif#ifndef IFF_TUN#define IFF_TUN		0x0001#endif#ifndef IFF_TAP#define IFF_TAP		0x0002#endif#ifndef IFF_NO_PI#define IFF_NO_PI	0x1000#endif/* netsimul uses Linux kernel's "Universal TUN/TAP device driver'; see * kernel source (linux/Documentation/network/tuntap.txt) for instructions on * how to configure TUN/TAP *//* Command line format: * <seconds from start> <command>{<field1>=<value1> ...} [option1]{..} ... * commands: *   send{dsthw,srchw,proto,dev} *     ip{dstip,srcip,proto} *     icmp{type,code,checksum} *     udp{dstport,srcport} *       req{opts,lifetime,home,ha,coa,id0,id1,saveid} *       rep{code,lifetime,home,ha,id0,id1,useid} *       mhauth{spi,secret,alg} *       mfauth{spi,secret,alg} *       fhauth{spi,secret,alg} *       encaps{} *       raw{data} *   expect: like send; fail if expected packet is not received *   reject: like expect, but fail if packet is received *   note{txt} *   exec{cmd} * * <seconds from start> can also be specified as a interval from previous * command (e.g., +0.5 means 0.5 sec after previous command) * * (see msgsimul1.data for an example) *//* Simulated network: * tap0: HA=192.168.250.1, hwaddr 00:00:00:00:00:01 * tap1: HA=192.168.251.1, hwaddr 00:00:00:00:00:02 * tap2: HA=192.168.252.1, hwaddr 00:00:00:00:00:03 * * HA=192.168.25x.1 * MN=192.168.25x.100 .. 199 * GW=192.168.25x.254, hwaddr 00:00:00:01:0x:fe * broadcast=192.168.25x.255 * * foreign net 192.168.150.0/24: route to tap0 */int fd[3];int max_fd;extern int opt_debug;static __u32 nextid = 0;static struct timeval start;void process(int fd, const char *dev);struct parse_data {	char *name;	char *next;	char *field;	char *value;	int was_last;};int add_ip(char *buf, int left, struct parse_data *parse);#define PARSE_BUF_SIZE 10240static int expect_received;static int expect_error = 0;static int reject_error = 0;char current_command[PARSE_BUF_SIZE];int current_cmd_expect;int reject_cmd;int current_expect;char expect_buf[PARSE_BUF_SIZE];struct parse_data expect_parse;static u32 prev_id[2]; /* id used in previous send/received req/reply */static int is_space(char c){	if (c == ' ' || c == '\t' || c == 13 || c == 10)		return 1;	return 0;}static int dyn_atoi(const char *c){	int i;	if (c[0] == '0' && c[1] == 'x')		sscanf(c, "0x%x", &i);	else		i = atoi(c);	return i;}static u32 get_id(const char *c){	if (strcmp(c, "prev0") == 0)		return prev_id[0];	else if (strcmp(c, "prev1") == 0)		return prev_id[1];	return htonl(dyn_atoi(c));}/* Returns: * 0 = no more entries * 1 = entry available, name in parse->name */int parse_init(struct parse_data *parse, char *buf){	char *t;	t = buf;	while (is_space(*t)) t++;	parse->name = t;	while (*t != '\0' && *t != '{') t++;	if (*t == '\0') {		return 0;	} else {		*t = '\0';		t++;		parse->next = t;	}	parse->was_last = 0;	return 1;}/* Returns: * -1 = invalid input data *  0 = no more entries *  1 = entry available in {parse->field, parse->value} */int parse_get_next(struct parse_data *parse){	if (parse->was_last)		return 0;	parse->was_last = 0;	while (is_space(*parse->next))		parse->next++;	if (*parse->next == '\0')		return -1;	if (*parse->next == '}') {		parse->next++;		return 0;	}	parse->field = parse->next;	while (*parse->next != '\0' && *parse->next != '=')		parse->next++;	if (*parse->next == '\0')		return -1;	*parse->next = '\0';	parse->next++;	while (is_space(*parse->next))		parse->next++;	if (*parse->next == '"') {		parse->next++;		parse->value = parse->next;		while (*parse->next != '\0' && *parse->next != '"')			parse->next++;		if (*parse->next == '\0')			return -1;		*parse->next = '\0';		parse->next++;	} else {		parse->value = parse->next;		while (*parse->next != '\0' && !is_space(*parse->next) &&		       *parse->next != '}')			parse->next++;		if (*parse->next == '\0')			return -1;		if (*parse->next == '}')			parse->was_last = 1;		*parse->next = '\0';		parse->next++;	}	return 1;}struct saved_id {	int num;	__u32 id[2];	struct saved_id *next;};struct saved_id *saved_ids = NULL;static void saveid(int num, __u32 id[]){	struct saved_id *entry;	printf("\tsaveid[%i] = %08x:%08x\n", num, id[0], id[1]);	entry = saved_ids;	while (entry != NULL) {		if (entry->num == num) {			entry->id[0] = id[0];			entry->id[1] = id[1];			return;		}		entry = entry->next;	}	entry = (struct saved_id *) malloc(sizeof(struct saved_id));	if (entry == NULL) {		fprintf(stderr, "saveid: out of memory\n");		return;	}	entry->num = num;	entry->id[0] = id[0];	entry->id[1] = id[1];	entry->next = saved_ids;	saved_ids = entry;}static void useid(int num, __u32 id[]){	struct saved_id *tmp = saved_ids;	printf("\tuseid[%i]\n", num);	while (tmp != NULL) {		if (tmp->num == num) {			id[0] = tmp->id[0];			id[1] = tmp->id[1];			return;		}		tmp = tmp->next;	}	fprintf(stderr, "useid - saved id=%i not found\n", num);}int add_req(char *buf, int left, struct parse_data *parse){	struct reg_req *req;	if (sizeof(struct reg_req) > left) {		fprintf(stderr, "add_req - buffer full\n");		return 0;	}	req = (struct reg_req *) buf;	memset(req, 0, sizeof(struct reg_req));	req->type = REG_REQ;	req->id[0] = htonl(time(NULL) + UNIX_NTP_DIFF);	req->id[1] = htonl(nextid++);	while (parse_get_next(parse) == 1) {		if (strcmp(parse->field, "lifetime") == 0)			req->lifetime = htons(dyn_atoi(parse->value));		else if (strcmp(parse->field, "opts") == 0)			req->opts = dyn_atoi(parse->value);		else if (strcmp(parse->field, "home") == 0)			inet_aton(parse->value, &req->home_addr);		else if (strcmp(parse->field, "ha") == 0)			inet_aton(parse->value, &req->ha_addr);		else if (strcmp(parse->field, "coa") == 0)			inet_aton(parse->value, &req->co_addr);		else if (strcmp(parse->field, "saveid") == 0)			saveid(dyn_atoi(parse->value), req->id);		else if (strcmp(parse->field, "id0") == 0)			req->id[0] = get_id(parse->value);		else if (strcmp(parse->field, "id1") == 0)			req->id[1] = get_id(parse->value);		else {			fprintf(stderr, "add_req - unknown field '%s'\n",				parse->field);			return 0;		}	}	return sizeof(struct reg_req);}int add_rep(char *buf, int left, struct parse_data *parse){	struct reg_rep *rep;	if (sizeof(struct reg_rep) > left) {		fprintf(stderr, "add_rep - buffer full\n");		return 0;	}	rep = (struct reg_rep *) buf;	memset(rep, 0, sizeof(struct reg_rep));	rep->type = REG_REP;	rep->id[0] = htonl(time(NULL) + UNIX_NTP_DIFF);	rep->id[1] = htonl(nextid++);	while (parse_get_next(parse) == 1) {		if (strcmp(parse->field, "lifetime") == 0)			rep->lifetime = htons(dyn_atoi(parse->value));		else if (strcmp(parse->field, "code") == 0)			rep->code = dyn_atoi(parse->value);		else if (strcmp(parse->field, "home") == 0)			inet_aton(parse->value, &rep->home_addr);		else if (strcmp(parse->field, "ha") == 0)			inet_aton(parse->value, &rep->ha_addr);		else if (strcmp(parse->field, "useid") == 0)			useid(dyn_atoi(parse->value), rep->id);		else if (strcmp(parse->field, "id0") == 0)			rep->id[0] = get_id(parse->value);		else if (strcmp(parse->field, "id1") == 0)			rep->id[1] = get_id(parse->value);		else {			fprintf(stderr, "add_rep - unknown field '%s'\n",				parse->field);			return 0;		}	}	return sizeof(struct reg_rep);}int add_auth(int type, char *start, char *buf, int left,	     struct parse_data *parse){	char *secret = NULL;	int alg = AUTH_ALG_MD5_PREFIX_SUFFIX;	int spi = 0;	if (sizeof(struct msg_auth) + MAX_SK_LEN > left) {		fprintf(stderr, "add_auth - buffer full\n");		return 0;	}	while (parse_get_next(parse) == 1) {		if (strcmp(parse->field, "spi") == 0)			spi = htonl(dyn_atoi(parse->value));		else if (strcmp(parse->field, "alg") == 0)			alg = dyn_atoi(parse->value);		else if (strcmp(parse->field, "secret") == 0)			secret = parse->value;		else {			fprintf(stderr, "add_auth - unknown field '%s'\n",				parse->field);			return 0;		}	}	return auth_add(alg, secret == NULL ?			(unsigned char *) "" : (unsigned char *) secret,			secret == NULL ? 0 : strlen(secret),			(unsigned char *) start, (struct msg_auth *) buf,			type, spi);}int add_encaps(char *buf, int left){	struct encaps_delivery_ext *encaps;	if (sizeof(struct encaps_delivery_ext) > left) {		fprintf(stderr, "add_encaps - buffer full\n");		return 0;	}	encaps = (struct encaps_delivery_ext *) buf;	encaps->type = ENCAPS_DELIVERY_EXT;	encaps->length = 0;	return sizeof(struct encaps_delivery_ext);}int add_raw(char *buf, int left, struct parse_data *parse){	char *pos = buf, *rpos;	int i, count;	while (parse_get_next(parse) == 1) {		if (strcmp(parse->field, "data") == 0) {			count = strlen(parse->value) / 2;			if (count > left) {				fprintf(stderr, "add_raw - buffer full\n");				return 0;			}			rpos = parse->value;			for (i = 0; i < count; i++) {				*pos = get_hex_digit(*rpos) * 16 +					get_hex_digit(*(rpos + 1));				pos++;				rpos += 2;			}		} else {			fprintf(stderr, "add_raw - unknown field '%s'\n",				parse->field);			return 0;		}	}	return pos - buf;}#define SENDBUF 8192int add_udp(char *buf, int left, struct parse_data *parse){	struct udphdr *udp;	char *mip_start, *pos;	struct msg_extensions ext;	int mip_msg = 0;	udp = (struct udphdr *) buf;	udp->source = htons(434);	udp->dest = htons(434);	udp->check = 0;	while (parse_get_next(parse) == 1) {		if (strcmp(parse->field, "dstport") == 0)			udp->dest = htons(dyn_atoi(parse->value));		else if (strcmp(parse->field, "srcport") == 0)			udp->source = htons(dyn_atoi(parse->value));	}	mip_start = pos = (char *) (udp + 1);	while (parse_init(parse, parse->next) == 1) {		int left = pos - buf + SENDBUF;		printf("\tudp-data: %s\n", parse->name);		if (strcmp(parse->name, "req") == 0) {			pos += add_req(pos, left, parse);			mip_msg = 1;		} else if (strcmp(parse->name, "rep") == 0) {			pos += add_rep(pos, left, parse);			mip_msg = 1;		} else if (strcmp(parse->name, "mhauth") == 0)			pos += add_auth(MH_AUTH, mip_start, pos, left, parse);		else if (strcmp(parse->name, "mfauth") == 0)			pos += add_auth(MF_AUTH, mip_start, pos, left, parse);		else if (strcmp(parse->name, "fhauth") == 0)			pos += add_auth(FH_AUTH, mip_start, pos, left, parse);		else if (strcmp(parse->name, "encaps") == 0)			pos += add_encaps(pos, left);		else if (strcmp(parse->name, "raw") == 0)			pos += add_raw(pos, left, parse);		else			printf("\tunknown udp data\n");	}	udp->len = htons(pos - buf);	/* FIX: UDP checksum */	memset(&ext, 0, sizeof(ext));	if (mip_msg && parse_msg(mip_start, pos - mip_start, &ext) != 0) {		fprintf(stderr, "\tInvalid message!\n");	}	if (ext.req != NULL) {		prev_id[0] = ext.req->id[0];		prev_id[1] = ext.req->id[1];	}	if (ext.rep != NULL) {		prev_id[0] = ext.rep->id[0];		prev_id[1] = ext.rep->id[1];	}	return pos - buf;}int add_icmp(char *buf, int left, struct parse_data *parse){	struct icmphdr *icmp;	char *pos;	int force_checksum = -1;	icmp = (struct icmphdr *) buf;	memset(icmp, 0, sizeof(*icmp));	pos = buf + sizeof(struct icmphdr);	while (parse_get_next(parse) == 1) {		if (strcmp(parse->field, "type") == 0)			icmp->type = dyn_atoi(parse->value);		else if (strcmp(parse->field, "code") == 0)			icmp->code = dyn_atoi(parse->value);		else if (strcmp(parse->field, "checksum") == 0)			force_checksum = dyn_atoi(parse->value);	}	while (parse_init(parse, parse->next) == 1) {		int left = pos - buf + SENDBUF;		printf("\ticmp-data: %s\n", parse->name);		if (strcmp(parse->name, "ip") == 0)			pos += add_ip(pos, left, parse);		else if (strcmp(parse->name, "raw") == 0)			pos += add_raw(pos, left, parse);		else			printf("\tunknown icmp data\n");	}	icmp->checksum = ip_checksum((unsigned char *) icmp, pos - buf);	return pos - buf;}int add_ip(char *buf, int left, struct parse_data *parse){	struct iphdr *ip;	char *pos;	struct in_addr addr;	ip = (struct iphdr *) buf;	ip->ihl = 5;

⌨️ 快捷键说明

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