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

📄 sendmsg.c

📁 mobile ip 在linux下的一种实现
💻 C
字号:
/* $Id: sendmsg.c,v 1.26 2001/08/11 14:49:21 jm Exp $ * Program for sending test messages * * 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 <sys/types.h>#include <sys/socket.h>#include <sys/stat.h>#include <fcntl.h>#include <netinet/in.h>#include <string.h>#include <stdio.h>#include <arpa/inet.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <getopt.h>#include <time.h>#include <netinet/ip.h>#include <netinet/udp.h>#include "message.h"#include "msgparser.h"#include "md5_mac.h"#include "jmrsa.h"#include "util.h"#define MAXMSG 1024#define DEFAULT_PORT      434#define DEFAULT_DST_ADDR  "127.0.0.1"#define DEFAULT_LIFETIME  120#define DEFAULT_HOME_ADDR "192.168.0.4"#define DEFAULT_HA_ADDR   "127.0.0.1"#define DEFAULT_CO_ADDR   "192.168.0.6"#define DEFAULT_MN_SPI     1002#define SHARED_SECRET     "\x01\x02\x03\x04\x05\x06\x07"#define SHARED_SECRET_LEN 7static struct {	int wait_for_reply;	char dst_addr[16];	int port;	char local_addr[16];	char home_addr[16];	char co_addr[16];	char ha_addr[16];	int mn_spi;	int lifetime;} opt;int main(int argc, char *argv[]){	int req_sock;	struct sockaddr_in /* cli_addr, */ serv_addr;	char msg[MAXMSG];	char *msgpos = msg;	struct reg_req *req_ext;	struct reg_rep *rep_ext;	struct msg_auth *auth_ext;	struct msg_key *key_ext;	struct msg_key *mn_keyreq;	int n;	struct msg_extensions ext;	char *optstring = "a:c:h:L:l:o:p:rs:";	char c;	rsa_public_key pub;	unsigned char *keybuf;	unsigned int keylen = 0;	int i;	int len;	unsigned long r;	int fd;	fd = open("/dev/urandom", O_RDONLY);	read(fd, &r, sizeof(r));	close(fd);	/* default arguments */	opt.wait_for_reply = 0;	dynamics_strlcpy(opt.dst_addr, DEFAULT_DST_ADDR, sizeof(opt.dst_addr));	opt.port = DEFAULT_PORT;	dynamics_strlcpy(opt.ha_addr, DEFAULT_HA_ADDR, sizeof(opt.ha_addr));	dynamics_strlcpy(opt.co_addr, DEFAULT_CO_ADDR, sizeof(opt.co_addr));	dynamics_strlcpy(opt.home_addr, DEFAULT_HOME_ADDR,			 sizeof(opt.home_addr));	opt.local_addr[0] = '\0';	opt.mn_spi = DEFAULT_MN_SPI;	opt.lifetime = DEFAULT_LIFETIME;	while ((c = getopt(argc, argv, optstring)) != EOF) {		switch (c) {		case 'a':			dynamics_strlcpy(opt.dst_addr, optarg,					 sizeof(opt.dst_addr));			break;		case 'c':			dynamics_strlcpy(opt.co_addr, optarg, 					 sizeof(opt.co_addr));			break;		case 'h':			dynamics_strlcpy(opt.ha_addr, optarg,					 sizeof(opt.ha_addr));			break;		case 'L':			dynamics_strlcpy(opt.local_addr, optarg,					 sizeof(opt.local_addr));			break;		case 'l':			opt.lifetime = atoi(optarg);			break;		case 'o':			dynamics_strlcpy(opt.home_addr, optarg,					 sizeof(opt.home_addr));			break;		case 'p':			opt.port = atoi(optarg);			break;		case 'r':			opt.wait_for_reply++;			break;		case 's':			opt.mn_spi = atoi(optarg);			break;		default:			printf("usage: sendmsg [-a remote_address]"			       " [-p remote_port] [-L local_address]"			       " [-c co_addr] [-h ha_addr]"			       " [-o home_addr] [-l lifetime] [-s mn_spi]"			       " [-r] [reg_req] [reg_rep]"			       " [msg_auth auth_code] [msg_key key_code]"			       " [key_req]\n"			       "valid auth codes\n"			       "\t32: Mobile-Home Authentication\n"			       "\t33: Mobile-Foreigh Authentication\n"			       "valid key codes:\n"			       "\t115: Foreign Agent Public Key\n"			       "\t120: Home-Mobile Key Reply\n"			       "\t121: Foreign Agent Key Reply\n");			exit(-1);		}	}	req_ext = NULL;	rep_ext = NULL;	for (;optind < argc; optind++) {		if (strcmp(argv[optind], "reg_req") == 0) {			/* Reqistration Request */			req_ext = (struct reg_req *) msgpos;			memset(req_ext, 0, sizeof(req_ext));			req_ext->type = REG_REQ;			req_ext->opts = 0;			req_ext->lifetime = htons(opt.lifetime);			inet_aton(opt.home_addr, &req_ext->home_addr);			inet_aton(opt.ha_addr, &req_ext->ha_addr);			inet_aton(opt.co_addr, &req_ext->co_addr);			req_ext->id[0] = htonl(time(NULL)+UNIX_NTP_DIFF);			req_ext->id[1] = r;			msgpos += sizeof(struct reg_req);		} else if (strcmp(argv[optind], "reg_rep") == 0) {			/* Registration Reply */			rep_ext = (struct reg_rep *) msgpos;			memset(rep_ext, 0, sizeof(req_ext));			rep_ext->type = REG_REP;			rep_ext->code = 0;			rep_ext->lifetime = htons(opt.lifetime);			inet_aton(opt.home_addr, &rep_ext->home_addr);			inet_aton(opt.ha_addr, &rep_ext->ha_addr);			rep_ext->id[0] = htonl(time(NULL));			rep_ext->id[1] = r;			msgpos += sizeof(struct reg_rep);		} else if (strcmp(argv[optind], "key_req") == 0) {			mn_keyreq = (struct msg_key *) msgpos;			init_key_extension(mn_keyreq,					   VENDOR_EXT_DYNAMICS_MN_KEYREQ,					   htonl(1000), 0);			msgpos += GET_KEY_EXT_LEN(mn_keyreq);		} else if (strcmp(argv[optind], "msg_auth") == 0) {			/* Message authentication */			auth_ext = (struct msg_auth *) msgpos;			auth_ext->type = atoi(argv[++optind]);			auth_ext->spi = htonl(opt.mn_spi);			auth_ext->length = MD5_MAC_LEN + SPI_LEN;			if (req_ext != NULL) {				len = msgpos - ((char *)req_ext) + 2;				md5_mac((unsigned char *) SHARED_SECRET,					SHARED_SECRET_LEN,					(unsigned char *) req_ext,					len,					MSG_AUTH_DATA(auth_ext));			} else if (rep_ext != NULL) {				len = msgpos - ((char *)rep_ext) + 2;				md5_mac((unsigned char *) SHARED_SECRET,					SHARED_SECRET_LEN,					(unsigned char *) rep_ext,					len,					MSG_AUTH_DATA(auth_ext));			} else {				fprintf(stderr, "Cannot make msg_auth "					"extension\n");				exit(1);			}			msgpos += GET_AUTH_EXT_LEN(auth_ext);		} else if (strcmp(argv[optind], "msg_key") == 0) {			/* Key extension */			key_ext = (struct msg_key *) msgpos;			key_ext->type = atoi(argv[++optind]);			key_ext->spi = htonl(1000);			rsa_init_pub(&pub);			mpz_set_ui(pub.n, 1234567);			mpz_set_ui(pub.e, 12345);			keybuf = rsa_public_key_buffer(&pub, &keylen);			rsa_clear_pub(&pub);			memcpy(MSG_KEY_DATA(key_ext), keybuf, keylen);			key_ext->length = keylen + 4;			msgpos += GET_KEY_EXT_LEN(key_ext);		}	}	req_sock = socket(AF_INET, SOCK_DGRAM, 0);	if (req_sock < 0) {		perror("socket");		exit(-1);	}	memset((char *) &serv_addr, 0, sizeof(serv_addr));	serv_addr.sin_family = AF_INET;	inet_aton(opt.dst_addr, &serv_addr.sin_addr);	serv_addr.sin_port = htons(opt.port);	if (opt.local_addr[0] != '\0') {		struct sockaddr_in own;		int raw_sock, total_len, one = 1;		struct iphdr *ip;		struct udphdr *udp;		unsigned char *buf;		struct in_addr tmpaddr;		own.sin_family = AF_INET;		own.sin_addr.s_addr = INADDR_ANY;		own.sin_port = htons(434);		if (opt.wait_for_reply > 0 &&		    bind(req_sock, (struct sockaddr *) &own, sizeof(own)) < 0)			perror("bind");		raw_sock = socket(PF_INET, SOCK_RAW, htons(IPPROTO_UDP));		if (raw_sock < 0) {			perror("socket (SOCK_RAW)");			exit(-1);		}		if (setsockopt(raw_sock, SOL_IP, IP_HDRINCL, &one, sizeof(one))		    < 0) {			perror("setsockopt - IP_HDRINCL");			exit(-1);		}		total_len = sizeof(*ip) + sizeof(*udp) + (msgpos - msg);		buf = (unsigned char *) malloc(total_len);		if (buf == 0) {			printf("malloc failed\n");			exit(-1);		}		ip = (struct iphdr *) buf;		memset(ip, 0, sizeof(struct iphdr));		ip->ihl = 5;		ip->version = 4;		ip->ttl = 255;		ip->protocol = IPPROTO_UDP;		inet_aton(opt.local_addr, &tmpaddr);		ip->saddr = tmpaddr.s_addr;		ip->daddr = serv_addr.sin_addr.s_addr;		udp = (struct udphdr *) (ip + 1);		udp->source = htons(434);		udp->dest = htons(opt.port);		udp->len = htons(sizeof(*udp) + (msgpos - msg));		udp->check = 0; /* FIX */		memcpy(udp + 1, msg, msgpos - msg);		ip->tot_len = htons(total_len);		ip->check = 0;		ip->check = ip_checksum(buf, total_len);		serv_addr.sin_port = htons(0);		n = sendto(raw_sock, buf, total_len, 0,			   (struct sockaddr *) &serv_addr, sizeof(serv_addr));		serv_addr.sin_port = htons(opt.port);		if (n < 0)			perror("sendto");		free(buf);		close(raw_sock);	} else {		n = sendto(req_sock, msg, msgpos - msg, 0,			   (struct sockaddr *) &serv_addr, sizeof(serv_addr));	}	printf("sent %d bytes (of %d) to %s:%d\n", n, msgpos - msg,	       inet_ntoa(serv_addr.sin_addr),	       ntohs(serv_addr.sin_port));	for (i = 0; i < opt.wait_for_reply; i++) {		printf("Waiting for reply %d\n", i + 1);		n = recvfrom(req_sock, msg, MAXMSG, 0,			     (struct sockaddr*)0, (unsigned int *) 0);		if (n == -1) {			perror("sendmsg");			exit(-1);		}		printf("Received %d bytes from %s:%d\n", n,		       inet_ntoa(serv_addr.sin_addr),		       ntohs(serv_addr.sin_port));		parse_msg(msg, n, &ext);		/*		 * Show what we got		 */		printf("Message is Registration ");		if (ext.req) {			printf("Request\n");		}		if (ext.rep) {			printf("Reply, code %u\n", ext.rep->code);		}		if (ext.mh_auth || ext.mf_auth || ext.fa_pubkey ||		    ext.mn_keyrep || ext.fa_pubkeyrep) {			printf("And has the following extensions:\n");			if (ext.mh_auth) {				printf("\tMobile-Home Authentication\n");			}			if (ext.mf_auth) {				printf("\tMobile-Foreign Authenticaton\n");			}			if (ext.fa_pubkey) {				printf("\tFA Public Key\n");			}			if (ext.mn_keyrep) {				printf("\tSession Key to MN\n");			}			if (ext.fa_pubkeyrep) {				printf("\tSession Key to FA (pubkeyrep)\n");			}		} else {			printf("And has no extensions\n");		}	}	return 0;}

⌨️ 快捷键说明

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