Main Page   Modules   Data Structures   File List   Data Fields   Globals  

pcap.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
00003  *  The Regents of the University of California.  All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. All advertising materials mentioning features or use of this software
00014  *    must display the following acknowledgement:
00015  *  This product includes software developed by the Computer Systems
00016  *  Engineering Group at Lawrence Berkeley Laboratory.
00017  * 4. Neither the name of the University nor of the Laboratory may be used
00018  *    to endorse or promote products derived from this software without
00019  *    specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00022  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00025  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00026  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00027  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00028  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00030  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  */
00033 
00034 #ifndef lint
00035 static const char rcsid[] =
00036     "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.41 2002/08/02 03:44:21 guy Exp $ (LBL)";
00037 #endif
00038 
00039 #ifdef HAVE_CONFIG_H
00040 #include "config.h"
00041 #endif
00042 
00043 #ifdef WIN32
00044 #include <pcap-stdinc.h>
00045 #else /* WIN32 */
00046 #include <sys/types.h>
00047 #endif /* WIN32 */
00048 
00049 #include <stdio.h>
00050 #include <stdlib.h>
00051 #include <string.h>
00052 #ifndef WIN32
00053 #include <unistd.h>
00054 #endif
00055 #include <fcntl.h>
00056 #include <errno.h>
00057 
00058 #ifdef HAVE_OS_PROTO_H
00059 #include "os-proto.h"
00060 #endif
00061 
00062 #include "pcap-int.h"
00063 
00064 int
00065 pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
00066 {
00067 
00068     if (p->sf.rfile != NULL)
00069         return (pcap_offline_read(p, cnt, callback, user));
00070     return (pcap_read(p, cnt, callback, user));
00071 }
00072 
00073 int
00074 pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
00075 {
00076     register int n;
00077 
00078     for (;;) {
00079         if (p->sf.rfile != NULL)
00080             n = pcap_offline_read(p, cnt, callback, user);
00081         else {
00082             /*
00083              * XXX keep reading until we get something
00084              * (or an error occurs)
00085              */
00086             do {
00087                 n = pcap_read(p, cnt, callback, user);
00088             } while (n == 0);
00089         }
00090         if (n <= 0)
00091             return (n);
00092         if (cnt > 0) {
00093             cnt -= n;
00094             if (cnt <= 0)
00095                 return (0);
00096         }
00097     }
00098 }
00099 
00100 struct singleton {
00101     struct pcap_pkthdr *hdr;
00102     const u_char *pkt;
00103 };
00104 
00105 
00106 static void
00107 pcap_oneshot(u_char *userData, const struct pcap_pkthdr *h, const u_char *pkt)
00108 {
00109     struct singleton *sp = (struct singleton *)userData;
00110     *sp->hdr = *h;
00111     sp->pkt = pkt;
00112 }
00113 
00114 const u_char *
00115 pcap_next(pcap_t *p, struct pcap_pkthdr *h)
00116 {
00117     struct singleton s;
00118 
00119     s.hdr = h;
00120     if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <= 0)
00121         return (0);
00122     return (s.pkt);
00123 }
00124 
00125 int
00126 pcap_datalink(pcap_t *p)
00127 {
00128     return (p->linktype);
00129 }
00130 
00131 int
00132 pcap_snapshot(pcap_t *p)
00133 {
00134     return (p->snapshot);
00135 }
00136 
00137 int
00138 pcap_is_swapped(pcap_t *p)
00139 {
00140     return (p->sf.swapped);
00141 }
00142 
00143 int
00144 pcap_major_version(pcap_t *p)
00145 {
00146     return (p->sf.version_major);
00147 }
00148 
00149 int
00150 pcap_minor_version(pcap_t *p)
00151 {
00152     return (p->sf.version_minor);
00153 }
00154 
00155 FILE *
00156 pcap_file(pcap_t *p)
00157 {
00158     return (p->sf.rfile);
00159 }
00160 
00161 int
00162 pcap_fileno(pcap_t *p)
00163 {
00164 #ifndef WIN32
00165     return (p->fd);
00166 #else
00167     if (p->adapter != NULL)
00168         return ((int)(DWORD)p->adapter->hFile);
00169     else
00170         return (-1);
00171 #endif
00172 }
00173 
00174 void
00175 pcap_perror(pcap_t *p, char *prefix)
00176 {
00177     fprintf(stderr, "%s: %s\n", prefix, p->errbuf);
00178 }
00179 
00180 char *
00181 pcap_geterr(pcap_t *p)
00182 {
00183     return (p->errbuf);
00184 }
00185 
00186 /*
00187  * NOTE: in the future, these may need to call platform-dependent routines,
00188  * e.g. on platforms with memory-mapped packet-capture mechanisms where
00189  * "pcap_read()" uses "select()" or "poll()" to wait for packets to arrive.
00190  */
00191 int
00192 pcap_getnonblock(pcap_t *p, char *errbuf)
00193 {
00194 #ifndef WIN32
00195     int fdflags;
00196 #endif
00197 
00198     if (p->sf.rfile != NULL) {
00199         /*
00200          * This is a savefile, not a live capture file, so
00201          * never say it's in non-blocking mode.
00202          */
00203         return (0);
00204     }
00205 #ifndef WIN32
00206     fdflags = fcntl(p->fd, F_GETFL, 0);
00207     if (fdflags == -1) {
00208         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
00209             pcap_strerror(errno));
00210         return (-1);
00211     }
00212     if (fdflags & O_NONBLOCK)
00213         return (1);
00214     else
00215         return (0);
00216 #else
00217     return (p->nonblock);
00218 #endif
00219 }
00220 
00221 int
00222 pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
00223 {
00224 #ifndef WIN32
00225     int fdflags;
00226 #else
00227     int newtimeout;
00228 #endif
00229 
00230     if (p->sf.rfile != NULL) {
00231         /*
00232          * This is a savefile, not a live capture file, so
00233          * ignore requests to put it in non-blocking mode.
00234          */
00235         return (0);
00236     }
00237 #ifndef WIN32
00238     fdflags = fcntl(p->fd, F_GETFL, 0);
00239     if (fdflags == -1) {
00240         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
00241             pcap_strerror(errno));
00242         return (-1);
00243     }
00244     if (nonblock)
00245         fdflags |= O_NONBLOCK;
00246     else
00247         fdflags &= ~O_NONBLOCK;
00248     if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
00249         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
00250             pcap_strerror(errno));
00251         return (-1);
00252     }
00253 #else
00254     if (nonblock) {
00255         /*
00256          * Set the read timeout to -1 for non-blocking mode.
00257          */
00258         newtimeout = -1;
00259     } else {
00260         /*
00261          * Restore the timeout set when the device was opened.
00262          * (Note that this may be -1, in which case we're not
00263          * really leaving non-blocking mode.)
00264          */
00265         newtimeout = p->timeout;
00266     }
00267     if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
00268         snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
00269             "PacketSetReadTimeout: %s", pcap_win32strerror());
00270         return (-1);
00271     }
00272     p->nonblock = (newtimeout == -1);
00273 #endif
00274     return (0);
00275 }
00276 
00277 #ifdef WIN32
00278 /*
00279  * Generate a string for the last Win32-specific error (i.e. an error generated when 
00280  * calling a Win32 API).
00281  * For errors occurred during standard C calls, we still use pcap_strerror()
00282  */
00283 char *
00284 pcap_win32strerror(void)
00285 {
00286     DWORD error;
00287     static char errbuf[PCAP_ERRBUF_SIZE+1];
00288     int errlen;
00289 
00290     error = GetLastError();
00291     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
00292         PCAP_ERRBUF_SIZE, NULL);
00293 
00294     /*
00295      * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
00296      * message.  Get rid of it.
00297      */
00298     errlen = strlen(errbuf);
00299     if (errlen >= 2) {
00300         errbuf[errlen - 1] = '\0';
00301         errbuf[errlen - 2] = '\0';
00302     }
00303     return (errbuf);
00304 }
00305 #endif
00306 
00307 /*
00308  * Not all systems have strerror().
00309  */
00310 char *
00311 pcap_strerror(int errnum)
00312 {
00313 #ifdef HAVE_STRERROR
00314     return (strerror(errnum));
00315 #else
00316     extern int sys_nerr;
00317     extern const char *const sys_errlist[];
00318     static char ebuf[20];
00319 
00320     if ((unsigned int)errnum < sys_nerr)
00321         return ((char *)sys_errlist[errnum]);
00322     (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
00323     return(ebuf);
00324 #endif
00325 }
00326 
00327 pcap_t *
00328 pcap_open_dead(int linktype, int snaplen)
00329 {
00330     pcap_t *p;
00331 
00332     p = malloc(sizeof(*p));
00333     if (p == NULL)
00334         return NULL;
00335     memset (p, 0, sizeof(*p));
00336 #ifndef WIN32
00337     p->fd = -1;
00338 #else
00339     p->adapter = NULL;
00340 #endif /* WIN32 */
00341     p->snapshot = snaplen;
00342     p->linktype = linktype;
00343     return p;
00344 }
00345 
00346 void
00347 pcap_close(pcap_t *p)
00348 {
00349     /*XXX*/
00350 #ifndef WIN32
00351     if (p->fd >= 0) {
00352 #ifdef linux
00353         pcap_close_linux(p);
00354 #endif
00355         close(p->fd);
00356     }
00357 #else /* WIN32 */
00358     if (p->adapter != NULL) {
00359         PacketCloseAdapter(p->adapter);
00360         p->adapter = NULL;
00361     }
00362 #endif /* WIN32 */
00363     if (p->sf.rfile != NULL) {
00364         if (p->sf.rfile != stdin)
00365             (void)fclose(p->sf.rfile);
00366         if (p->sf.base != NULL)
00367             free(p->sf.base);
00368     } else if (p->buffer != NULL)
00369         free(p->buffer);
00370 
00371     pcap_freecode(&p->fcode);
00372     free(p);
00373 }

documentation. Copyright (c) 2002 Politecnico di Torino. All rights reserved.