Bug Summary

File:libs/libnatpmp/natpmp.c
Location:line 214, column 31
Description:The left operand of '!=' is a garbage value

Annotated Source Code

1/* $Id: natpmp.c,v 1.8 2008/07/02 22:33:06 nanard Exp $ */
2/* libnatpmp
3 * Copyright (c) 2007-2008, Thomas BERNARD <miniupnp@free.fr>
4 * http://miniupnp.free.fr/libnatpmp.html
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
17#ifdef __linux__1
18#ifndef _DEFAULT_SOURCE1
19#define _DEFAULT_SOURCE1
20#endif
21#define _BSD_SOURCE1 1
22#endif
23#include <string.h>
24#include <time.h>
25#ifndef _MSC_VER
26#include <sys/time.h>
27#endif
28#ifdef WIN32
29#include <winsock2.h>
30#include <Ws2tcpip.h>
31#include <io.h>
32#define EWOULDBLOCK11 WSAEWOULDBLOCK
33#define ECONNREFUSED111 WSAECONNREFUSED
34
35static int gettimeofday(struct timeval* p, void* tz /* IGNORED */) {
36 union {
37 long long ns100; /*time since 1 Jan 1601 in 100ns units */
38 FILETIME ft;
39 } _now;
40
41 GetSystemTimeAsFileTime( &(_now.ft) );
42 p->tv_usec=(long)((_now.ns100 / 10LL) % 1000000LL );
43 p->tv_sec= (long)((_now.ns100-(116444736000000000LL))/10000000LL);
44 return 0;
45}
46
47#else
48#include <errno(*__errno_location ()).h>
49#include <unistd.h>
50#include <fcntl.h>
51#include <sys/types.h>
52#include <sys/socket.h>
53#define closesocketclose close
54#endif
55#include "natpmp.h"
56#include "getgateway.h"
57
58int initnatpmp(natpmp_t * p)
59{
60#ifdef WIN32
61 u_long ioctlArg = 1;
62#else
63 int flags;
64#endif
65 struct sockaddr_in addr;
66 if(!p)
67 return NATPMP_ERR_INVALIDARGS(-1);
68 memset(p, 0, sizeof(natpmp_t));
69 p->s = socket(PF_INET2, SOCK_DGRAMSOCK_DGRAM, 0);
70 if(p->s < 0)
71 return NATPMP_ERR_SOCKETERROR(-2);
72#ifdef WIN32
73 if(ioctlsocket(p->s, FIONBIO, &ioctlArg) == SOCKET_ERROR)
74 return NATPMP_ERR_FCNTLERROR(-11);
75#else
76 if((flags = fcntl(p->s, F_GETFL3, 0)) < 0)
77 return NATPMP_ERR_FCNTLERROR(-11);
78 if(fcntl(p->s, F_SETFL4, flags | O_NONBLOCK04000) < 0)
79 return NATPMP_ERR_FCNTLERROR(-11);
80#endif
81
82 if(getdefaultgateway(&(p->gateway)) < 0)
83 return NATPMP_ERR_CANNOTGETGATEWAY(-3);
84
85 memset(&addr, 0, sizeof(addr));
86 addr.sin_family = AF_INET2;
87 addr.sin_port = htons(NATPMP_PORT)(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) ((5351)); if (__builtin_constant_p (__x)) __v = ((unsigned
short int) ((((__x) >> 8) & 0xff) | (((__x) & 0xff
) << 8))); else __asm__ ("rorw $8, %w0" : "=r" (__v) : "0"
(__x) : "cc"); __v; }))
;
88 addr.sin_addr.s_addr = p->gateway;
89 if(connect(p->s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
90 return NATPMP_ERR_CONNECTERR(-8);
91 return 0;
92}
93
94int closenatpmp(natpmp_t * p)
95{
96 if(!p)
97 return NATPMP_ERR_INVALIDARGS(-1);
98 if(closesocketclose(p->s) < 0)
99 return NATPMP_ERR_CLOSEERR(-4);
100 return 0;
101}
102
103int sendpendingrequest(natpmp_t * p)
104{
105 int r;
106/* struct sockaddr_in addr;*/
107 if(!p)
108 return NATPMP_ERR_INVALIDARGS(-1);
109/* memset(&addr, 0, sizeof(addr));
110 addr.sin_family = AF_INET;
111 addr.sin_port = htons(NATPMP_PORT);
112 addr.sin_addr.s_addr = p->gateway;
113 r = (int)sendto(p->s, p->pending_request, p->pending_request_len, 0,
114 (struct sockaddr *)&addr, sizeof(addr));*/
115 r = (int)send(p->s, p->pending_request, p->pending_request_len, 0);
116 return (r<0) ? NATPMP_ERR_SENDERR(-10) : r;
117}
118
119int sendnatpmprequest(natpmp_t * p)
120{
121 int n;
122 if(!p)
123 return NATPMP_ERR_INVALIDARGS(-1);
124 /* TODO : check if no request is allready pending */
125 p->has_pending_request = 1;
126 p->try_number = 1;
127 n = sendpendingrequest(p);
128 gettimeofday(&p->retry_time, NULL((void*)0)); // check errors !
129 p->retry_time.tv_usec += 250000; /* add 250ms */
130 if(p->retry_time.tv_usec >= 1000000) {
131 p->retry_time.tv_usec -= 1000000;
132 p->retry_time.tv_sec++;
133 }
134 return n;
135}
136
137int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout)
138{
139 struct timeval now;
140 if(!p || !timeout)
141 return NATPMP_ERR_INVALIDARGS(-1);
142 if(!p->has_pending_request)
143 return NATPMP_ERR_NOPENDINGREQ(-6);
144 if(gettimeofday(&now, NULL((void*)0)) < 0)
145 return NATPMP_ERR_GETTIMEOFDAYERR(-12);
146 timeout->tv_sec = p->retry_time.tv_sec - now.tv_sec;
147 timeout->tv_usec = p->retry_time.tv_usec - now.tv_usec;
148 if(timeout->tv_usec < 0) {
149 timeout->tv_usec += 1000000;
150 timeout->tv_sec--;
151 }
152 return 0;
153}
154
155int sendpublicaddressrequest(natpmp_t * p)
156{
157 if(!p)
158 return NATPMP_ERR_INVALIDARGS(-1);
159 //static const unsigned char request[] = { 0, 0 };
160 p->pending_request[0] = 0;
161 p->pending_request[1] = 0;
162 p->pending_request_len = 2;
163 // TODO: return 0 instead of sizeof(request) ??
164 return sendnatpmprequest(p);
165}
166
167int sendnewportmappingrequest(natpmp_t * p, int protocol,
168 uint16_t privateport, uint16_t publicport,
169 uint32_t lifetime)
170{
171 uint16_t *n;
172 uint32_t *m;
173
174 if(!p || (protocol!=NATPMP_PROTOCOL_TCP(2) && protocol!=NATPMP_PROTOCOL_UDP(1)))
175 return NATPMP_ERR_INVALIDARGS(-1);
176 p->pending_request[0] = 0;
177 p->pending_request[1] = (char)protocol;
178 p->pending_request[2] = 0;
179 p->pending_request[3] = 0;
180 n = (uint16_t *)(p->pending_request + 4); *n = htons(privateport)(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (privateport); if (__builtin_constant_p (__x)) __v = ((
unsigned short int) ((((__x) >> 8) & 0xff) | (((__x
) & 0xff) << 8))); else __asm__ ("rorw $8, %w0" : "=r"
(__v) : "0" (__x) : "cc"); __v; }))
;
181 n = (uint16_t *)(p->pending_request + 6); *n = htons(publicport)(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (publicport); if (__builtin_constant_p (__x)) __v = ((unsigned
short int) ((((__x) >> 8) & 0xff) | (((__x) & 0xff
) << 8))); else __asm__ ("rorw $8, %w0" : "=r" (__v) : "0"
(__x) : "cc"); __v; }))
;
182 m = (uint32_t *)(p->pending_request + 8); *m = htonl(lifetime)(__extension__ ({ unsigned int __v, __x = (lifetime); if (__builtin_constant_p
(__x)) __v = ((((__x) & 0xff000000) >> 24) | (((__x
) & 0x00ff0000) >> 8) | (((__x) & 0x0000ff00) <<
8) | (((__x) & 0x000000ff) << 24)); else __asm__ (
"bswap %0" : "=r" (__v) : "0" (__x)); __v; }))
;
183
184 //*((uint16_t *)(p->pending_request + 4)) = htons(privateport);
185 //*((uint16_t *)(p->pending_request + 6)) = htons(publicport);
186 //*((uint32_t *)(p->pending_request + 8)) = htonl(lifetime);
187 p->pending_request_len = 12;
188 return sendnatpmprequest(p);
189}
190
191int readnatpmpresponse(natpmp_t * p, natpmpresp_t * response)
192{
193 unsigned char buf[16];
194 struct sockaddr_in addr;
195 socklen_t addrlen = sizeof(addr);
196 int n;
197 if(!p)
6
Taking false branch
198 return NATPMP_ERR_INVALIDARGS(-1);
199 n = recvfrom(p->s, (char *)buf, sizeof(buf), 0,
200 (struct sockaddr *)&addr, &addrlen);
201 if(n<0)
7
Assuming 'n' is >= 0
8
Taking false branch
202 switch(errno(*__errno_location ())) {
203 /*case EAGAIN:*/
204 case EWOULDBLOCK11:
205 n = NATPMP_TRYAGAIN(-100);
206 break;
207 case ECONNREFUSED111:
208 n = NATPMP_ERR_NOGATEWAYSUPPORT(-7);
209 break;
210 default:
211 n = NATPMP_ERR_RECVFROM(-5);
212 }
213 /* check that addr is correct (= gateway) */
214 else if(addr.sin_addr.s_addr != p->gateway)
9
The left operand of '!=' is a garbage value
215 n = NATPMP_ERR_WRONGPACKETSOURCE(-9);
216 else {
217 response->resultcode = ntohs(*((uint16_t *)(buf + 2)))(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (*((uint16_t *)(buf + 2))); if (__builtin_constant_p (__x
)) __v = ((unsigned short int) ((((__x) >> 8) & 0xff
) | (((__x) & 0xff) << 8))); else __asm__ ("rorw $8, %w0"
: "=r" (__v) : "0" (__x) : "cc"); __v; }))
;
218 response->epoch = ntohl(*((uint32_t *)(buf + 4)))(__extension__ ({ unsigned int __v, __x = (*((uint32_t *)(buf
+ 4))); if (__builtin_constant_p (__x)) __v = ((((__x) &
0xff000000) >> 24) | (((__x) & 0x00ff0000) >>
8) | (((__x) & 0x0000ff00) << 8) | (((__x) & 0x000000ff
) << 24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (
__x)); __v; }))
;
219 if(buf[0] != 0)
220 n = NATPMP_ERR_UNSUPPORTEDVERSION(-14);
221 else if(buf[1] < 128 || buf[1] > 130)
222 n = NATPMP_ERR_UNSUPPORTEDOPCODE(-15);
223 else if(response->resultcode != 0) {
224 switch(response->resultcode) {
225 case 1:
226 n = NATPMP_ERR_UNSUPPORTEDVERSION(-14);
227 break;
228 case 2:
229 n = NATPMP_ERR_NOTAUTHORIZED(-51);
230 break;
231 case 3:
232 n = NATPMP_ERR_NETWORKFAILURE(-52);
233 break;
234 case 4:
235 n = NATPMP_ERR_OUTOFRESOURCES(-53);
236 break;
237 case 5:
238 n = NATPMP_ERR_UNSUPPORTEDOPCODE(-15);
239 break;
240 default:
241 n = NATPMP_ERR_UNDEFINEDERROR(-49);
242 }
243 } else {
244 response->type = buf[1] & 0x7f;
245 if(buf[1] == 128)
246 //response->publicaddress.addr = *((uint32_t *)(buf + 8));
247 response->pnu.publicaddress.addr.s_addr = *((uint32_t *)(buf + 8));
248 else {
249 response->pnu.newportmapping.privateport = ntohs(*((uint16_t *)(buf + 8)))(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (*((uint16_t *)(buf + 8))); if (__builtin_constant_p (__x
)) __v = ((unsigned short int) ((((__x) >> 8) & 0xff
) | (((__x) & 0xff) << 8))); else __asm__ ("rorw $8, %w0"
: "=r" (__v) : "0" (__x) : "cc"); __v; }))
;
250 response->pnu.newportmapping.mappedpublicport = ntohs(*((uint16_t *)(buf + 10)))(__extension__ ({ unsigned short int __v, __x = (unsigned short
int) (*((uint16_t *)(buf + 10))); if (__builtin_constant_p (
__x)) __v = ((unsigned short int) ((((__x) >> 8) & 0xff
) | (((__x) & 0xff) << 8))); else __asm__ ("rorw $8, %w0"
: "=r" (__v) : "0" (__x) : "cc"); __v; }))
;
251 response->pnu.newportmapping.lifetime = ntohl(*((uint32_t *)(buf + 12)))(__extension__ ({ unsigned int __v, __x = (*((uint32_t *)(buf
+ 12))); if (__builtin_constant_p (__x)) __v = ((((__x) &
0xff000000) >> 24) | (((__x) & 0x00ff0000) >>
8) | (((__x) & 0x0000ff00) << 8) | (((__x) & 0x000000ff
) << 24)); else __asm__ ("bswap %0" : "=r" (__v) : "0" (
__x)); __v; }))
;
252 }
253 n = 0;
254 }
255 }
256 return n;
257}
258
259int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response)
260{
261 int n;
262 if(!p || !response)
1
Assuming 'p' is non-null
2
Assuming 'response' is non-null
3
Taking false branch
263 return NATPMP_ERR_INVALIDARGS(-1);
264 if(!p->has_pending_request)
4
Taking false branch
265 return NATPMP_ERR_NOPENDINGREQ(-6);
266 n = readnatpmpresponse(p, response);
5
Calling 'readnatpmpresponse'
267 if(n<0) {
268 if(n==NATPMP_TRYAGAIN(-100)) {
269 struct timeval now;
270 gettimeofday(&now, NULL((void*)0)); // check errors !
271 if(timercmp(&now, &p->retry_time, >=)(((&now)->tv_sec == (&p->retry_time)->tv_sec
) ? ((&now)->tv_usec >= (&p->retry_time)->
tv_usec) : ((&now)->tv_sec >= (&p->retry_time
)->tv_sec))
) {
272 int delay, r;
273 if(p->try_number >= 9) {
274 return NATPMP_ERR_NOGATEWAYSUPPORT(-7);
275 }
276 /*printf("retry! %d\n", p->try_number);*/
277 delay = 250 * (1<<p->try_number); // ms
278 /*for(i=0; i<p->try_number; i++)
279 delay += delay;*/
280 p->retry_time.tv_sec += (delay / 1000);
281 p->retry_time.tv_usec += (delay % 1000) * 1000;
282 if(p->retry_time.tv_usec >= 1000000) {
283 p->retry_time.tv_usec -= 1000000;
284 p->retry_time.tv_sec++;
285 }
286 p->try_number++;
287 r = sendpendingrequest(p);
288 if(r<0)
289 return r;
290 }
291 }
292 } else {
293 p->has_pending_request = 0;
294 }
295 return n;
296}
297
298#ifdef ENABLE_STRNATPMPERR
299const char * strnatpmperr(int r)
300{
301 const char * s;
302 switch(r) {
303 case NATPMP_ERR_INVALIDARGS(-1):
304 s = "invalid arguments";
305 break;
306 case NATPMP_ERR_SOCKETERROR(-2):
307 s = "socket() failed";
308 break;
309 case NATPMP_ERR_CANNOTGETGATEWAY(-3):
310 s = "cannot get default gateway ip address";
311 break;
312 case NATPMP_ERR_CLOSEERR(-4):
313#ifdef WIN32
314 s = "closesocket() failed";
315#else
316 s = "close() failed";
317#endif
318 break;
319 case NATPMP_ERR_RECVFROM(-5):
320 s = "recvfrom() failed";
321 break;
322 case NATPMP_ERR_NOPENDINGREQ(-6):
323 s = "no pending request";
324 break;
325 case NATPMP_ERR_NOGATEWAYSUPPORT(-7):
326 s = "the gateway does not support nat-pmp";
327 break;
328 case NATPMP_ERR_CONNECTERR(-8):
329 s = "connect() failed";
330 break;
331 case NATPMP_ERR_WRONGPACKETSOURCE(-9):
332 s = "packet not received from the default gateway";
333 break;
334 case NATPMP_ERR_SENDERR(-10):
335 s = "send() failed";
336 break;
337 case NATPMP_ERR_FCNTLERROR(-11):
338 s = "fcntl() failed";
339 break;
340 case NATPMP_ERR_GETTIMEOFDAYERR(-12):
341 s = "gettimeofday() failed";
342 break;
343 case NATPMP_ERR_UNSUPPORTEDVERSION(-14):
344 s = "unsupported nat-pmp version error from server";
345 break;
346 case NATPMP_ERR_UNSUPPORTEDOPCODE(-15):
347 s = "unsupported nat-pmp opcode error from server";
348 break;
349 case NATPMP_ERR_UNDEFINEDERROR(-49):
350 s = "undefined nat-pmp server error";
351 break;
352 case NATPMP_ERR_NOTAUTHORIZED(-51):
353 s = "not authorized";
354 break;
355 case NATPMP_ERR_NETWORKFAILURE(-52):
356 s = "network failure";
357 break;
358 case NATPMP_ERR_OUTOFRESOURCES(-53):
359 s = "nat-pmp server out of resources";
360 break;
361 default:
362 s = "Unknown libnatpmp error";
363 }
364 return s;
365}
366#endif
367