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.