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