00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifdef HAVE_CONFIG_H
00014 #include <config.h>
00015 #endif
00016
00017 #include <stdlib.h>
00018 #include <stdio.h>
00019 #include <string.h>
00020 #include <errno.h>
00021 #include <pcap.h>
00022 #include <unistd.h>
00023 #include <sys/types.h>
00024 #include <sys/socket.h>
00025 #include <netinet/in.h>
00026 #include <arpa/inet.h>
00027 #include <cygwin/in.h>
00028
00029 #include "debug.h"
00030 #include "mn.h"
00031
00032
00033
00034 static struct bpf_insn agentadv_filter[] = {
00035
00036 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 14+9),
00037
00038 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_ICMP, 0, 3),
00039
00040 BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 14+20),
00041
00042 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 9, 0, 1),
00043 BPF_STMT(BPF_RET+BPF_K, (unsigned int)-1),
00044 BPF_STMT(BPF_RET+BPF_K, 0)
00045 };
00046
00047 static struct bpf_program agentadv_fprog = {
00048 sizeof(agentadv_filter) / sizeof(struct bpf_insn),
00049 agentadv_filter
00050 };
00051
00052
00053 struct dst_data {
00054 int s;
00055 struct sockaddr_in addr;
00056 };
00057
00058 static void dispatcher_handler(u_char *user, const struct pcap_pkthdr *header,
00059 const u_char *pkt_data)
00060 {
00061 struct dst_data *dst = (struct dst_data *) user;
00062
00063 DEBUG(DEBUG_INFO, "%lu:%lu len=%lu ==> %s:%i\n",
00064 header->ts.tv_sec, header->ts.tv_usec,
00065 (unsigned long) header->len,
00066 inet_ntoa(dst->addr.sin_addr), ntohs(dst->addr.sin_port));
00067
00068
00069
00070 if (sendto(dst->s, pkt_data, header->len, 0,
00071 (struct sockaddr *) &dst->addr, sizeof(dst->addr)) < 0) {
00072 DEBUG(DEBUG_INFO, "dispatcher_handler: sendto failed: %s\n",
00073 strerror(errno));
00074 }
00075 }
00076
00077
00078 pid_t init_pcap_for_advs(void)
00079 {
00080 pcap_t *fp;
00081 char error[PCAP_ERRBUF_SIZE];
00082 char *dev;
00083 struct dst_data dst;
00084 pid_t pid;
00085
00086 pid = fork();
00087 if (pid < 0) {
00088 DEBUG(DEBUG_INFO, "init_pcap_for_advs: fork failed: %s\n",
00089 strerror(errno));
00090 return -1;
00091 }
00092
00093 if (pid > 0) {
00094
00095 return pid;
00096 }
00097
00098 dst.s = socket(AF_INET, SOCK_DGRAM, 0);
00099 if (dst.s < 0) {
00100 perror("socket");
00101 exit(1);
00102 }
00103 dst.addr.sin_family = AF_INET;
00104 dst.addr.sin_addr.s_addr = htonl((127 << 24 | 1));
00105 dst.addr.sin_port = htons(4344);
00106
00107
00108
00109
00110 dev = pcap_lookupdev(error);
00111 if (dev == NULL) {
00112 DEBUG(DEBUG_INFO,
00113 "init_pcap_for_advs: Could not get device (%s)\n",
00114 error);
00115 return -1;
00116 }
00117
00118 DEBUG(DEBUG_INFO, "init_pcap_for_advs: using device '%s'\n", dev);
00119 fp = pcap_open_live(dev, 1500, 0, 20, error);
00120 if (fp == NULL) {
00121 DEBUG(DEBUG_INFO, "pcap_open_live failed (%s)\n", error);
00122 return -1;
00123 }
00124
00125 if (pcap_setfilter(fp, &agentadv_fprog) < 0) {
00126 DEBUG(DEBUG_INFO,
00127 "init_pcap_for_advs: Could not attach BPF\n");
00128 return -1;
00129 }
00130
00131
00132 DEBUG(DEBUG_INFO, "init_pcap_for_advs: child starting to capture "
00133 "packets\n");
00134
00135 pcap_loop(fp, 0, dispatcher_handler, (u_char *) &dst);
00136
00137
00138 DEBUG(DEBUG_INFO, "pcap_loop returned?!\n");
00139 return 0;
00140 }