📄 dyndump.c
字号:
/* $Id: dyndump.c,v 1.8 2001/09/02 10:27:32 jm Exp $ * Mobile IP packet dumper * * 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. */#ifndef _GNU_SOURCE#define _GNU_SOURCE#endif#include <stdlib.h>#include <stdio.h>#include <netinet/ip.h>#include <netinet/udp.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <string.h>#include <unistd.h>#include <sys/ioctl.h>#include <assert.h>#include <linux/if_ether.h>#include <sys/ioctl.h>#include <net/if.h>#include <time.h>#include <sys/time.h>#include <signal.h>#include <errno.h>#include <features.h> /* for the glibc version number */#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1#include <netpacket/packet.h>#include <net/ethernet.h> /* the L2 protocols */#include <netinet/if_ether.h>#else#include <linux/if_packet.h>#include <linux/if_ether.h> /* The L2 protocols */#endif#include "message.h"#include "dyn_ip.h"#ifndef ETHERTYPE_IP#define ETHERTYPE_IP 0x0800 /* IP */#endifstruct idxmap *idxmap = NULL;struct ext_header { __u8 type; __u8 length;};char *ip_to_a(int i){ struct in_addr ia; ia.s_addr = i; return inet_ntoa(ia);}void cleanup(int sig){ dyn_ip_free_interface_map(idxmap); exit(0);}static char *ll_index_to_name(int idx){ struct idxmap *im; static char nbuf[64]; if (idx == 0) return "*"; for (im = idxmap; im != NULL; im = im->next) if (im->index == idx) return im->name; snprintf(nbuf, sizeof(nbuf), "if%d", idx); return nbuf;}static void handle_udp(struct sockaddr_ll *from, struct iphdr *ip){ struct udphdr *udp; char *pos; struct timeval tv; struct tm *t; int left; udp = (struct udphdr *) (ip + 1); pos = (char *) (udp + 1); if (ntohs(udp->dest) != 434 && ntohs(udp->source) != 434 && ntohs(udp->dest) != 1434 && ntohs(udp->source) != 1434) return; if (ntohs(udp->len) - sizeof(struct udphdr) < sizeof(struct reg_rep)) return; left = ntohs(udp->len) - sizeof(struct udphdr); gettimeofday(&tv, NULL); t = localtime(&tv.tv_sec); printf("%02i:%02i:%02i.%06li ", t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec); printf("%s:%i => ", ip_to_a(ip->saddr), ntohs(udp->source)); printf("%s:%i (%s)\n", ip_to_a(ip->daddr), ntohs(udp->dest), ll_index_to_name(from->sll_ifindex)); if (*pos == REG_REQ) { struct reg_req *req = (struct reg_req *) pos; printf("\tREQ: type=%i opts=%i lifetime=%i " "home_addr=%s\n", req->type, req->opts, ntohs(req->lifetime), inet_ntoa(req->home_addr)); printf("\t ha_addr=%s", inet_ntoa(req->ha_addr)); printf(" co_addr=%s\n\t id=%08x,%08x\n", inet_ntoa(req->co_addr), (__u32) ntohl(req->id[0]), (__u32) ntohl(req->id[1])); pos += sizeof(struct reg_req); left -= sizeof(struct reg_req); } else if (*pos == REG_REP) { struct reg_rep *rep = (struct reg_rep *) pos; printf("\tREP: type=%i code=%i lifetime=%i " "home_addr=%s\n", rep->type, rep->code, ntohs(rep->lifetime), inet_ntoa(rep->home_addr)); printf("\t ha_addr=%s\n\t id=%08x,%08x\n", inet_ntoa(rep->ha_addr), (__u32) ntohl(rep->id[0]), (__u32) ntohl(rep->id[1])); pos += sizeof(struct reg_rep); left -= sizeof(struct reg_rep); } else { printf("\tunknown type %i\n", (int) *pos); return; } while (left > 0) { int i; struct ext_header *ext = (struct ext_header *) pos; printf("\tEXT: type=%i length=%i", ext->type, ext->length); if (ext->length + 2 > left) { printf(" (OVERFLOW!)"); ext->length = left - 2; } if (ext->type == VENDOR_EXT_TYPE2) { struct vendor_ext_header *dyn = (struct vendor_ext_header *)pos; if (ntohl(dyn->vendor_id) == VENDOR_ID_DYNAMICS) printf(" Dynamics sub_type=%i", ntohs(dyn->sub_type)); } pos += 2; left -= 2; printf(" payload:"); for (i = 0; i < ext->length; i++) { if (i % 16 == 0) printf("\n\t "); printf(" %02X", (unsigned char) *pos); pos++; left--; } printf("\n"); } printf("\n");}int main(int argc, char *argv[]){ struct sockaddr_ll sa; char buf[10000]; int s, i; struct ifreq ifr; if (argc > 1 && (strncmp(argv[1], "-h", 2) == 0 || strcmp(argv[1], "--help") == 0)) { printf("dyndump [interface]\n"); printf("If interface is given, only the packets to/from that " "interface are shown.\n" "dyndump does not change the interface to a promiscuous" " mode, so this must be done\n" "separately, if needed (e.g. 'ifconfig <iface> " "promisc>')\n"); exit(0); } idxmap = dyn_ip_get_interface_map(); if (idxmap == NULL) { fprintf(stderr, "Could not get interface map\n"); exit(1); } memset(&ifr, 0, sizeof(ifr)); memset(&sa, 0, sizeof(sa)); sa.sll_family = AF_PACKET; s = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); if (s < 0) { if (errno == EPERM) fprintf(stderr, "Must be run as root\n"); perror("socket"); exit(1); } if (argc > 1) { i = strlen(argv[1]); if (i >= sizeof(ifr.ifr_name)) { fprintf(stderr, "Too long interface parameter\n"); exit(1); } memcpy(ifr.ifr_name, argv[1], i + 1); if (ioctl(s, SIOCGIFINDEX, &ifr) != 0) { perror("ioctl"); close(s); exit(1); } sa.sll_ifindex = ifr.ifr_ifindex; } if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("bind"); exit(1); } signal(SIGHUP, cleanup); signal(SIGINT, cleanup); for(;;) { struct sockaddr_ll from; unsigned int fromlen; struct iphdr *ip; int len; fromlen = sizeof(from); len = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *) &from, &fromlen); if (len < 0) { perror("recvfrom"); exit(1); } ip = (struct iphdr *) buf; if (ip->version != 4) continue; if (ip->protocol == IPPROTO_UDP) handle_udp(&from, ip); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -