Bug Summary

File:src/usr.sbin/npppd/npppd/npppd_iface.c
Warning:line 233, column 15
Value stored to 'sock' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name npppd_iface.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/npppd/npppd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/npppd/npppd/../common -I /usr/src/usr.sbin/npppd/npppd -I /usr/src/usr.sbin/npppd/npppd/../pptp -I /usr/src/usr.sbin/npppd/npppd/../l2tp -I /usr/src/usr.sbin/npppd/npppd/../pppoe -D USE_NPPPD_PPTP -D USE_NPPPD_L2TP -D USE_NPPPD_PPPOE -D __COPYRIGHT(x)= -D __RCSID(x)= -D NPPPD_MAX_IFACE=8 -D NPPPD_MAX_POOL=8 -D USE_NPPPD_MPPE -D USE_NPPPD_PIPEX -D USE_NPPPD_RADIUS -D USE_SA_COOKIE -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/npppd/npppd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/npppd/npppd/npppd_iface.c
1/* $OpenBSD: npppd_iface.c,v 1.15 2021/02/01 07:44:58 mvs Exp $ */
2
3/*-
4 * Copyright (c) 2009 Internet Initiative Japan Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28/* $Id: npppd_iface.c,v 1.15 2021/02/01 07:44:58 mvs Exp $ */
29/**@file
30 * The interface of npppd and kernel.
31 * This is an implementation to use tun(4) or pppx(4).
32 */
33#include <sys/types.h>
34#include <sys/ioctl.h>
35#include <sys/socket.h>
36#include <sys/uio.h>
37#include <sys/sockio.h>
38#include <netinet/in.h>
39#include <netinet/ip.h>
40#include <arpa/inet.h>
41#include <net/if_dl.h>
42#include <net/if_tun.h>
43#include <net/if_types.h>
44#include <net/if.h>
45#include <net/pipex.h>
46
47#include <fcntl.h>
48
49#include <syslog.h>
50#include <stdio.h>
51#include <stdlib.h>
52#include <string.h>
53#include <unistd.h>
54#include <errno(*__errno()).h>
55#include <stdarg.h>
56
57#include <time.h>
58#include <event.h>
59#include "radish.h"
60
61#include "npppd_defs.h"
62#include "npppd_local.h"
63#include "npppd_subr.h"
64#include "debugutil.h"
65#include "npppd_iface.h"
66
67#ifdef USE_NPPPD_PIPEX1
68#include <net/if.h>
69#if defined(__NetBSD__)
70#include <net/if_ether.h>
71#else
72#include <netinet/if_ether.h>
73#endif
74#include <net/pipex.h>
75#endif /* USE_NPPPD_PIPEX */
76
77#ifdef NPPPD_IFACE_DEBUG
78#define NPPPD_IFACE_DBG(x) npppd_iface_log x
79#define NPPPD_IFACE_ASSERT(cond) \
80 if (!(cond)) { \
81 fprintf(stderr(&__sF[2]), \
82 "\nASSERT(" #cond ") failed on %s() at %s:%d.\n"\
83 , __func__, __FILE__"/usr/src/usr.sbin/npppd/npppd/npppd_iface.c", __LINE__83); \
84 abort(); \
85 }
86#else
87#define NPPPD_IFACE_ASSERT(cond)
88#define NPPPD_IFACE_DBG(x)
89#endif
90
91static void npppd_iface_network_input_ipv4(npppd_iface *, struct pppx_hdr *,
92 u_char *, int);
93static void npppd_iface_network_input(npppd_iface *, u_char *, int);
94static int npppd_iface_setup_ip(npppd_iface *);
95static void npppd_iface_io_event_handler (int, short, void *);
96static int npppd_iface_log (npppd_iface *, int, const char *, ...)
97 __printflike(3,4)__attribute__((__format__ (__printf__, 3, 4)));
98
99
100/** initialize npppd_iface */
101void
102npppd_iface_init(npppd *npppd, npppd_iface *_this, struct iface *iface)
103{
104
105 NPPPD_IFACE_ASSERT(_this != NULL);
106 memset(_this, 0, sizeof(npppd_iface));
107
108 _this->npppd = npppd;
109 strlcpy(_this->ifname, iface->name, sizeof(_this->ifname));
110 _this->using_pppx = iface->is_pppx;
111 _this->set_ip4addr = 1;
112 _this->ip4addr = iface->ip4addr;
113 _this->ipcpconf = iface->ipcpconf;
114 _this->devf = -1;
115 _this->initialized = 1;
116}
117
118static int
119npppd_iface_setup_ip(npppd_iface *_this)
120{
121 int sock, if_flags, changed;
122 struct in_addr gw, assigned;
123 struct sockaddr_in *sin0;
124 struct ifreq ifr;
125 struct ifaliasreq ifra;
126 npppd_ppp *ppp;
127
128 NPPPD_IFACE_ASSERT(_this != NULL);
129
130 sock = -1;
131 changed = 0;
132 memset(&ifr, 0, sizeof(ifr));
133
134 /* get address which was assigned to interface */
135 assigned.s_addr = INADDR_NONE((u_int32_t)(0xffffffff));
136 memset(&ifr, 0, sizeof(ifr));
137 memset(&ifra, 0, sizeof(ifra));
138 strlcpy(ifr.ifr_name, _this->ifname, sizeof(ifr.ifr_name));
139 strlcpy(ifra.ifra_name, _this->ifname, sizeof(ifra.ifra_name));
140 sin0 = (struct sockaddr_in *)&ifr.ifr_addrifr_ifru.ifru_addr;
141
142 if (priv_get_if_addr(_this->ifname, &assigned) != 0) {
143 if (errno(*__errno()) != EADDRNOTAVAIL49) {
144 npppd_iface_log(_this, LOG_ERR3,
145 "get ip address failed: %m");
146 goto fail;
147 }
148 assigned.s_addr = 0;
149 }
150
151 if (assigned.s_addr != _this->ip4addr.s_addr)
152 changed = 1;
153
154 if (priv_get_if_flags(_this->ifname, &if_flags) != 0) {
155 npppd_iface_log(_this, LOG_ERR3,
156 "ioctl(,SIOCGIFFLAGS) failed: %m");
157 goto fail;
158 }
159 if_flags = ifr.ifr_flagsifr_ifru.ifru_flags;
160 if (_this->set_ip4addr != 0 && changed) {
161 do {
162 struct in_addr dummy;
163 if (priv_delete_if_addr(_this->ifname) != 0) {
164 if (errno(*__errno()) == EADDRNOTAVAIL49)
165 break;
166 npppd_iface_log(_this, LOG_ERR3,
167 "delete ipaddress %s failed: %m",
168 _this->ifname);
169 goto fail;
170 }
171 if (priv_get_if_addr(_this->ifname, &dummy) != 0) {
172 if (errno(*__errno()) == EADDRNOTAVAIL49)
173 break;
174 npppd_iface_log(_this, LOG_ERR3,
175 "cannot get ipaddress %s failed: %m",
176 _this->ifname);
177 goto fail;
178 }
179 } while (1);
180
181 /* ifconfig tun1 down */
182 if (priv_set_if_flags(_this->ifname,
183 if_flags & ~(IFF_UP0x1 | IFF_BROADCAST0x2)) != 0) {
184 npppd_iface_log(_this, LOG_ERR3,
185 "disabling %s failed: %m", _this->ifname);
186 goto fail;
187 }
188 if (priv_set_if_addr(_this->ifname, &_this->ip4addr) != 0 &&
189 errno(*__errno()) != EEXIST17) {
190 npppd_iface_log(_this, LOG_ERR3,
191 "Cannot assign tun device ip address: %m");
192 goto fail;
193 }
194 /* erase old route */
195 if (assigned.s_addr != 0) {
196 gw.s_addr = htonl(INADDR_LOOPBACK)(__uint32_t)(__builtin_constant_p(((u_int32_t)(0x7f000001))) ?
(__uint32_t)(((__uint32_t)(((u_int32_t)(0x7f000001))) & 0xff
) << 24 | ((__uint32_t)(((u_int32_t)(0x7f000001))) &
0xff00) << 8 | ((__uint32_t)(((u_int32_t)(0x7f000001))
) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t)(0x7f000001
))) & 0xff000000) >> 24) : __swap32md(((u_int32_t)(
0x7f000001))))
;
197 in_host_route_delete(&assigned, &gw);
198 }
199
200 assigned.s_addr = _this->ip4addr.s_addr;
201
202 }
203 _this->ip4addr.s_addr = assigned.s_addr;
204 if (npppd_iface_ip_is_ready(_this)((_this)->initialized != 0 && (_this)->ip4addr.
s_addr != ((u_int32_t)(0x00000000)))
) {
205 if (changed) {
206 /*
207 * If there is a PPP session which was assigned
208 * interface IP address, disconnect it.
209 */
210 ppp = npppd_get_ppp_by_ip(_this->npppd, _this->ip4addr);
211 if (ppp != NULL((void *)0)) {
212 npppd_iface_log(_this, LOG_ERR3,
213 "Assigning %s, but ppp=%d is using "
214 "the address. Requested the ppp to stop",
215 inet_ntoa(_this->ip4addr), ppp->id);
216 ppp_stop(ppp, "Administrative reason");
217 }
218 }
219 /* ifconfig tun1 up */
220 if (priv_set_if_flags(_this->ifname,
221 if_flags | IFF_UP0x1 | IFF_MULTICAST0x8000) != 0) {
222 npppd_iface_log(_this, LOG_ERR3,
223 "enabling %s failed: %m", _this->ifname);
224 goto fail;
225 }
226 /*
227 * Add routing entry to communicate from host itself to
228 * _this->ip4addr.
229 */
230 gw.s_addr = htonl(INADDR_LOOPBACK)(__uint32_t)(__builtin_constant_p(((u_int32_t)(0x7f000001))) ?
(__uint32_t)(((__uint32_t)(((u_int32_t)(0x7f000001))) & 0xff
) << 24 | ((__uint32_t)(((u_int32_t)(0x7f000001))) &
0xff00) << 8 | ((__uint32_t)(((u_int32_t)(0x7f000001))
) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t)(0x7f000001
))) & 0xff000000) >> 24) : __swap32md(((u_int32_t)(
0x7f000001))))
;
231 in_host_route_add(&_this->ip4addr, &gw, LOOPBACK_IFNAME"lo0", 0);
232 }
233 close(sock); sock = -1;
Value stored to 'sock' is never read
234
235 return 0;
236fail:
237 if (sock >= 0)
238 close(sock);
239
240 return 1;
241}
242
243/** set tunnel end address */
244int
245npppd_iface_reinit(npppd_iface *_this, struct iface *iface)
246{
247 int rval;
248 struct in_addr backup;
249 char buf0[128], buf1[128];
250
251 _this->ipcpconf = iface->ipcpconf;
252 backup = _this->ip4addr;
253 _this->ip4addr = iface->ip4addr;
254
255 if (_this->using_pppx)
256 return 0;
257 if ((rval = npppd_iface_setup_ip(_this)) != 0)
258 return rval;
259
260 if (backup.s_addr != _this->ip4addr.s_addr) {
261 npppd_iface_log(_this, LOG_INFO6, "Reinited ip4addr %s=>%s",
262 (backup.s_addr != INADDR_ANY((u_int32_t)(0x00000000)))
263 ? inet_ntop(AF_INET2, &backup, buf0, sizeof(buf0))
264 : "(not assigned)",
265 (_this->ip4addr.s_addr != INADDR_ANY((u_int32_t)(0x00000000)))
266 ? inet_ntop(AF_INET2, &_this->ip4addr, buf1,
267 sizeof(buf1))
268 : "(not assigned)");
269 }
270
271 return 0;
272}
273
274/** start npppd_iface */
275int
276npppd_iface_start(npppd_iface *_this)
277{
278 char buf[PATH_MAX1024];
279
280 NPPPD_IFACE_ASSERT(_this != NULL);
281
282 /* open device file */
283 snprintf(buf, sizeof(buf), "/dev/%s", _this->ifname);
284 if ((_this->devf = priv_open(buf, O_RDWR0x0002 | O_NONBLOCK0x0004)) < 0) {
285 npppd_iface_log(_this, LOG_ERR3, "open(%s) failed: %m", buf);
286 goto fail;
287 }
288
289 event_set(&_this->ev, _this->devf, EV_READ0x02 | EV_PERSIST0x10,
290 npppd_iface_io_event_handler, _this);
291 event_add(&_this->ev, NULL((void *)0));
292
293 if (_this->using_pppx == 0) {
294 if (npppd_iface_setup_ip(_this) != 0)
295 goto fail;
296 }
297
298#ifndef USE_NPPPD_PIPEX1
299 if (_this->using_pppx) {
300 npppd_iface_log(_this, LOG_ERR3,
301 "pipex is required when using pppx interface");
302 goto fail;
303 }
304#endif /* USE_NPPPD_PIPEX */
305
306 if (_this->using_pppx) {
307 npppd_iface_log(_this, LOG_INFO6, "Started pppx");
308 } else {
309 npppd_iface_log(_this, LOG_INFO6, "Started ip4addr=%s",
310 (npppd_iface_ip_is_ready(_this)((_this)->initialized != 0 && (_this)->ip4addr.
s_addr != ((u_int32_t)(0x00000000)))
)?
311 inet_ntop(AF_INET2, &_this->ip4addr, buf,
312 sizeof(buf)) : "(not assigned)");
313 }
314 _this->started = 1;
315
316 return 0;
317fail:
318 if (_this->devf >= 0) {
319 event_del(&_this->ev);
320 close(_this->devf);
321 }
322 _this->devf = -1;
323
324 return -1;
325}
326
327/** stop to use npppd_iface */
328void
329npppd_iface_stop(npppd_iface *_this)
330{
331 struct in_addr gw;
332
333 NPPPD_IFACE_ASSERT(_this != NULL);
334 if (_this->using_pppx == 0) {
335 priv_delete_if_addr(_this->ifname);
336 gw.s_addr = htonl(INADDR_LOOPBACK)(__uint32_t)(__builtin_constant_p(((u_int32_t)(0x7f000001))) ?
(__uint32_t)(((__uint32_t)(((u_int32_t)(0x7f000001))) & 0xff
) << 24 | ((__uint32_t)(((u_int32_t)(0x7f000001))) &
0xff00) << 8 | ((__uint32_t)(((u_int32_t)(0x7f000001))
) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t)(0x7f000001
))) & 0xff000000) >> 24) : __swap32md(((u_int32_t)(
0x7f000001))))
;
337 in_host_route_delete(&_this->ip4addr, &gw);
338 }
339 if (_this->devf >= 0) {
340 event_del(&_this->ev);
341 close(_this->devf);
342 npppd_iface_log(_this, LOG_INFO6, "Stopped");
343 }
344 _this->devf = -1;
345 _this->started = 0;
346 event_del(&_this->ev);
347}
348
349/** finalize npppd_iface */
350void
351npppd_iface_fini(npppd_iface *_this)
352{
353 NPPPD_IFACE_ASSERT(_this != NULL);
354 _this->initialized = 0;
355}
356
357
358/***********************************************************************
359 * I/O related functions
360 ***********************************************************************/
361/** I/O event handler */
362static void
363npppd_iface_io_event_handler(int fd, short evtype, void *data)
364{
365 int sz;
366 u_char buffer[8192];
367 npppd_iface *_this;
368
369 NPPPD_IFACE_ASSERT((evtype & EV_READ) != 0);
370
371 _this = data;
372 NPPPD_IFACE_ASSERT(_this->devf >= 0);
373 do {
374 sz = read(_this->devf, buffer, sizeof(buffer));
375 if (sz <= 0) {
376 if (sz == 0)
377 npppd_iface_log(_this, LOG_ERR3,
378 "file is closed");
379 else if (errno(*__errno()) == EAGAIN35)
380 break;
381 else
382 npppd_iface_log(_this, LOG_ERR3,
383 "read failed: %m");
384 npppd_iface_stop(_this);
385 return;
386 }
387 npppd_iface_network_input(_this, buffer, sz);
388
389 } while (1 /* CONSTCOND */);
390
391 return;
392}
393
394/** structure of argument of npppd_iface_network_input_delegate */
395struct npppd_iface_network_input_arg{
396 npppd_iface *_this;
397 u_char *pktp;
398 int lpktp;
399};
400
401/** callback function which works for each PPP session */
402static int
403npppd_iface_network_input_delegate(struct radish *radish, void *args0)
404{
405 npppd_ppp *ppp;
406 struct sockaddr_npppd *snp;
407 struct npppd_iface_network_input_arg *args;
408
409 snp = radish->rd_rtent;
410
411 if (snp->snp_type == SNP_PPP3) {
412 args = args0;
413 ppp = snp->snp_data_ptr;
414 if (ppp_iface(ppp)(&(ppp)->pppd->iface[(ppp)->ifidx]) != args->_this)
415 return 0;
416#ifdef USE_NPPPD_MPPE1
417 if (MPPE_SEND_READY(ppp)((ppp)->mppe_started != 0 && (ppp)->mppe.send.keybits
> 0)
) {
418 /* output via MPPE if MPPE started */
419 mppe_pkt_output(&ppp->mppe, PPP_PROTO_IP0x0021, args->pktp,
420 args->lpktp);
421 } else if (MPPE_IS_REQUIRED(ppp)(((ppp)->mppe.enabled != 0) && ((ppp)->mppe.required
!= 0))
) {
422 /* in case MPPE not started but MPPE is mandatory, */
423 /* it is not necessary to log because of multicast. */
424 return 0;
425 }
426#endif
427 ppp_output(ppp, PPP_PROTO_IP0x0021, 0, 0, args->pktp, args->lpktp);
428 }
429
430 return 0;
431}
432
433static void
434npppd_iface_network_input_ipv4(npppd_iface *_this, struct pppx_hdr *pppx,
435 u_char *pktp, int lpktp)
436{
437 struct ip *iphdr;
438 npppd *_npppd;
439 npppd_ppp *ppp;
440 struct npppd_iface_network_input_arg input_arg;
441
442 NPPPD_IFACE_ASSERT(_this != NULL);
443 NPPPD_IFACE_ASSERT(pktp != NULL);
444
445 iphdr = (struct ip *)pktp;
446 _npppd = _this->npppd;
447
448 if (lpktp < sizeof(iphdr)) {
449 npppd_iface_log(_this, LOG_ERR3, "Received short packet.");
450 return;
451 }
452 if (_this->using_pppx)
453 ppp = npppd_get_ppp_by_id(_npppd, pppx->pppx_id);
454 else {
455 if (IN_MULTICAST(ntohl(iphdr->ip_dst.s_addr))(((u_int32_t)((__uint32_t)(__builtin_constant_p(iphdr->ip_dst
.s_addr) ? (__uint32_t)(((__uint32_t)(iphdr->ip_dst.s_addr
) & 0xff) << 24 | ((__uint32_t)(iphdr->ip_dst.s_addr
) & 0xff00) << 8 | ((__uint32_t)(iphdr->ip_dst.s_addr
) & 0xff0000) >> 8 | ((__uint32_t)(iphdr->ip_dst
.s_addr) & 0xff000000) >> 24) : __swap32md(iphdr->
ip_dst.s_addr))) & ((u_int32_t)(0xf0000000))) == ((u_int32_t
)(0xe0000000)))
) {
456 NPPPD_IFACE_ASSERT(
457 ((npppd *)(_this->npppd))->rd != NULL);
458 input_arg._this = _this;
459 input_arg.pktp = pktp;
460 input_arg.lpktp = lpktp;
461 /* delegate */
462 rd_walktree(((npppd *)(_this->npppd))->rd,
463 npppd_iface_network_input_delegate, &input_arg);
464 return;
465 }
466 ppp = npppd_get_ppp_by_ip(_npppd, iphdr->ip_dst);
467 }
468
469 if (ppp == NULL((void *)0)) {
470#ifdef NPPPD_DEBUG
471 log_printf(LOG_INFO6, "%s received a packet to unknown "
472 "%s.", _this->ifname, inet_ntoa(iphdr->ip_dst));
473#endif
474 return;
475 }
476#ifndef NO_ADJUST_MSS
477 if (ppp->adjust_mss) {
478 adjust_tcp_mss(pktp, lpktp, MRU_IPMTU(ppp->peer_mru)(ppp->peer_mru));
479 }
480#endif
481 if (ppp->timeout_sec > 0 && !ip_is_idle_packet(iphdr, lpktp))
482 ppp_reset_idle_timeout(ppp);
483
484#ifdef USE_NPPPD_MPPE1
485 if (MPPE_SEND_READY(ppp)((ppp)->mppe_started != 0 && (ppp)->mppe.send.keybits
> 0)
) {
486 /* output via MPPE if MPPE started */
487 mppe_pkt_output(&ppp->mppe, PPP_PROTO_IP0x0021, pktp, lpktp);
488 return;
489 } else if (MPPE_IS_REQUIRED(ppp)(((ppp)->mppe.enabled != 0) && ((ppp)->mppe.required
!= 0))
) {
490 /* in case MPPE not started but MPPE is mandatory */
491 ppp_log(ppp, LOG_WARNING4, "A packet received from network, "
492 "but MPPE is not started.");
493 return;
494 }
495#endif
496 ppp_output(ppp, PPP_PROTO_IP0x0021, 0, 0, pktp, lpktp);
497}
498
499/**
500 * This function is called when an input packet come from network(tun).
501 * Currently, it assumes that it input IPv4 packet.
502 */
503static void
504npppd_iface_network_input(npppd_iface *_this, u_char *pktp, int lpktp)
505{
506 uint32_t af;
507 struct pppx_hdr *pppx = NULL((void *)0);
508
509 if (_this->using_pppx) {
510 if (lpktp < sizeof(struct pppx_hdr)) {
511 npppd_iface_log(_this, LOG_ERR3,
512 "Received short packet.");
513 return;
514 }
515 pppx = (struct pppx_hdr *)pktp;
516 pktp += sizeof(struct pppx_hdr);
517 lpktp -= sizeof(struct pppx_hdr);
518 }
519
520 if (lpktp < sizeof(uint32_t)) {
521 npppd_iface_log(_this, LOG_ERR3, "Received short packet.");
522 return;
523 }
524 GETLONG(af, pktp){ (af) = *(pktp)++ << 8; (af) |= *(pktp)++; (af) <<=
8; (af) |= *(pktp)++; (af) <<= 8; (af) |= *(pktp)++; }
;
525 lpktp -= sizeof(uint32_t);
526
527 switch (af) {
528 case AF_INET2:
529 npppd_iface_network_input_ipv4(_this, pppx, pktp, lpktp);
530 break;
531
532 default:
533 NPPPD_IFACE_ASSERT(0);
534 break;
535
536 }
537}
538
539/** write to tunnel device */
540void
541npppd_iface_write(npppd_iface *_this, npppd_ppp *ppp, int proto, u_char *pktp,
542 int lpktp)
543{
544 int niov = 0, tlen;
545 uint32_t th;
546 struct iovec iov[3];
547 struct pppx_hdr pppx;
548 NPPPD_IFACE_ASSERT(_this != NULL);
549 NPPPD_IFACE_ASSERT(_this->devf >= 0);
550
551 tlen = 0;
552 th = htonl(proto)(__uint32_t)(__builtin_constant_p(proto) ? (__uint32_t)(((__uint32_t
)(proto) & 0xff) << 24 | ((__uint32_t)(proto) &
0xff00) << 8 | ((__uint32_t)(proto) & 0xff0000) >>
8 | ((__uint32_t)(proto) & 0xff000000) >> 24) : __swap32md
(proto))
;
553 if (_this->using_pppx) {
554 pppx.pppx_proto = npppd_pipex_proto(ppp->tunnel_type)(((ppp->tunnel_type) == 1)? 1 : ((ppp->tunnel_type) == 2
)? 2 : ((ppp->tunnel_type) == 3)? 3 : -1)
;
555 pppx.pppx_id = ppp->tunnel_session_id;
556 iov[niov].iov_base = &pppx;
557 iov[niov++].iov_len = sizeof(pppx);
558 tlen += sizeof(pppx);
559 }
560 iov[niov].iov_base = &th;
561 iov[niov++].iov_len = sizeof(th);
562 tlen += sizeof(th);
563 iov[niov].iov_base = pktp;
564 iov[niov++].iov_len = lpktp;
565 tlen += lpktp;
566
567 if (writev(_this->devf, iov, niov) != tlen)
568 npppd_iface_log(_this, LOG_ERR3, "write failed: %m");
569}
570
571/***********************************************************************
572 * misc functions
573 ***********************************************************************/
574/** Log it which starts the label based on this instance. */
575static int
576npppd_iface_log(npppd_iface *_this, int prio, const char *fmt, ...)
577{
578 int status;
579 char logbuf[BUFSIZ1024];
580 va_list ap;
581
582 NPPPD_IFACE_ASSERT(_this != NULL);
583
584 va_start(ap, fmt)__builtin_va_start(ap, fmt);
585 snprintf(logbuf, sizeof(logbuf), "%s %s", _this->ifname, fmt);
586 status = vlog_printf(prio, logbuf, ap);
587 va_end(ap)__builtin_va_end(ap);
588
589 return status;
590}