📄 sendmsg.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 + -