2 * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the Computer Systems
16 * Engineering Group at Lawrence Berkeley Laboratory.
17 * 4. Neither the name of the University nor of the Laboratory may be used
18 * to endorse or promote products derived from this software without
19 * specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * Utilities for message formatting used both by libpcap and rpcapd.
50 #include <pcap/pcap.h>
52 #include "portability.h"
57 * Generate an error message based on a format, arguments, and an
58 * errno, with a message for the errno after the formatted output.
61 pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
67 size_t errbuflen_remaining;
70 pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
72 msglen = strlen(errbuf);
75 * Do we have enough space to append ": "?
76 * Including the terminating '\0', that's 3 bytes.
78 if (msglen + 3 > errbuflen) {
79 /* No - just give them what we've produced. */
83 errbuflen_remaining = errbuflen - msglen;
88 errbuflen_remaining -= 2;
91 * Now append the string for the error code.
93 #if defined(HAVE_STRERROR_S)
95 * We have a Windows-style strerror_s().
97 errno_t err = strerror_s(p, errbuflen_remaining, errnum);
100 * It doesn't appear to be documented anywhere obvious
101 * what the error returns from strerror_s().
103 pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum);
105 #elif defined(HAVE_GNU_STRERROR_R)
107 * We have a GNU-style strerror_r(), which is *not* guaranteed to
108 * do anything to the buffer handed to it, and which returns a
109 * pointer to the error string, which may or may not be in
112 * It is, however, guaranteed to succeed.
114 char strerror_buf[PCAP_ERRBUF_SIZE];
115 char *errstring = strerror_r(errnum, strerror_buf, PCAP_ERRBUF_SIZE);
116 pcap_snprintf(p, errbuflen_remaining, "%s", errstring);
117 #elif defined(HAVE_POSIX_STRERROR_R)
119 * We have a POSIX-style strerror_r(), which is guaranteed to fill
120 * in the buffer, but is not guaranteed to succeed.
122 int err = strerror_r(errnum, p, errbuflen_remaining);
125 * UNIX 03 says this isn't guaranteed to produce a
126 * fallback error message.
128 pcap_snprintf(p, errbuflen_remaining, "Unknown error: %d",
130 } else if (err == ERANGE) {
132 * UNIX 03 says this isn't guaranteed to produce a
133 * fallback error message.
135 pcap_snprintf(p, errbuflen_remaining,
136 "Message for error %d is too long", errnum);
140 * We have neither strerror_s() nor strerror_r(), so we're
141 * stuck with using pcap_strerror().
143 pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
149 * Generate an error message based on a format, arguments, and a
150 * Win32 error, with a message for the Win32 error after the formatted output.
153 pcap_fmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum,
154 const char *fmt, ...)
159 size_t errbuflen_remaining;
161 char win32_errbuf[PCAP_ERRBUF_SIZE+1];
164 pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
166 msglen = strlen(errbuf);
169 * Do we have enough space to append ": "?
170 * Including the terminating '\0', that's 3 bytes.
172 if (msglen + 3 > errbuflen) {
173 /* No - just give them what we've produced. */
177 errbuflen_remaining = errbuflen - msglen;
182 errbuflen_remaining -= 2;
185 * Now append the string for the error code.
187 * XXX - what language ID to use?
189 * For UN*Xes, pcap_strerror() may or may not return localized
192 * We currently don't have localized messages for libpcap, but
193 * we might want to do so. On the other hand, if most of these
194 * messages are going to be read by libpcap developers and
195 * perhaps by developers of libpcap-based applications, English
196 * might be a better choice, so the developer doesn't have to
197 * get the message translated if it's in a language they don't
198 * happen to understand.
200 retval = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_MAX_WIDTH_MASK,
201 NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
202 win32_errbuf, PCAP_ERRBUF_SIZE, NULL);
207 pcap_snprintf(p, errbuflen_remaining,
208 "Couldn't get error message for error (%lu)", errnum);
212 pcap_snprintf(p, errbuflen_remaining, "%s (%lu)", win32_errbuf, errnum);