Coverage Report

Created: 2021-11-03 07:11

/src/libpcap-1.9.1/fmtutils.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
3
 *  The Regents of the University of California.  All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
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.
20
 *
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
31
 * SUCH DAMAGE.
32
 */
33
34
/*
35
 * Utilities for message formatting used both by libpcap and rpcapd.
36
 */
37
38
#ifdef HAVE_CONFIG_H
39
#include <config.h>
40
#endif
41
42
#include "ftmacros.h"
43
44
#include <stddef.h>
45
#include <stdarg.h>
46
#include <stdio.h>
47
#include <string.h>
48
#include <errno.h>
49
50
#include <pcap/pcap.h>
51
52
#include "portability.h"
53
54
#include "fmtutils.h"
55
56
/*
57
 * Generate an error message based on a format, arguments, and an
58
 * errno, with a message for the errno after the formatted output.
59
 */
60
void
61
pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
62
    const char *fmt, ...)
63
7
{
64
7
  va_list ap;
65
7
  size_t msglen;
66
7
  char *p;
67
7
  size_t errbuflen_remaining;
68
69
7
  va_start(ap, fmt);
70
7
  pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
71
7
  va_end(ap);
72
7
  msglen = strlen(errbuf);
73
74
  /*
75
   * Do we have enough space to append ": "?
76
   * Including the terminating '\0', that's 3 bytes.
77
   */
78
7
  if (msglen + 3 > errbuflen) {
79
    /* No - just give them what we've produced. */
80
0
    return;
81
0
  }
82
7
  p = errbuf + msglen;
83
7
  errbuflen_remaining = errbuflen - msglen;
84
7
  *p++ = ':';
85
7
  *p++ = ' ';
86
7
  *p = '\0';
87
7
  msglen += 2;
88
7
  errbuflen_remaining -= 2;
89
90
  /*
91
   * Now append the string for the error code.
92
   */
93
#if defined(HAVE_STRERROR_S)
94
  /*
95
   * We have a Windows-style strerror_s().
96
   */
97
  errno_t err = strerror_s(p, errbuflen_remaining, errnum);
98
  if (err != 0) {
99
    /*
100
     * It doesn't appear to be documented anywhere obvious
101
     * what the error returns from strerror_s().
102
     */
103
    pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum);
104
  }
105
#elif defined(HAVE_GNU_STRERROR_R)
106
  /*
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
110
   * the buffer.
111
   *
112
   * It is, however, guaranteed to succeed.
113
   */
114
7
  char strerror_buf[PCAP_ERRBUF_SIZE];
115
7
  char *errstring = strerror_r(errnum, strerror_buf, PCAP_ERRBUF_SIZE);
116
7
  pcap_snprintf(p, errbuflen_remaining, "%s", errstring);
117
#elif defined(HAVE_POSIX_STRERROR_R)
118
  /*
119
   * We have a POSIX-style strerror_r(), which is guaranteed to fill
120
   * in the buffer, but is not guaranteed to succeed.
121
   */
122
  int err = strerror_r(errnum, p, errbuflen_remaining);
123
  if (err == EINVAL) {
124
    /*
125
     * UNIX 03 says this isn't guaranteed to produce a
126
     * fallback error message.
127
     */
128
    pcap_snprintf(p, errbuflen_remaining, "Unknown error: %d",
129
        errnum);
130
  } else if (err == ERANGE) {
131
    /*
132
     * UNIX 03 says this isn't guaranteed to produce a
133
     * fallback error message.
134
     */
135
    pcap_snprintf(p, errbuflen_remaining,
136
        "Message for error %d is too long", errnum);
137
  }
138
#else
139
  /*
140
   * We have neither strerror_s() nor strerror_r(), so we're
141
   * stuck with using pcap_strerror().
142
   */
143
  pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
144
#endif
145
7
}
146
147
#ifdef _WIN32
148
/*
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.
151
 */
152
void
153
pcap_fmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum,
154
    const char *fmt, ...)
155
{
156
  va_list ap;
157
  size_t msglen;
158
  char *p;
159
  size_t errbuflen_remaining;
160
  DWORD retval;
161
  char win32_errbuf[PCAP_ERRBUF_SIZE+1];
162
163
  va_start(ap, fmt);
164
  pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
165
  va_end(ap);
166
  msglen = strlen(errbuf);
167
168
  /*
169
   * Do we have enough space to append ": "?
170
   * Including the terminating '\0', that's 3 bytes.
171
   */
172
  if (msglen + 3 > errbuflen) {
173
    /* No - just give them what we've produced. */
174
    return;
175
  }
176
  p = errbuf + msglen;
177
  errbuflen_remaining = errbuflen - msglen;
178
  *p++ = ':';
179
  *p++ = ' ';
180
  *p = '\0';
181
  msglen += 2;
182
  errbuflen_remaining -= 2;
183
184
  /*
185
   * Now append the string for the error code.
186
   *
187
   * XXX - what language ID to use?
188
   *
189
   * For UN*Xes, pcap_strerror() may or may not return localized
190
   * strings.
191
   *
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.
199
   */
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);
203
  if (retval == 0) {
204
    /*
205
     * Failed.
206
     */
207
    pcap_snprintf(p, errbuflen_remaining,
208
        "Couldn't get error message for error (%lu)", errnum);
209
    return;
210
  }
211
212
  pcap_snprintf(p, errbuflen_remaining, "%s (%lu)", win32_errbuf, errnum);
213
}
214
#endif