win_adv_capture.c

Go to the documentation of this file.
00001 /* $Id: win_adv_capture.c,v 1.2 2001/10/03 13:47:25 jm Exp $
00002  * MN helper for getting L2 data for agent advertisement in Windows environment
00003  *
00004  * Dynamic hierarchial IP tunnel
00005  * Copyright (C) 2001, Jouni Malinen
00006  *
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License version 2 as
00009  * published by the Free Software Foundation. See README and COPYING for
00010  * more details.
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 /* ethhdr - 14 octets; iphdr - 20 octets */
00034 static struct bpf_insn agentadv_filter[] = {
00035         /* A <- P[14+9:1] - load byte - IP protocol */
00036         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 14+9),
00037         /* pc += (A == IPPROTO_ICMP) ? 0 : 3 */
00038         BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_ICMP, 0, 3),
00039         /* A <- P[14+20:1] - load byte - ICMP type */
00040         BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 14+20),
00041         /* pc += (A == 9) ? 0 : 1 (agentadv) */
00042         BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 9, 0, 1),
00043         BPF_STMT(BPF_RET+BPF_K, (unsigned int)-1), /* accept the packet */
00044         BPF_STMT(BPF_RET+BPF_K, 0) /* filter packet */
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         /* send agent advertisement for dynmnd using UDP port 4344 */
00069         /* buf=pkt_data, len=header->len */
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                 /* in parent - return */
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         /* FIX: should support more than one interface and also detect new
00108          * interfaces when, e.g., wireless LAN card is inserted */
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         /* in child - start capturing packets */
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         /* never reached */
00138         DEBUG(DEBUG_INFO, "pcap_loop returned?!\n");
00139         return 0;
00140 }

Generated on Tue Jan 15 08:50:43 2008 for Virtual foreign agent generator version 0.1 by  doxygen 1.5.1