Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

# 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[] _U_ =
    00036     "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.63.2.9 2004/03/25 22:40:52 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 _MSC_VER
    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 #ifdef HAVE_DAG_API
    00065 #include <dagnew.h>
    00066 #include <dagapi.h>
    00067 #endif
    00068
    00069 #ifdef HAVE_REMOTE
    00070 #include <pcap-remote.h>
    00071 #endif
    00072
    00073 int
    00074 pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    00075 {
    00076
    00077     return p->read_op(p, cnt, callback, user);
    00078 }
    00079
    00080 /*
    00081  * XXX - is this necessary?
    00082  */
    00083 int
    00084 pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    00085 {
    00086
    00087     return p->read_op(p, cnt, callback, user);
    00088 }
    00089
    00090 int
    00091 pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    00092 {
    00093     register int n;
    00094
    00095 #ifdef HAVE_REMOTE
    00096     /* Checks the capture type */
    00097     if (p->rmt_clientside)
    00098     {
    00099         /* We are on an remote capture */
    00100         if (!p->rmt_capstarted)
    00101         {
    00102             // if the capture has not started yet, please start it
    00103             if (pcap_startcapture_remote(p) )
    00104                 return -1;
    00105         }
    00106     }
    00107 #endif /* HAVE_REMOTE */
    00108
    00109     for (;;) {
    00110         if (p->sf.rfile != NULL) {
    00111             /*
    00112              * 0 means EOF, so don't loop if we get 0.
    00113              */
    00114             n = pcap_offline_read(p, cnt, callback, user);
    00115         } else {
    00116             /*
    00117              * XXX keep reading until we get something
    00118              * (or an error occurs)
    00119              */
    00120             do {
    00121                 n = p->read_op(p, cnt, callback, user);
    00122             } while (n == 0);
    00123         }
    00124         if (n <= 0)
    00125             return (n);
    00126         if (cnt > 0) {
    00127             cnt -= n;
    00128             if (cnt <= 0)
    00129                 return (0);
    00130         }
    00131     }
    00132 }
    00133
    00134 struct singleton {
    00135     struct pcap_pkthdr *hdr;
    00136     const u_char *pkt;
    00137 };
    00138
    00139
    00140 static void
    00141 pcap_oneshot(u_char *userData, const struct pcap_pkthdr *h, const u_char *pkt)
    00142 {
    00143     struct singleton *sp = (struct singleton *)userData;
    00144     *sp->hdr = *h;
    00145     sp->pkt = pkt;
    00146 }
    00147
    00148 const u_char *
    00149 pcap_next(pcap_t *p, struct pcap_pkthdr *h)
    00150 {
    00151     struct singleton s;
    00152
    00153     s.hdr = h;
    00154     if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <= 0)
    00155         return (0);
    00156     return (s.pkt);
    00157 }
    00158
    00159 struct pkt_for_fakecallback {
    00160     struct pcap_pkthdr *hdr;
    00161     const u_char **pkt;
    00162 };
    00163
    00164 static void
    00165 pcap_fakecallback(u_char *userData, const struct pcap_pkthdr *h,
    00166     const u_char *pkt)
    00167 {
    00168     struct pkt_for_fakecallback *sp = (struct pkt_for_fakecallback *)userData;
    00169
    00170     *sp->hdr = *h;
    00171     *sp->pkt = pkt;
    00172 }
    00173
    00174 int
    00175 pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
    00176     const u_char **pkt_data)
    00177 {
    00178     struct pkt_for_fakecallback s;
    00179
    00180     s.hdr = &p->pcap_header;
    00181     s.pkt = pkt_data;
    00182
    00183     /* Saves a pointer to the packet headers */
    00184     *pkt_header= &p->pcap_header;
    00185
    00186 #ifdef HAVE_REMOTE
    00187     /* Checks the capture type */
    00188     if (p->rmt_clientside)
    00189     {
    00190         /* We are on an remote capture */
    00191         if (!p->rmt_capstarted)
    00192         {
    00193             // if the capture has not started yet, please start it
    00194             if (pcap_startcapture_remote(p) )
    00195                 return -1;
    00196         }
    00197
    00198         return pcap_read_nocb_remote(p, pkt_header, (u_char **) pkt_data);
    00199     }
    00200 #endif /* HAVE_REMOTE */
    00201
    00202     if (p->sf.rfile != NULL) {
    00203         int status;
    00204
    00205         /* We are on an offline capture */
    00206         status = pcap_offline_read(p, 1, pcap_fakecallback,
    00207             (u_char *)&s);
    00208
    00209         /*
    00210          * Return codes for pcap_offline_read() are:
    00211          *   -  0: EOF
    00212          *   - -1: error
    00213          *   - >1: OK
    00214          * The first one ('0') conflicts with the return code of
    00215          * 0 from pcap_read() meaning "no packets arrived before
    00216          * the timeout expired", so we map it to -2 so you can
    00217          * distinguish between an EOF from a savefile and a
    00218          * "no packets arrived before the timeout expired, try
    00219          * again" from a live capture.
    00220          */
    00221         if (status == 0)
    00222             return (-2);
    00223         else
    00224             return (status);
    00225     }
    00226
    00227     /*
    00228      * Return codes for pcap_read() are:
    00229      *   -  0: timeout
    00230      *   - -1: error
    00231      *   - -2: loop was broken out of with pcap_breakloop()
    00232      *   - >1: OK
    00233      * The first one ('0') conflicts with the return code of 0 from
    00234      * pcap_offline_read() meaning "end of file".
    00235     */
    00236     return (p->read_op(p, 1, pcap_fakecallback, (u_char *)&s));
    00237 }
    00238
    00239 /*
    00240  * Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate.
    00241  */
    00242 void
    00243 pcap_breakloop(pcap_t *p)
    00244 {
    00245     p->break_loop = 1;
    00246 }
    00247
    00248 int
    00249 pcap_datalink(pcap_t *p)
    00250 {
    00251     return (p->linktype);
    00252 }
    00253
    00254 int
    00255 pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
    00256 {
    00257     if (p->dlt_count == 0) {
    00258         /*
    00259          * We couldn't fetch the list of DLTs, which means
    00260          * this platform doesn't support changing the
    00261          * DLT for an interface.  Return a list of DLTs
    00262          * containing only the DLT this device supports.
    00263          */
    00264         *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer));
    00265         if (*dlt_buffer == NULL) {
    00266             (void)snprintf(p->errbuf, sizeof(p->errbuf),
    00267                 "malloc: %s", pcap_strerror(errno));
    00268             return (-1);
    00269         }
    00270         **dlt_buffer = p->linktype;
    00271         return (1);
    00272     } else {
    00273         *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer) * p->dlt_count);
    00274         if (*dlt_buffer == NULL) {
    00275             (void)snprintf(p->errbuf, sizeof(p->errbuf),
    00276                 "malloc: %s", pcap_strerror(errno));
    00277             return (-1);
    00278         }
    00279         (void)memcpy(*dlt_buffer, p->dlt_list,
    00280             sizeof(**dlt_buffer) * p->dlt_count);
    00281         return (p->dlt_count);
    00282     }
    00283 }
    00284
    00285 int
    00286 pcap_set_datalink(pcap_t *p, int dlt)
    00287 {
    00288     int i;
    00289     const char *dlt_name;
    00290
    00291     if (p->dlt_count == 0 || p->set_datalink_op == NULL) {
    00292         /*
    00293          * We couldn't fetch the list of DLTs, or we don't
    00294          * have a "set datalink" operation, which means
    00295          * this platform doesn't support changing the
    00296          * DLT for an interface.  Check whether the new
    00297          * DLT is the one this interface supports.
    00298          */
    00299         if (p->linktype != dlt)
    00300             goto unsupported;
    00301
    00302         /*
    00303          * It is, so there's nothing we need to do here.
    00304          */
    00305         return (0);
    00306     }
    00307     for (i = 0; i < p->dlt_count; i++)
    00308         if (p->dlt_list[i] == dlt)
    00309             break;
    00310     if (i >= p->dlt_count)
    00311         goto unsupported;
    00312     if (p->set_datalink_op(p, dlt) == -1)
    00313         return (-1);
    00314     p->linktype = dlt;
    00315     return (0);
    00316
    00317 unsupported:
    00318     dlt_name = pcap_datalink_val_to_name(dlt);
    00319     if (dlt_name != NULL) {
    00320         (void) snprintf(p->errbuf, sizeof(p->errbuf),
    00321             "%s is not one of the DLTs supported by this device",
    00322             dlt_name);
    00323     } else {
    00324         (void) snprintf(p->errbuf, sizeof(p->errbuf),
    00325             "DLT %d is not one of the DLTs supported by this device",
    00326             dlt);
    00327     }
    00328     return (-1);
    00329 }
    00330
    00331 struct dlt_choice {
    00332     const char *name;
    00333     const char *description;
    00334     int dlt;
    00335 };
    00336
    00337 #define DLT_CHOICE(code, description) { #code, description, code }
    00338 #define DLT_CHOICE_SENTINEL { NULL, NULL, 0 }
    00339
    00340 static struct dlt_choice dlt_choices[] = {
    00341     DLT_CHOICE(DLT_NULL, "BSD loopback"),
    00342     DLT_CHOICE(DLT_EN10MB, "Ethernet"),
    00343     DLT_CHOICE(DLT_IEEE802, "Token ring"),
    00344     DLT_CHOICE(DLT_ARCNET, "ARCNET"),
    00345     DLT_CHOICE(DLT_SLIP, "SLIP"),
    00346     DLT_CHOICE(DLT_PPP, "PPP"),
    00347     DLT_CHOICE(DLT_FDDI, "FDDI"),
    00348     DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 IP-over-ATM"),
    00349     DLT_CHOICE(DLT_RAW, "Raw IP"),
    00350     DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"),
    00351     DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"),
    00352     DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"),
    00353     DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"),
    00354     DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"),
    00355     DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"),
    00356     DLT_CHOICE(DLT_IEEE802_11, "802.11"),
    00357     DLT_CHOICE(DLT_FRELAY, "Frame Relay"),
    00358     DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"),
    00359     DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"),
    00360     DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"),
    00361     DLT_CHOICE(DLT_LTALK, "Localtalk"),
    00362     DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"),
    00363     DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"),
    00364     DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"),
    00365     DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"),
    00366     DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus BSD radio information header"),
    00367     DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"),
    00368     DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"),
    00369     DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
    00370     DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"),
    00371     DLT_CHOICE_SENTINEL
    00372 };
    00373
    00374 /*
    00375  * This array is designed for mapping upper and lower case letter
    00376  * together for a case independent comparison.  The mappings are
    00377  * based upon ascii character sequences.
    00378  */
    00379 static const u_char charmap[] = {
    00380     (u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003',
    00381     (u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007',
    00382     (u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013',
    00383     (u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017',
    00384     (u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023',
    00385     (u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027',
    00386     (u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033',
    00387     (u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037',
    00388     (u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043',
    00389     (u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047',
    00390     (u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053',
    00391     (u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057',
    00392     (u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063',
    00393     (u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067',
    00394     (u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073',
    00395     (u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077',
    00396     (u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143',
    00397     (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
    00398     (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
    00399     (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
    00400     (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
    00401     (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
    00402     (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133',
    00403     (u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137',
    00404     (u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143',
    00405     (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
    00406     (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
    00407     (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
    00408     (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
    00409     (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
    00410     (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173',
    00411     (u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177',
    00412     (u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203',
    00413     (u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207',
    00414     (u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213',
    00415     (u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217',
    00416     (u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223',
    00417     (u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227',
    00418     (u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233',
    00419     (u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237',
    00420     (u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243',
    00421     (u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247',
    00422     (u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253',
    00423     (u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257',
    00424     (u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263',
    00425     (u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267',
    00426     (u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273',
    00427     (u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277',
    00428     (u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343',
    00429     (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
    00430     (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
    00431     (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
    00432     (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
    00433     (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
    00434     (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333',
    00435     (u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337',
    00436     (u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343',
    00437     (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
    00438     (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
    00439     (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
    00440     (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
    00441     (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
    00442     (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373',
    00443     (u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377',
    00444 };
    00445
    00446 int
    00447 pcap_strcasecmp(const char *s1, const char *s2)
    00448 {
    00449     register const u_char   *cm = charmap,
    00450                 *us1 = (u_char *)s1,
    00451                 *us2 = (u_char *)s2;
    00452
    00453     while (cm[*us1] == cm[*us2++])
    00454         if (*us1++ == '\0')
    00455             return(0);
    00456     return (cm[*us1] - cm[*--us2]);
    00457 }
    00458
    00459 int
    00460 pcap_datalink_name_to_val(const char *name)
    00461 {
    00462     int i;
    00463
    00464     for (i = 0; dlt_choices[i].name != NULL; i++) {
    00465         if (pcap_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1,
    00466             name) == 0)
    00467             return (dlt_choices[i].dlt);
    00468     }
    00469     return (-1);
    00470 }
    00471
    00472 const char *
    00473 pcap_datalink_val_to_name(int dlt)
    00474 {
    00475     int i;
    00476
    00477     for (i = 0; dlt_choices[i].name != NULL; i++) {
    00478         if (dlt_choices[i].dlt == dlt)
    00479             return (dlt_choices[i].name + sizeof("DLT_") - 1);
    00480     }
    00481     return (NULL);
    00482 }
    00483
    00484 const char *
    00485 pcap_datalink_val_to_description(int dlt)
    00486 {
    00487     int i;
    00488
    00489     for (i = 0; dlt_choices[i].name != NULL; i++) {
    00490         if (dlt_choices[i].dlt == dlt)
    00491             return (dlt_choices[i].description);
    00492     }
    00493     return (NULL);
    00494 }
    00495
    00496 int
    00497 pcap_snapshot(pcap_t *p)
    00498 {
    00499     return (p->snapshot);
    00500 }
    00501
    00502 int
    00503 pcap_is_swapped(pcap_t *p)
    00504 {
    00505     return (p->sf.swapped);
    00506 }
    00507
    00508 int
    00509 pcap_major_version(pcap_t *p)
    00510 {
    00511     return (p->sf.version_major);
    00512 }
    00513
    00514 int
    00515 pcap_minor_version(pcap_t *p)
    00516 {
    00517     return (p->sf.version_minor);
    00518 }
    00519
    00520 FILE *
    00521 pcap_file(pcap_t *p)
    00522 {
    00523     return (p->sf.rfile);
    00524 }
    00525
    00526 int
    00527 pcap_fileno(pcap_t *p)
    00528 {
    00529 #ifdef HAVE_REMOTE
    00530     if (p->rmt_clientside)
    00531         return(p->rmt_sockdata);
    00532 #endif /* HAVE_REMOTE */
    00533
    00534 #ifndef WIN32
    00535     return (p->fd);
    00536 #else
    00537     if (p->adapter != NULL)
    00538         return ((int)(DWORD)p->adapter->hFile);
    00539     else
    00540         return (-1);
    00541 #endif
    00542 }
    00543
    00544 #ifndef WIN32
    00545 int
    00546 pcap_get_selectable_fd(pcap_t *p)
    00547 {
    00548     return (p->selectable_fd);
    00549 }
    00550 #endif
    00551
    00552 void
    00553 pcap_perror(pcap_t *p, char *prefix)
    00554 {
    00555     fprintf(stderr, "%s: %s\n", prefix, p->errbuf);
    00556 }
    00557
    00558 char *
    00559 pcap_geterr(pcap_t *p)
    00560 {
    00561     return (p->errbuf);
    00562 }
    00563
    00564 int
    00565 pcap_getnonblock(pcap_t *p, char *errbuf)
    00566 {
    00567     return p->getnonblock_op(p, errbuf);
    00568 }
    00569
    00570 /*
    00571  * Get the current non-blocking mode setting, under the assumption that
    00572  * it's just the standard POSIX non-blocking flag.
    00573  *
    00574  * We don't look at "p->nonblock", in case somebody tweaked the FD
    00575  * directly.
    00576  */
    00577 #ifndef WIN32
    00578 int
    00579 pcap_getnonblock_fd(pcap_t *p, char *errbuf)
    00580 {
    00581     int fdflags;
    00582
    00583     fdflags = fcntl(p->fd, F_GETFL, 0);
    00584     if (fdflags == -1) {
    00585         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
    00586             pcap_strerror(errno));
    00587         return (-1);
    00588     }
    00589     if (fdflags & O_NONBLOCK)
    00590         return (1);
    00591     else
    00592         return (0);
    00593 }
    00594 #endif
    00595
    00596 int
    00597 pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
    00598 {
    00599     return p->setnonblock_op(p, nonblock, errbuf);
    00600 }
    00601
    00602 #ifndef WIN32
    00603 /*
    00604  * Set non-blocking mode, under the assumption that it's just the
    00605  * standard POSIX non-blocking flag.  (This can be called by the
    00606  * per-platform non-blocking-mode routine if that routine also
    00607  * needs to do some additional work.)
    00608  */
    00609 int
    00610 pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
    00611 {
    00612     int fdflags;
    00613
    00614     fdflags = fcntl(p->fd, F_GETFL, 0);
    00615     if (fdflags == -1) {
    00616         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
    00617             pcap_strerror(errno));
    00618         return (-1);
    00619     }
    00620     if (nonblock)
    00621         fdflags |= O_NONBLOCK;
    00622     else
    00623         fdflags &= ~O_NONBLOCK;
    00624     if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
    00625         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
    00626             pcap_strerror(errno));
    00627         return (-1);
    00628     }
    00629     return (0);
    00630 }
    00631 #endif
    00632
    00633 #ifdef WIN32
    00634 /*
    00635  * Generate a string for the last Win32-specific error (i.e. an error generated when
    00636  * calling a Win32 API).
    00637  * For errors occurred during standard C calls, we still use pcap_strerror()
    00638  */
    00639 char *
    00640 pcap_win32strerror(void)
    00641 {
    00642     DWORD error;
    00643     static char errbuf[PCAP_ERRBUF_SIZE+1];
    00644     int errlen;
    00645
    00646     error = GetLastError();
    00647     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
    00648         PCAP_ERRBUF_SIZE, NULL);
    00649
    00650     /*
    00651      * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
    00652      * message.  Get rid of it.
    00653      */
    00654     errlen = strlen(errbuf);
    00655     if (errlen >= 2) {
    00656         errbuf[errlen - 1] = '\0';
    00657         errbuf[errlen - 2] = '\0';
    00658     }
    00659     return (errbuf);
    00660 }
    00661 #endif
    00662
    00663 /*
    00664  * Not all systems have strerror().
    00665  */
    00666 char *
    00667 pcap_strerror(int errnum)
    00668 {
    00669 #ifdef HAVE_STRERROR
    00670     return (strerror(errnum));
    00671 #else
    00672     extern int sys_nerr;
    00673     extern const char *const sys_errlist[];
    00674     static char ebuf[20];
    00675
    00676     if ((unsigned int)errnum < sys_nerr)
    00677         return ((char *)sys_errlist[errnum]);
    00678     (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
    00679     return(ebuf);
    00680 #endif
    00681 }
    00682
    00683 int
    00684 pcap_setfilter(pcap_t *p, struct bpf_program *fp)
    00685 {
    00686     return p->setfilter_op(p, fp);
    00687 }
    00688
    00689 int
    00690 pcap_stats(pcap_t *p, struct pcap_stat *ps)
    00691 {
    00692     return p->stats_op(p, ps);
    00693 }
    00694
    00695 static int
    00696 pcap_stats_dead(pcap_t *p, struct pcap_stat *ps)
    00697 {
    00698     snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    00699         "Statistics aren't available from a pcap_open_dead pcap_t");
    00700     return (-1);
    00701 }
    00702
    00703 static void
    00704 pcap_close_dead(pcap_t *p)
    00705 {
    00706     /* Nothing to do. */
    00707 }
    00708
    00709 pcap_t *
    00710 pcap_open_dead(int linktype, int snaplen)
    00711 {
    00712     pcap_t *p;
    00713
    00714     p = malloc(sizeof(*p));
    00715     if (p == NULL)
    00716         return NULL;
    00717     memset (p, 0, sizeof(*p));
    00718     p->snapshot = snaplen;
    00719     p->linktype = linktype;
    00720     p->stats_op = pcap_stats_dead;
    00721     p->close_op = pcap_close_dead;
    00722     return p;
    00723 }
    00724
    00725 void
    00726 pcap_close(pcap_t *p)
    00727 {
    00728     p->close_op(p);
    00729     if (p->dlt_list != NULL)
    00730         free(p->dlt_list);
    00731     pcap_freecode(&p->fcode);
    00732     free(p);
    00733 }
    00734
    00735 /*
    00736  * We make the version string static, and return a pointer to it, rather
    00737  * than exporting the version string directly.  On at least some UNIXes,
    00738  * if you import data from a shared library into an program, the data is
    00739  * bound into the program binary, so if the string in the version of the
    00740  * library with which the program was linked isn't the same as the
    00741  * string in the version of the library with which the program is being
    00742  * run, various undesirable things may happen (warnings, the string
    00743  * being the one from the version of the library with which the program
    00744  * was linked, or even weirder things, such as the string being the one
    00745  * from the library but being truncated).
    00746  */
    00747 #ifdef WIN32
    00748 /*
    00749  * XXX - it'd be nice if we could somehow generate the WinPcap and libpcap
    00750  * version numbers when building WinPcap.  (It'd be nice to do so for
    00751  * the packet.dll version number as well.)
    00752  */
    00753 static const char wpcap_version_string[] = "3.1 beta4";
    00754 static const char pcap_version_string_fmt[] =
    00755     "WinPcap version %s, based on libpcap version 0.8.3";
    00756 static const char pcap_version_string_packet_dll_fmt[] =
    00757     "WinPcap version %s (packet.dll version %s), based on libpcap version 0.8.3";
    00758 static char *pcap_version_string;
    00759
    00760 const char *
    00761 pcap_lib_version(void)
    00762 {
    00763     char *packet_version_string;
    00764     size_t pcap_version_string_len;
    00765
    00766     if (pcap_version_string == NULL) {
    00767         /*
    00768          * Generate the version string.
    00769          */
    00770         packet_version_string = PacketGetVersion();
    00771         if (strcmp(wpcap_version_string, packet_version_string) == 0) {
    00772             /*
    00773              * WinPcap version string and packet.dll version
    00774              * string are the same; just report the WinPcap
    00775              * version.
    00776              */
    00777             pcap_version_string_len =
    00778                 (sizeof pcap_version_string_fmt - 2) +
    00779                 strlen(wpcap_version_string);
    00780             pcap_version_string = malloc(pcap_version_string_len);
    00781             sprintf(pcap_version_string, pcap_version_string_fmt,
    00782                 wpcap_version_string);
    00783         } else {
    00784             /*
    00785              * WinPcap version string and packet.dll version
    00786              * string are different; that shouldn't be the
    00787              * case (the two libraries should come from the
    00788              * same version of WinPcap), so we report both
    00789              * versions.
    00790              */
    00791             pcap_version_string_len =
    00792                 (sizeof pcap_version_string_packet_dll_fmt - 4) +
    00793                 strlen(wpcap_version_string) +
    00794                 strlen(packet_version_string);
    00795             pcap_version_string = malloc(pcap_version_string_len);
    00796             sprintf(pcap_version_string,
    00797                 pcap_version_string_packet_dll_fmt,
    00798                 wpcap_version_string, packet_version_string);
    00799         }
    00800     }
    00801     return (pcap_version_string);
    00802 }
    00803 #else
    00804 #include "version.h"
    00805
    00806 const char *
    00807 pcap_lib_version(void)
    00808 {
    00809     return (pcap_version_string);
    00810 }
    00811 #endif

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