00001 #include "packet_obsd_bpf.h"
00002 #ifdef _OBSD_
00003
00004 #include <sys/types.h>
00005 #include <sys/socket.h>
00006 #include <netinet/in.h>
00007 #include <unistd.h>
00008 #include <fcntl.h>
00009 #include <sys/ioctl.h>
00010 #include <net/if.h>
00011 #include <time.h>
00012 #include <net/bpf.h>
00013 #include <errno.h>
00014 #include <poll.h>
00015 #include <err.h>
00016 #include <string.h>
00017 #include <stdlib.h>
00018 #include <stdio.h>
00019
00020 #define DEBUG
00021
00022 #define FATAL 1
00023 #define NONFATAL 0
00024
00025 extern GlobalVars Globals;
00026
00027
00028
00029
00030 static int
00031 bpf_open()
00032 {
00033 int fd;
00034 int n = 0;
00035 char device[sizeof "/dev/bpf0000000000"];
00036
00037
00038 do {
00039 (void) snprintf(device, sizeof device, "/dev/bpf%d", n++);
00040 fd = open(device, O_RDWR);
00041 } while (fd < 0 && errno == EBUSY);
00042
00043 if (fd < 0) {
00044 err(FATAL, "%s: %s", device, strerror(errno));
00045
00046 }
00047 return fd;
00048 }
00049
00050
00051
00052
00053 int GetIfrMTU(char *name) {
00054 int fd;
00055 struct ifreq ifr;
00056 int retval;
00057
00058 retval = -1;
00059 fd = socket(AF_INET, SOCK_DGRAM, 0);
00060 if ( fd < 0) {
00061 printf("Couldn't create socket for MTU\n");
00062 return -1;
00063 }
00064
00065 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
00066 if (ioctl(fd, SIOCGIFMTU, &ifr) == 0)
00067 retval = ifr.ifr_metric;
00068 else
00069 printf("ioctl(SIOCGIFMTU)");
00070 close(fd);
00071 return retval;
00072 }
00073
00074
00075
00076
00077
00078 int OpenInterfaceOBSDBPF(int InterfaceID){
00079 int fd;
00080 struct ifreq ifr;
00081 u_int dlt;
00082 int immediate;
00083 int promisc;
00084 int link;
00085 struct timeval timeout;
00086 InterfaceRec* Interface;
00087
00088 #ifdef DEBUGPATH
00089 printf("In OpenInterfaceOBSDBPF\n");
00090 #endif
00091
00092 Interface=&Globals.Interfaces[InterfaceID];
00093
00094 #ifdef DEBUG
00095 printf("Opening interface %s\n", Interface->Name);
00096 #endif
00097
00098 fd = bpf_open();
00099
00100 (void) strncpy(ifr.ifr_name, Interface->Name, sizeof ifr.ifr_name);
00101 if (ioctl(fd, BIOCSETIF, (caddr_t) & ifr) < 0) {
00102 err(FATAL, "BIOCSETIF: %s", strerror(errno));
00103
00104 }
00105
00106
00107 if (ioctl(fd, BIOCGDLT, (caddr_t) & dlt) < 0) {
00108 err(FATAL, "BIOCGDLT: %s", strerror(errno));
00109
00110 }
00111 if (dlt != DLT_EN10MB) {
00112 err(FATAL, "%s is not an ethernet", Interface->Name);
00113
00114 }
00115
00116 link=1;
00117 if (ioctl(fd, BIOCSHDRCMPLT, &link) < 0){
00118 printf("Couldn't turn off auto mac address\n");
00119 exit(0);
00120 }
00121
00122 promisc=1;
00123 if (ioctl(fd, BIOCPROMISC, &promisc) < 0) {
00124 printf("Couldn't enter promisc mode\n");
00125 exit(1);
00126 }
00127 if (dlt != DLT_EN10MB) {
00128 err(FATAL, "%s is not an ethernet", Interface->Name);
00129
00130 }
00131
00132
00133 immediate = 1;
00134 if (ioctl(fd, BIOCIMMEDIATE, &immediate) < 0) {
00135 err(FATAL, "BIOCIMMEDIATE: %s", strerror(errno));
00136
00137 }
00138
00139
00140 timeout.tv_sec=0;
00141 timeout.tv_usec=1;
00142 if (ioctl(fd, BIOCSRTIMEOUT, &timeout) < 0) {
00143 err(FATAL, "BIOCSRTIMEOUT: %s", strerror(errno));
00144
00145 }
00146
00147
00148
00149 immediate = 0;
00150 if (ioctl(fd, BIOCIMMEDIATE, &immediate) < 0) {
00151 err(FATAL, "BIOCIMMEDIATE: %s", strerror(errno));
00152
00153 }
00154
00155 Interface->FD=fd;
00156 Interface->MTU=GetIfrMTU(Interface->Name);
00157 if (Interface->MTU==-1) Interface->MTU=1500;
00158
00159 Interface->IsPollable=TRUE;
00160
00161 return TRUE;
00162 }
00163
00164
00165
00166
00167
00168 int ReadPacketOBSDBPF(int InterfaceID){
00169 int bufsize1, cc;
00170 u_char *buf1, *bp, *ep;
00171
00172 InterfaceRec* interface;
00173 PacketRec* p;
00174 int PacketSlot;
00175
00176 #ifdef DEBUGPATH
00177 printf("In ReadPacketOBSDBPF\n");
00178 #endif
00179
00180 interface=&Globals.Interfaces[InterfaceID];
00181
00182
00183 if (ioctl(interface->FD, BIOCGBLEN, (caddr_t) & bufsize1) < 0) {
00184 err(FATAL, "BIOCGBLEN: %s", strerror(errno));
00185
00186 }
00187 #ifdef DEBUG
00188 printf("Buffer size1 is %i\n",bufsize1);
00189 #endif
00190
00191 buf1 = (u_char *) malloc((unsigned) bufsize1);
00192 if (buf1 == 0) {
00193 err(FATAL, "malloc: %s", strerror(errno));
00194
00195 }
00196
00197 again:
00198 cc = read(interface->FD, (char *) buf1, bufsize1);
00199 #ifdef DEBUG1
00200 printf("Read %i bytes from the bpf\n",cc);
00201 #endif
00202
00203 if (cc==0){
00204 free(buf1);
00205 return TRUE;
00206 }
00207
00208
00209 if (cc < 0 && errno == EINTR)
00210 goto again;
00211 if (cc < 0) {
00212 if (errno == EINVAL &&
00213 (lseek(interface->FD, 0, SEEK_CUR) + bufsize1) < 0) {
00214 (void) lseek(interface->FD, 0, 0);
00215 goto again;
00216 }
00217 err(FATAL, "read: %s", strerror(errno));
00218
00219
00220 }
00221
00222
00223 #define bhp ((struct bpf_hdr *)bp)
00224 bp = buf1;
00225 ep = bp + cc;
00226 while (bp < ep) {
00227 register int caplen, hdrlen;
00228
00229 caplen = bhp->bh_caplen;
00230 hdrlen = bhp->bh_hdrlen;
00231
00232 #ifdef DEBUG
00233 printf("This packet is %u bytes\n",bhp->bh_caplen);
00234 #endif
00235
00236 PacketSlot=GetEmptyPacket();
00237 if (PacketSlot==PACKET_NONE) return FALSE;
00238 p=&Globals.Packets[PacketSlot];
00239 p->InterfaceNum=InterfaceID;
00240
00241
00242 p->PacketLen=bhp->bh_caplen;
00243 p->tv.tv_sec=bhp->bh_tstamp.tv_sec;
00244 p->tv.tv_usec=bhp->bh_tstamp.tv_usec;
00245 memcpy(p->RawPacket, bp+18, p->PacketLen);
00246
00247
00248 if (!AddPacketToPending(PacketSlot)){
00249 printf("Coulnd't add packet to pending queue\n");
00250 ReturnEmptyPacket(PacketSlot);
00251 free(buf1);
00252 return FALSE;
00253 }
00254 bp += BPF_WORDALIGN(hdrlen + caplen);
00255 }
00256
00257 free(buf1);
00258 return TRUE;
00259 }
00260
00261
00262
00263
00264 int WritePacketOBSDBPF(int InterfaceID, unsigned char* Packet, int PacketLen){
00265 InterfaceRec* interface;
00266 int cc;
00267
00268 #ifdef DEBUGPATH
00269 printf("In WritePacketOBSDBPF\n");
00270 #endif
00271
00272 interface=&Globals.Interfaces[InterfaceID];
00273
00274 #ifdef DEBUG
00275 printf("Writing packet OBSD to interface %s\n",interface->Name);
00276 #endif
00277
00278 cc=write(interface->FD, Packet, PacketLen);
00279 if (cc!=PacketLen){
00280 #ifdef DEBUG
00281 printf("write_packet: Failed to write packet ot interface %s\n",interface->Name);
00282 #endif
00283 return FALSE;
00284 }
00285
00286 return TRUE;
00287 }
00288
00289
00290
00291
00292 void* OBSDBPFLoopFunc(void* v){
00293 int InterfaceID;
00294
00295 #ifdef DEBUGPATH
00296 printf("In OBSDBPFLoopFunc\n");
00297 #endif
00298
00299 InterfaceID=(int)v;
00300 while (!Globals.Done){
00301 ReadPacketOBSDBPF(InterfaceID);
00302 }
00303
00304 return NULL;
00305 }
00306
00307
00308
00309
00310 int LoopThreadOBSDBPF(int InterfaceID){
00311 #ifdef DEBUGPATH
00312 printf("In loopThreadOBSDBPF\n");
00313 #endif
00314
00315 #ifndef HAS_THREADS
00316 return FALSE;
00317 #else
00318
00319 #ifdef DEBUG
00320 printf("Starting Thread for interface %s\n",Globals.Interfaces[InterfaceID].Name);
00321 #endif
00322
00323 Globals.Interfaces[InterfaceID].ThreadID=pthread_create(
00324 &Globals.Interfaces[InterfaceID].Thread,
00325 NULL,
00326 OBSDBPFLoopFunc,
00327 (void*)InterfaceID
00328 );
00329
00330 return (!Globals.Interfaces[InterfaceID].ThreadID);
00331 #endif
00332 }
00333
00334 #endif