Mercurial > flash_v2
annotate packages/net/ppp/current/src/sys-ecos.c @ 1777:c16341b1bac6 default tip
* Added execute permissions to files missed in conversion from CVS
| author | alexs |
|---|---|
| date | Mon, 12 Oct 2009 02:26:09 +0100 |
| parents | 5629b7c30ed2 |
| children |
| rev | line source |
|---|---|
| 1586 | 1 //========================================================================== |
| 2 // | |
| 3 // src/sys-ecos.c | |
| 4 // | |
| 5 //========================================================================== | |
| 6 //####ECOSGPLCOPYRIGHTBEGIN#### | |
| 7 // ------------------------------------------- | |
| 8 // This file is part of eCos, the Embedded Configurable Operating System. | |
| 9 // Portions created by Nick Garnett are | |
| 10 // Copyright (C) 2003, 2004 eCosCentric Ltd. | |
| 11 // | |
| 12 // eCos is free software; you can redistribute it and/or modify it under | |
| 13 // the terms of the GNU General Public License as published by the Free | |
| 14 // Software Foundation; either version 2 or (at your option) any later version. | |
| 15 // | |
| 16 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY | |
| 17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 18 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 19 // for more details. | |
| 20 // | |
| 21 // You should have received a copy of the GNU General Public License along | |
| 22 // with eCos; if not, write to the Free Software Foundation, Inc., | |
| 23 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | |
| 24 // | |
| 25 // As a special exception, if other files instantiate templates or use macros | |
| 26 // or inline functions from this file, or you compile this file and link it | |
| 27 // with other works to produce a work based on this file, this file does not | |
| 28 // by itself cause the resulting work to be covered by the GNU General Public | |
| 29 // License. However the source code for this file must still be made available | |
| 30 // in accordance with section (3) of the GNU General Public License. | |
| 31 // | |
| 32 // This exception does not invalidate any other reasons why a work based on | |
| 33 // this file might be covered by the GNU General Public License. | |
| 34 // | |
| 35 // ------------------------------------------- | |
| 36 //####ECOSGPLCOPYRIGHTEND#### | |
| 37 //####BSDCOPYRIGHTBEGIN#### | |
| 38 // | |
| 39 // ------------------------------------------- | |
| 40 // | |
| 41 // Portions of this software may have been derived from OpenBSD, | |
| 42 // FreeBSD or other sources, and are covered by the appropriate | |
| 43 // copyright disclaimers included herein. | |
| 44 // | |
| 45 // ------------------------------------------- | |
| 46 // | |
| 47 //####BSDCOPYRIGHTEND#### | |
| 48 //========================================================================== | |
| 49 | |
| 50 /* | |
| 51 * sys-bsd.c - System-dependent procedures for setting up | |
| 52 * PPP interfaces on bsd-4.4-ish systems (including 386BSD, NetBSD, etc.) | |
| 53 * | |
| 54 * Copyright (c) 1989 Carnegie Mellon University. | |
| 55 * Copyright (c) 1995 The Australian National University. | |
| 56 * All rights reserved. | |
| 57 * | |
| 58 * Redistribution and use in source and binary forms are permitted | |
| 59 * provided that the above copyright notice and this paragraph are | |
| 60 * duplicated in all such forms and that any documentation, | |
| 61 * advertising materials, and other materials related to such | |
| 62 * distribution and use acknowledge that the software was developed | |
| 63 * by Carnegie Mellon University and The Australian National University. | |
| 64 * The names of the Universities may not be used to endorse or promote | |
| 65 * products derived from this software without specific prior written | |
| 66 * permission. | |
| 67 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
| 68 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
| 69 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
| 70 */ | |
| 71 | |
| 72 #ifndef lint | |
| 73 //static char rcsid[] = "$FreeBSD: src/usr.sbin/pppd/sys-bsd.c,v 1.17 1999/08/28 01:19:08 peter Exp $"; | |
| 74 #endif | |
| 75 /* $NetBSD: sys-bsd.c,v 1.1.1.3 1997/09/26 18:53:04 christos Exp $ */ | |
| 76 | |
| 77 /* | |
| 78 * TODO: | |
| 79 */ | |
| 80 | |
| 81 //========================================================================== | |
| 82 | |
| 83 #include <pkgconf/system.h> | |
| 84 #include <pkgconf/net.h> | |
| 85 #include <pkgconf/ppp.h> | |
| 86 | |
| 87 #include <stdio.h> | |
| 88 #include <string.h> | |
| 89 #include <stdlib.h> | |
| 90 #include <unistd.h> | |
| 91 #include <errno.h> | |
| 92 #include <fcntl.h> | |
| 93 #include <termios.h> | |
| 94 #include <signal.h> | |
| 95 #define _KERNEL 1 | |
| 96 #include <sys/param.h> | |
| 97 #undef _KERNEL | |
| 98 #include <sys/ioctl.h> | |
| 99 #include <sys/types.h> | |
| 100 #include <sys/socket.h> | |
| 101 #include <sys/time.h> | |
| 102 #include <sys/stat.h> | |
| 103 #ifdef NetBSD1_2 | |
| 104 #include <util.h> | |
| 105 #endif | |
| 106 #ifdef PPP_FILTER | |
| 107 #include <net/bpf.h> | |
| 108 #endif | |
| 109 | |
| 110 #include <cyg/ppp/syslog.h> | |
| 111 | |
| 112 #include <net/if.h> | |
| 113 #include <cyg/ppp/net/ppp_defs.h> | |
| 114 #include <cyg/ppp/net/if_ppp.h> | |
| 115 #include <net/route.h> | |
| 116 #include <net/if_dl.h> | |
| 117 #include <netinet/in.h> | |
| 118 | |
| 119 #ifdef IPX_CHANGE | |
| 120 #include <netipx/ipx.h> | |
| 121 #endif | |
| 122 | |
| 123 #if RTM_VERSION >= 3 | |
| 124 #include <sys/param.h> | |
| 125 #if defined(NetBSD) && (NetBSD >= 199703) | |
| 126 #include <netinet/if_inarp.h> | |
| 127 #else /* NetBSD 1.2D or later */ | |
| 128 #include <netinet/if_ether.h> | |
| 129 #endif | |
| 130 #endif | |
| 131 | |
| 132 #include "cyg/ppp/pppd.h" | |
| 133 #include "cyg/ppp/fsm.h" | |
| 134 #include "cyg/ppp/ipcp.h" | |
| 135 | |
| 136 #include "cyg/ppp/ppp_io.h" | |
| 137 | |
| 138 #include <cyg/ppp/ppp.h> | |
| 139 | |
| 140 //========================================================================== | |
| 141 | |
| 142 static int rtm_seq; | |
| 143 | |
| 144 static cyg_io_handle_t ppp_handle; /* IO subsystem handle to PPP stream */ | |
| 145 struct tty ppp_tty; /* dummy TTY structure */ | |
| 146 | |
| 147 static cyg_handle_t ppp_rtc; | |
| 148 static cyg_resolution_t ppp_rtc_resolution; | |
| 149 | |
| 150 static int loop_slave = -1; | |
| 151 static int loop_master; | |
| 152 | |
| 153 static unsigned char inbuf[PPP_MTU + PPP_HDRLEN + 100]; /* buffer for chars read from input */ | |
| 154 | |
| 155 static int sockfd = -1; /* socket for doing interface ioctls */ | |
| 156 | |
| 157 static int if_is_up; /* the interface is currently up */ | |
| 158 static u_int32_t ifaddrs[2]; /* local and remote addresses we set */ | |
| 159 static u_int32_t default_route_gateway; /* gateway addr for default route */ | |
| 160 static u_int32_t proxy_arp_addr; /* remote addr for proxy arp */ | |
| 161 | |
| 162 /* Prototypes for procedures local to this file. */ | |
| 163 static int dodefaultroute __P((u_int32_t, int)); | |
| 164 static int get_ether_addr __P((u_int32_t, struct sockaddr_dl *)); | |
| 165 | |
| 166 static void wait_input_alarm(cyg_handle_t alarm, cyg_addrword_t data); | |
| 167 #ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS | |
| 168 void cyg_ppp_serial_callback( cyg_serial_line_status_t *s, | |
| 169 CYG_ADDRWORD priv ); | |
| 170 #endif | |
| 171 | |
| 1628 | 172 extern u_int32_t netmask; /* IP netmask to set on interface */ |
| 1586 | 173 |
| 174 //========================================================================== | |
| 175 /* | |
| 176 * sys_init - System-dependent initialization. | |
| 177 */ | |
| 178 void | |
| 179 sys_init() | |
| 180 { | |
| 181 if( sockfd == -1 ) | |
| 182 { | |
| 183 /* Get an internet socket for doing socket ioctl's on. */ | |
| 184 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { | |
| 185 syslog(LOG_ERR, "Couldn't create IP socket: %d",errno); | |
| 186 die(1); | |
| 187 } | |
| 188 } | |
| 189 | |
| 190 ppp_tty.pppd_wakeup = 0; | |
| 191 ppp_tty.pppd_thread_running = true; | |
| 192 | |
| 193 ppp_rtc = cyg_real_time_clock(); | |
| 194 ppp_rtc_resolution = cyg_clock_get_resolution( ppp_rtc ); | |
| 195 | |
| 196 cyg_alarm_create( ppp_rtc, | |
| 197 wait_input_alarm, | |
| 198 (cyg_addrword_t)&ppp_tty, | |
| 199 &ppp_tty.alarm, | |
| 200 &ppp_tty.alarm_obj); | |
| 201 } | |
| 202 | |
| 203 //========================================================================== | |
| 204 /* | |
| 205 * sys_cleanup - restore any system state we modified before exiting: | |
| 206 * mark the interface down, delete default route and/or proxy arp entry. | |
| 207 * This should call die() because it's called from die(). | |
| 208 */ | |
| 209 void | |
| 210 sys_cleanup() | |
| 211 { | |
| 212 struct ifreq ifr; | |
| 213 | |
| 214 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 215 if (if_is_up) { | |
| 216 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); | |
| 217 if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) >= 0 | |
| 218 && ((ifr.ifr_flags & IFF_UP) != 0)) { | |
| 219 ifr.ifr_flags &= ~IFF_UP; | |
| 220 ioctl(sockfd, SIOCSIFFLAGS, &ifr); | |
| 221 } | |
| 222 } | |
| 223 if (ifaddrs[0] != 0) | |
| 224 cifaddr(0, ifaddrs[0], ifaddrs[1]); | |
| 225 if (default_route_gateway) | |
| 226 cifdefaultroute(0, 0, default_route_gateway); | |
| 227 if (proxy_arp_addr) | |
| 228 cifproxyarp(0, proxy_arp_addr); | |
| 229 | |
| 230 if( sockfd != -1 ) | |
| 231 { | |
| 232 close(sockfd); | |
| 233 sockfd = -1; | |
| 234 } | |
| 235 } | |
| 236 | |
| 237 //========================================================================== | |
| 238 | |
| 239 #ifdef __ECOS | |
| 240 | |
| 241 void | |
| 242 sys_exit(void) | |
| 243 { | |
| 244 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 245 phase = PHASE_DEAD; | |
| 246 while( ppp_tty.tx_thread_running ) | |
| 247 { | |
| 248 db_printf("kick tx thread\n"); | |
| 249 cyg_semaphore_post( &ppp_tty.tx_sem ); | |
| 250 cyg_thread_delay(100); | |
| 251 } | |
| 252 ppp_tty.pppd_thread_running = false; | |
| 253 cyg_thread_exit(); | |
| 254 } | |
| 255 #endif | |
| 256 | |
| 257 //========================================================================== | |
| 258 /* | |
| 259 * sys_close - Clean up in a child process before execing. | |
| 260 */ | |
| 261 void | |
| 262 sys_close() | |
| 263 { | |
| 264 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 265 if (loop_slave >= 0) { | |
| 266 close(loop_slave); | |
| 267 close(loop_master); | |
| 268 } | |
| 269 } | |
| 270 | |
| 271 //========================================================================== | |
| 272 /* | |
| 273 * sys_check_options - check the options that the user specified | |
| 274 */ | |
| 275 void | |
| 276 sys_check_options() | |
| 277 { | |
| 278 //db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 279 } | |
| 280 | |
| 281 //========================================================================== | |
| 282 /* | |
| 283 * ppp_available - check whether the system has any ppp interfaces | |
| 284 * (in fact we check whether we can do an ioctl on ppp0). | |
| 285 */ | |
| 286 int | |
| 287 ppp_available() | |
| 288 { | |
| 289 int s, ok; | |
| 290 struct ifreq ifr; | |
| 291 extern char *no_ppp_msg; | |
| 292 | |
| 293 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) | |
| 294 return 1; /* can't tell */ | |
| 295 | |
| 296 strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); | |
| 297 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; | |
| 298 close(s); | |
| 299 | |
| 300 no_ppp_msg = "\ | |
| 301 This system lacks kernel support for PPP. To include PPP support\n\ | |
| 302 in the kernel, please follow the steps detailed in the README.bsd\n\ | |
| 303 file in the ppp-2.2 distribution.\n"; | |
| 304 return ok; | |
| 305 } | |
| 306 | |
| 307 //========================================================================== | |
| 308 /* | |
| 309 * establish_ppp - Turn the serial port into a ppp interface. | |
| 310 */ | |
| 311 void | |
| 312 establish_ppp(cyg_io_handle_t handle) | |
| 313 { | |
| 314 int s; | |
| 315 int x; | |
| 316 int err; | |
| 317 | |
| 318 //db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 319 | |
| 320 ppp_handle = ppp_tty.t_handle = handle; | |
| 321 ppp_tty.t_sc = NULL; | |
| 322 | |
| 323 s = splsoftnet(); | |
| 324 | |
| 325 err = cyg_ppp_pppopen( &ppp_tty ); | |
| 326 | |
| 327 if( err != 0 ) | |
| 328 syslog( LOG_ERR, "Couldn't establish PPP interface: %d", err ); | |
| 329 | |
| 330 /* | |
| 331 * Enable debug in the driver if requested. | |
| 332 */ | |
| 333 if (kdebugflag) { | |
| 334 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGFLAGS, (caddr_t) &x, 0)) < 0) { | |
| 335 syslog(LOG_WARNING, "ioctl (PPPIOCGFLAGS): %d",err); | |
| 336 } else { | |
| 337 x |= (kdebugflag & 0xFF) * SC_DEBUG; | |
| 338 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSFLAGS, (caddr_t) &x, 0)) < 0) | |
| 339 syslog(LOG_WARNING, "ioctl(PPPIOCSFLAGS): %d",err); | |
| 340 } | |
| 341 } | |
| 342 | |
| 343 splx(s); | |
| 344 } | |
| 345 | |
| 346 //========================================================================== | |
| 347 /* | |
| 348 * restore_loop - reattach the ppp unit to the loopback. | |
| 349 */ | |
| 350 void | |
| 351 restore_loop() | |
| 352 { | |
| 353 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 354 } | |
| 355 | |
| 356 | |
| 357 //========================================================================== | |
| 358 /* | |
| 359 * disestablish_ppp - Restore the serial port to normal operation. | |
| 360 * This shouldn't call die() because it's called from die(). | |
| 361 */ | |
| 362 void | |
| 363 disestablish_ppp(cyg_io_handle_t handle) | |
| 364 { | |
| 365 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 366 } | |
| 367 | |
| 368 //========================================================================== | |
| 369 /* | |
| 370 * Check whether the link seems not to be 8-bit clean. | |
| 371 */ | |
| 372 void | |
| 373 clean_check() | |
| 374 { | |
| 375 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 376 } | |
| 377 | |
| 378 //========================================================================== | |
| 379 /* | |
| 380 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity, | |
| 381 * at the requested speed, etc. If `local' is true, set CLOCAL | |
| 382 * regardless of whether the modem option was specified. | |
| 383 * | |
| 384 * For *BSD, we assume that speed_t values numerically equal bits/second. | |
| 385 */ | |
| 386 void | |
| 387 set_up_tty(cyg_io_handle_t handle, int local) | |
| 388 { | |
| 389 cyg_serial_info_t cfg; | |
| 390 int err; | |
| 391 int len = sizeof(cfg); | |
| 392 | |
| 393 err = cyg_io_get_config( handle, | |
| 394 CYG_IO_GET_CONFIG_SERIAL_INFO, | |
| 395 &cfg, | |
| 396 &len); | |
| 397 | |
| 398 if( err != 0 ) { | |
| 399 syslog(LOG_ERR, "cyg_io_get_config: %d",err); | |
| 400 die(1); | |
| 401 } | |
| 402 | |
| 403 switch ( flowctl ) | |
| 404 { | |
| 405 case CYG_PPP_FLOWCTL_DEFAULT: | |
| 406 break; | |
| 407 | |
| 408 case CYG_PPP_FLOWCTL_NONE: | |
| 409 cfg.flags &= ~(CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX| | |
| 410 CYGNUM_SERIAL_FLOW_XONXOFF_RX|CYGNUM_SERIAL_FLOW_XONXOFF_TX); | |
| 411 break; | |
| 412 | |
| 413 case CYG_PPP_FLOWCTL_HARDWARE: | |
| 414 cfg.flags &= ~(CYGNUM_SERIAL_FLOW_XONXOFF_RX|CYGNUM_SERIAL_FLOW_XONXOFF_TX); | |
| 415 cfg.flags |= CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX; | |
| 416 break; | |
| 417 | |
| 418 case CYG_PPP_FLOWCTL_SOFTWARE: | |
| 419 cfg.flags &= ~(CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX); | |
| 420 cfg.flags |= CYGNUM_SERIAL_FLOW_XONXOFF_RX|CYGNUM_SERIAL_FLOW_XONXOFF_TX; | |
| 421 break; | |
| 422 } | |
| 423 | |
| 424 if( inspeed != 0 ) | |
| 425 cfg.baud = inspeed; | |
| 426 | |
| 427 err = cyg_io_set_config( handle, | |
| 428 CYG_IO_SET_CONFIG_SERIAL_INFO, | |
| 429 &cfg, | |
| 430 &len); | |
| 431 | |
| 432 if( err != 0 ) { | |
| 433 syslog(LOG_ERR, "cyg_io_set_config: %d",err); | |
| 434 die(1); | |
| 435 } | |
| 436 } | |
| 437 | |
| 438 //========================================================================== | |
| 439 /* | |
| 440 * restore_tty - restore the terminal to the saved settings. | |
| 441 */ | |
| 442 void | |
| 443 restore_tty(cyg_io_handle_t handle) | |
| 444 { | |
| 445 #ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS | |
| 446 if( modem ) | |
| 447 { | |
| 448 // Restore callback handler if it was set. | |
| 449 | |
| 450 Cyg_ErrNo err; | |
| 451 cyg_uint32 len = sizeof(ppp_tty.serial_callbacks); | |
| 452 | |
| 453 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 454 | |
| 455 err = cyg_io_set_config( handle, | |
| 456 CYG_IO_SET_CONFIG_SERIAL_STATUS_CALLBACK, | |
| 457 &ppp_tty.serial_callbacks, | |
| 458 &len); | |
| 459 | |
| 460 if( err != 0 ) { | |
| 461 syslog(LOG_ERR, "cyg_io_set_config(restore serial callbacks): %d",err); | |
| 462 die(1); | |
| 463 } | |
| 464 } | |
| 465 #endif | |
| 466 } | |
| 467 | |
| 468 //========================================================================== | |
| 469 /* | |
| 470 * setdtr - control the DTR line on the serial port. | |
| 471 * This is called from die(), so it shouldn't call die(). | |
| 472 */ | |
| 473 void | |
| 474 setdtr(fd, on) | |
| 475 int fd, on; | |
| 476 { | |
| 477 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 478 } | |
| 479 | |
| 480 //========================================================================== | |
| 481 /* | |
| 482 * output - Output PPP packet. | |
| 483 */ | |
| 484 void | |
| 485 output(unit, p, len) | |
| 486 int unit; | |
| 487 u_char *p; | |
| 488 int len; | |
| 489 { | |
| 490 Cyg_ErrNo err; | |
| 491 struct uio uio; | |
| 492 struct iovec iov; | |
| 493 int s; | |
| 494 | |
| 495 if (debug) | |
| 496 log_packet(p, len, "sent ", LOG_DEBUG); | |
| 497 | |
| 498 | |
| 499 iov.iov_base = p; | |
| 500 iov.iov_len = len; | |
| 501 uio.uio_iov = &iov; | |
| 502 uio.uio_iovcnt = 1; | |
| 503 uio.uio_resid = len; | |
| 504 uio.uio_segflg = UIO_USERSPACE; | |
| 505 uio.uio_rw = UIO_WRITE; | |
| 506 | |
| 507 s = splsoftnet(); | |
| 508 | |
| 509 err = cyg_ppp_pppwrite( &ppp_tty, &uio, 0 ); | |
| 510 | |
| 511 splx(s); | |
| 512 | |
| 513 if( err != 0 ) | |
| 514 syslog(LOG_ERR, "write: %d",err); | |
| 515 | |
| 516 } | |
| 517 | |
| 518 //========================================================================== | |
| 519 | |
| 520 #ifdef __ECOS | |
| 521 | |
| 522 static void wait_input_alarm(cyg_handle_t alarm, cyg_addrword_t data) | |
| 523 { | |
| 524 cyg_thread_release( ppp_tty.pppd_thread ); | |
| 525 ppp_tty.pppd_wakeup = 1; | |
| 526 } | |
| 527 | |
| 528 #ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS | |
| 529 void cyg_ppp_serial_callback( cyg_serial_line_status_t *s, | |
| 530 CYG_ADDRWORD priv ) | |
| 531 { | |
| 532 externC int kill_link; | |
| 533 | |
| 534 // db_printf("serial callback %d %x\n",s->which, s->value ); | |
| 535 | |
| 536 if( s->which == CYGNUM_SERIAL_STATUS_CARRIERDETECT ) | |
| 537 { | |
| 538 if( s->value == 0 ) | |
| 539 { | |
| 540 // CD lost | |
|
1694
5629b7c30ed2
Various patches from Matt Jerdonek and Oyvind Harboe:
nickg
parents:
1629
diff
changeset
|
541 ppp_tty.carrier_detected = 0; |
| 1586 | 542 kill_link = 1; |
| 543 cyg_thread_release( ppp_tty.pppd_thread ); | |
| 544 ppp_tty.pppd_wakeup = 1; | |
| 545 } | |
| 546 else | |
| 547 { | |
| 548 // CD up | |
| 549 ppp_tty.carrier_detected = 1; | |
| 550 } | |
| 551 } | |
| 552 } | |
| 553 #endif | |
| 554 | |
| 555 static void cyg_ppp_tx_thread(CYG_ADDRWORD arg) | |
| 556 { | |
| 557 ppp_tty.tx_thread_running = true; | |
| 558 | |
| 559 // Wait for the PPPD thread to get going and start the PPP | |
| 560 // initialization phase. | |
| 561 while(phase == PHASE_DEAD ) | |
| 562 cyg_thread_delay(100); | |
| 563 | |
| 564 // Now loop until the link goes back down. | |
| 565 while( phase != PHASE_DEAD ) | |
| 566 { | |
| 567 cyg_semaphore_wait( &ppp_tty.tx_sem ); | |
| 568 | |
| 569 if( phase == PHASE_DEAD ) | |
| 570 break; | |
| 571 | |
| 572 // Call into PPP driver to get transmissions going. This is | |
| 573 // only called if some other thread has failed to transmit all | |
| 574 // of a packet due to a full buffer, or flow control. | |
| 575 | |
| 576 cyg_ppp_pppstart( &ppp_tty ); | |
| 577 } | |
| 578 | |
| 579 db_printf("%s exiting\n", __PRETTY_FUNCTION__); | |
| 580 ppp_tty.tx_thread_running = false; | |
| 581 cyg_thread_exit(); | |
| 582 } | |
| 583 | |
| 584 #endif | |
| 585 | |
| 586 | |
| 587 //========================================================================== | |
| 588 /* | |
| 589 * wait_input - wait until there is data available on ttyfd, | |
| 590 * for the length of time specified by *timo (indefinite | |
| 591 * if timo is NULL). | |
| 592 */ | |
| 593 void | |
| 594 wait_input(timo) | |
| 595 struct timeval *timo; | |
| 596 { | |
| 1629 | 597 // If there are any packets still waiting on the input queue then |
| 598 // return immediately to let the PPPD handle them. | |
| 599 if (cyg_ppp_pppcheck(&ppp_tty) != 0) | |
| 600 return; | |
| 601 | |
| 1586 | 602 if( timo != NULL ) |
| 603 { | |
| 604 cyg_tick_count_t trigger = timo->tv_sec*ppp_rtc_resolution.divisor; | |
| 605 | |
| 606 // If the timeval has a microseconds value, just add another | |
| 607 // second on to the trigger time. These are after all just | |
| 608 // timeouts, not accurate timings, so a bit of imprecision | |
| 609 // will not hurt. | |
| 610 if( timo->tv_usec != 0 ) | |
| 611 trigger += ppp_rtc_resolution.divisor; | |
| 612 | |
| 613 trigger += cyg_current_time(); | |
| 614 | |
| 615 // We set the alarm to retrigger after a second. This is in | |
| 616 // case it catches cyg_io_read() at an uninterruptible | |
| 617 // point. The alarm is disabled as soon as the read returns, | |
| 618 // so the retrigger will usually not happen. | |
| 619 cyg_alarm_initialize( ppp_tty.alarm, | |
| 620 trigger, | |
| 621 ppp_rtc_resolution.divisor ); | |
| 622 } | |
| 623 | |
| 624 for(;;) | |
| 625 { | |
| 626 int s; | |
| 627 int len = 1; | |
| 628 Cyg_ErrNo err; | |
| 629 cyg_serial_buf_info_t info; | |
| 630 cyg_uint32 ilen = sizeof(info); | |
| 631 | |
| 632 #if 1 | |
| 633 // Work out how many bytes are waiting in the serial device | |
| 634 // buffer and read them all at once. If there are none, we | |
| 635 // just wait for a single character to arrive. | |
| 636 | |
| 637 if( cyg_io_get_config( ppp_tty.t_handle, CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO, | |
| 638 &info, &ilen ) == 0 && info.rx_count > 1 ) | |
| 639 { | |
| 640 len = info.rx_count-1; | |
| 641 if( len > sizeof(inbuf) ) | |
| 642 len = sizeof(inbuf); | |
| 643 } | |
| 644 #endif | |
| 645 | |
| 646 if( timo != NULL ) | |
| 647 cyg_alarm_enable( ppp_tty.alarm ); | |
| 648 | |
| 649 err = cyg_io_read( ppp_handle, &inbuf, &len ); | |
| 650 | |
| 651 if( timo != NULL ) | |
| 652 cyg_alarm_disable( ppp_tty.alarm ); | |
| 653 | |
| 654 // db_printf("read: err %d len %d byte %02x\n",err,len,inbuf[0]); | |
| 655 | |
| 656 if( err == 0 ) | |
| 657 { | |
| 658 int i; | |
| 659 | |
| 660 // Pass all input data to PPP driver for analysis. If this | |
| 661 // turns out to be for the PPPD, it will call | |
| 662 // pppasyncctlp() which in turn will set | |
| 663 // ppp_tty.pppd_wakeup. We detect that on return from | |
| 664 // pppinput() and return to the caller to do pppd | |
| 665 // processing. | |
| 666 | |
| 667 s = splsoftnet(); | |
| 668 | |
| 669 for( i = 0; i < len; i++ ) | |
| 670 { | |
| 671 err = cyg_ppp_pppinput( inbuf[i], &ppp_tty ); | |
| 672 | |
| 673 if( err != 0 ) | |
| 674 syslog( LOG_ERR, "pppinput error: %d", err); | |
| 675 | |
| 676 } | |
| 677 | |
| 678 splx(s); | |
| 679 | |
| 680 } | |
| 681 else if( err != -EINTR ) | |
| 682 syslog( LOG_ERR, "Read error: %d",err); | |
| 683 | |
| 684 if( ppp_tty.pppd_wakeup ) | |
| 685 { | |
| 686 ppp_tty.pppd_wakeup = 0; | |
| 687 break; | |
| 688 } | |
| 689 } | |
| 690 } | |
| 691 | |
| 692 //========================================================================== | |
| 693 /* | |
| 694 * wait_time - wait for a given length of time or until a | |
| 695 * signal is received. | |
| 696 */ | |
| 697 void | |
| 698 wait_time(timo) | |
| 699 struct timeval *timo; | |
| 700 { | |
| 701 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 702 } | |
| 703 | |
| 704 | |
| 705 //========================================================================== | |
| 706 /* | |
| 707 * read_packet - get a PPP packet from the serial device. | |
| 708 */ | |
| 709 int | |
| 710 read_packet(buf) | |
| 711 u_char *buf; | |
| 712 { | |
| 713 int err; | |
| 714 struct uio uio; | |
| 715 struct iovec iov; | |
| 716 int len = PPP_MTU + PPP_HDRLEN; | |
| 717 int s; | |
| 718 | |
| 719 //db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 720 | |
| 721 iov.iov_base = buf; | |
| 722 iov.iov_len = len; | |
| 723 uio.uio_iov = &iov; | |
| 724 uio.uio_iovcnt = 1; | |
| 725 uio.uio_resid = len; | |
| 726 uio.uio_segflg = UIO_USERSPACE; | |
| 727 uio.uio_rw = UIO_READ; | |
| 728 | |
| 729 s = splsoftnet(); | |
| 730 | |
| 731 err = cyg_ppp_pppread( &ppp_tty, &uio, 0 ); | |
| 732 | |
| 733 splx(s); | |
| 734 | |
| 735 if( err == EWOULDBLOCK ) | |
| 736 return -1; | |
| 737 | |
| 738 if( err != 0 ) | |
| 739 { | |
| 740 syslog(LOG_ERR, "pppread: %d",err); | |
| 741 die(1); | |
| 742 } | |
| 743 | |
| 744 len -= uio.uio_resid; | |
| 745 | |
| 746 return len; | |
| 747 } | |
| 748 | |
| 749 //========================================================================== | |
| 750 /* | |
| 751 * ppp_send_config - configure the transmit characteristics of | |
| 752 * the ppp interface. | |
| 753 */ | |
| 754 void | |
| 755 ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) | |
| 756 int unit, mtu; | |
| 757 u_int32_t asyncmap; | |
| 758 int pcomp, accomp; | |
| 759 { | |
| 760 u_int x; | |
| 761 struct ifreq ifr; | |
| 762 int err; | |
| 763 int s; | |
| 764 | |
| 765 // db_printf("%s: unit %d mtu %d asyncmap %08x pcomp %08x accomp %08x\n", __PRETTY_FUNCTION__, | |
| 766 // unit,mtu,asyncmap,pcomp,accomp); | |
| 767 | |
| 768 strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); | |
| 769 ifr.ifr_mtu = mtu; | |
| 770 if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0) { | |
| 771 syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %d",errno); | |
| 772 quit(); | |
| 773 } | |
| 774 | |
| 775 | |
| 776 s = splsoftnet(); | |
| 777 | |
| 778 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSASYNCMAP, (caddr_t) &asyncmap, 0)) < 0) { | |
| 779 syslog(LOG_ERR, "ioctl(PPPIOCSASYNCMAP): %d",err); | |
| 780 } | |
| 781 | |
| 782 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGFLAGS, (caddr_t) &x, 0)) < 0) { | |
| 783 syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %d",err); | |
| 784 } | |
| 785 x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT; | |
| 786 x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC; | |
| 787 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSFLAGS, (caddr_t) &x, 0)) < 0) { | |
| 788 syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %d",err); | |
| 789 } | |
| 790 | |
| 791 splx(s); | |
| 792 } | |
| 793 | |
| 794 | |
| 795 //========================================================================== | |
| 796 /* | |
| 797 * ppp_set_xaccm - set the extended transmit ACCM for the interface. | |
| 798 */ | |
| 799 void | |
| 800 ppp_set_xaccm(unit, accm) | |
| 801 int unit; | |
| 802 ext_accm accm; | |
| 803 { | |
| 804 int error; | |
| 805 int s; | |
| 806 | |
| 807 //db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 808 | |
| 809 s = splsoftnet(); | |
| 810 | |
| 811 error = cyg_ppp_ppptioctl( &ppp_tty, PPPIOCSXASYNCMAP, (caddr_t)accm, 0 ); | |
| 812 | |
| 813 splx(s); | |
| 814 | |
| 815 if( error != 0 ) | |
| 816 syslog(LOG_WARNING, "ioctl(set extended ACCM): %d",error); | |
| 817 } | |
| 818 | |
| 819 | |
| 820 //========================================================================== | |
| 821 /* | |
| 822 * ppp_recv_config - configure the receive-side characteristics of | |
| 823 * the ppp interface. | |
| 824 */ | |
| 825 void | |
| 826 ppp_recv_config(unit, mru, asyncmap, pcomp, accomp) | |
| 827 int unit, mru; | |
| 828 u_int32_t asyncmap; | |
| 829 int pcomp, accomp; | |
| 830 { | |
| 831 int x; | |
| 832 int err; | |
| 833 int s; | |
| 834 | |
| 835 s = splsoftnet(); | |
| 836 | |
| 837 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSMRU, (caddr_t) &mru, 0)) < 0) { | |
| 838 syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %d",err); | |
| 839 } | |
| 840 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap, 0)) < 0) { | |
| 841 syslog(LOG_ERR, "ioctl(PPPIOCSRASYNCMAP): %d",err); | |
| 842 } | |
| 843 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGFLAGS, (caddr_t) &x, 0)) < 0) { | |
| 844 syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %d",err); | |
| 845 } | |
| 846 x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC; | |
| 847 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSFLAGS, (caddr_t) &x, 0)) < 0) { | |
| 848 syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %d",err); | |
| 849 } | |
| 850 | |
| 851 splx(s); | |
| 852 } | |
| 853 | |
| 854 //========================================================================== | |
| 855 /* | |
| 856 * ccp_test - ask kernel whether a given compression method | |
| 857 * is acceptable for use. Returns 1 if the method and parameters | |
| 858 * are OK, 0 if the method is known but the parameters are not OK | |
| 859 * (e.g. code size should be reduced), or -1 if the method is unknown. | |
| 860 */ | |
| 861 int | |
| 862 ccp_test(unit, opt_ptr, opt_len, for_transmit) | |
| 863 int unit, opt_len, for_transmit; | |
| 864 u_char *opt_ptr; | |
| 865 { | |
| 866 struct ppp_option_data data; | |
| 867 int s; | |
| 868 | |
| 869 data.ptr = opt_ptr; | |
| 870 data.length = opt_len; | |
| 871 data.transmit = for_transmit; | |
| 872 //db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 873 | |
| 874 s = splsoftnet(); | |
| 875 | |
| 876 errno = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSCOMPRESS, (caddr_t) &data, 0 ); | |
| 877 | |
| 878 splx(s); | |
| 879 | |
| 880 if (errno == 0) | |
| 881 return 1; | |
| 882 else return (errno == ENOBUFS)? 0: -1; | |
| 883 | |
| 884 } | |
| 885 | |
| 886 //========================================================================== | |
| 887 /* | |
| 888 * ccp_flags_set - inform kernel about the current state of CCP. | |
| 889 */ | |
| 890 void | |
| 891 ccp_flags_set(unit, isopen, isup) | |
| 892 int unit, isopen, isup; | |
| 893 { | |
| 894 int x; | |
| 895 | |
| 896 int err; | |
| 897 //db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 898 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGFLAGS, (caddr_t) &x, 0)) != 0) { | |
| 899 syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %d",err); | |
| 900 return; | |
| 901 } | |
| 902 x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN; | |
| 903 x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP; | |
| 904 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSFLAGS, (caddr_t) &x,0)) != 0) | |
| 905 syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %d",err); | |
| 906 } | |
| 907 | |
| 908 //========================================================================== | |
| 909 /* | |
| 910 * ccp_fatal_error - returns 1 if decompression was disabled as a | |
| 911 * result of an error detected after decompression of a packet, | |
| 912 * 0 otherwise. This is necessary because of patent nonsense. | |
| 913 */ | |
| 914 int | |
| 915 ccp_fatal_error(unit) | |
| 916 int unit; | |
| 917 { | |
| 918 int x; | |
| 919 int err; | |
| 920 | |
| 921 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 922 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGFLAGS, (caddr_t) &x, 0)) != 0) { | |
| 923 syslog(LOG_ERR, "ioctl(PPPIOCGFLAGS): %d",err); | |
| 924 return 0; | |
| 925 } | |
| 926 return x & SC_DC_FERROR; | |
| 927 } | |
| 928 | |
| 929 //========================================================================== | |
| 930 /* | |
| 931 * get_idle_time - return how long the link has been idle. | |
| 932 */ | |
| 933 int | |
| 934 get_idle_time(u, ip) | |
| 935 int u; | |
| 936 struct ppp_idle *ip; | |
| 937 { | |
| 938 return cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGIDLE, (caddr_t)ip, 0) == 0; | |
| 939 } | |
| 940 | |
| 941 | |
| 942 //========================================================================== | |
| 943 | |
| 944 #ifdef PPP_FILTER | |
| 945 /* | |
| 946 * set_filters - transfer the pass and active filters to the kernel. | |
| 947 */ | |
| 948 int | |
| 949 set_filters(pass, active) | |
| 950 struct bpf_program *pass, *active; | |
| 951 { | |
| 952 int ret = 1; | |
| 953 | |
| 954 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 955 if (pass->bf_len > 0) { | |
| 956 if (ioctl(ppp_fd, PPPIOCSPASS, pass) < 0) { | |
| 957 syslog(LOG_ERR, "Couldn't set pass-filter in kernel: %m"); | |
| 958 ret = 0; | |
| 959 } | |
| 960 } | |
| 961 if (active->bf_len > 0) { | |
| 962 if (ioctl(ppp_fd, PPPIOCSACTIVE, active) < 0) { | |
| 963 syslog(LOG_ERR, "Couldn't set active-filter in kernel: %m"); | |
| 964 ret = 0; | |
| 965 } | |
| 966 } | |
| 967 return ret; | |
| 968 } | |
| 969 #endif | |
| 970 | |
| 971 //========================================================================== | |
| 972 /* | |
| 973 * sifvjcomp - config tcp header compression | |
| 974 */ | |
| 975 int | |
| 976 sifvjcomp(u, vjcomp, cidcomp, maxcid) | |
| 977 int u, vjcomp, cidcomp, maxcid; | |
| 978 { | |
| 979 u_int x; | |
| 980 int err; | |
| 981 | |
| 982 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGFLAGS, (caddr_t) &x, 0)) != 0) { | |
| 983 syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %d",err); | |
| 984 return 0; | |
| 985 } | |
| 986 x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP; | |
| 987 x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID; | |
| 988 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSFLAGS, (caddr_t) &x, 0)) != 0) { | |
| 989 syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %d",err); | |
| 990 return 0; | |
| 991 } | |
| 992 if (vjcomp && ((err=cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSMAXCID, (caddr_t) &maxcid, 0)) != 0)) { | |
| 993 syslog(LOG_ERR, "ioctl(PPPIOCSMAXCID): %d",err); | |
| 994 return 0; | |
| 995 } | |
| 996 return 1; | |
| 997 } | |
| 998 | |
| 999 //========================================================================== | |
| 1000 /* | |
| 1001 * sifup - Config the interface up and enable IP packets to pass. | |
| 1002 */ | |
| 1003 int | |
| 1004 sifup(u) | |
| 1005 int u; | |
| 1006 { | |
| 1007 struct ifreq ifr; | |
| 1008 | |
| 1009 //db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1010 strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); | |
| 1011 if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { | |
| 1012 syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); | |
| 1013 return 0; | |
| 1014 } | |
| 1015 ifr.ifr_flags |= IFF_UP; | |
| 1016 if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { | |
| 1017 syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m"); | |
| 1018 return 0; | |
| 1019 } | |
| 1020 if_is_up = 1; | |
| 1021 return 1; | |
| 1022 } | |
| 1023 | |
| 1024 //========================================================================== | |
| 1025 /* | |
| 1026 * sifnpmode - Set the mode for handling packets for a given NP. | |
| 1027 */ | |
| 1028 int | |
| 1029 sifnpmode(u, proto, mode) | |
| 1030 int u; | |
| 1031 int proto; | |
| 1032 enum NPmode mode; | |
| 1033 { | |
| 1034 struct npioctl npi; | |
| 1035 | |
| 1036 //db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1037 npi.protocol = proto; | |
| 1038 npi.mode = mode; | |
| 1039 { | |
| 1040 int err; | |
| 1041 | |
| 1042 if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSNPMODE, (caddr_t)&npi, 0)) < 0) { | |
| 1043 syslog(LOG_ERR, "ioctl(set NP %d mode to %d): %d", proto, mode,err); | |
| 1044 return 0; | |
| 1045 } | |
| 1046 } | |
| 1047 | |
| 1048 return 1; | |
| 1049 } | |
| 1050 | |
| 1051 //========================================================================== | |
| 1052 /* | |
| 1053 * sifdown - Config the interface down and disable IP. | |
| 1054 */ | |
| 1055 int | |
| 1056 sifdown(u) | |
| 1057 int u; | |
| 1058 { | |
| 1059 struct ifreq ifr; | |
| 1060 int rv; | |
| 1061 struct npioctl npi; | |
| 1062 | |
| 1063 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1064 rv = 1; | |
| 1065 npi.protocol = PPP_IP; | |
| 1066 npi.mode = NPMODE_ERROR; | |
| 1067 { | |
| 1068 int err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSNPMODE, (caddr_t) &npi, 0); | |
| 1069 if( err < 0 ) | |
| 1070 syslog(LOG_WARNING, "ioctl(PPPIOCSNPMODE): %d",err); | |
| 1071 } | |
| 1072 strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); | |
| 1073 if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { | |
| 1074 syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); | |
| 1075 rv = 0; | |
| 1076 } else { | |
| 1077 ifr.ifr_flags &= ~IFF_UP; | |
| 1078 if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { | |
| 1079 syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m"); | |
| 1080 rv = 0; | |
| 1081 } else | |
| 1082 if_is_up = 0; | |
| 1083 } | |
| 1084 return rv; | |
| 1085 return 0; | |
| 1086 } | |
| 1087 | |
| 1088 //========================================================================== | |
| 1089 /* | |
| 1090 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, | |
| 1091 * if it exists. | |
| 1092 */ | |
| 1093 #define SET_SA_FAMILY(addr, family) \ | |
| 1094 BZERO((char *) &(addr), sizeof(addr)); \ | |
| 1095 addr.sa_family = (family); \ | |
| 1096 addr.sa_len = sizeof(addr); | |
| 1097 | |
| 1098 //========================================================================== | |
| 1099 /* | |
| 1100 * sifaddr - Config the interface IP addresses and netmask. | |
| 1101 */ | |
| 1102 int | |
| 1103 sifaddr(u, o, h, m) | |
| 1104 int u; | |
| 1105 u_int32_t o, h, m; | |
| 1106 { | |
| 1107 struct ifaliasreq ifra; | |
| 1108 struct ifreq ifr; | |
| 1109 | |
| 1110 //db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1111 strncpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); | |
| 1112 SET_SA_FAMILY(ifra.ifra_addr, AF_INET); | |
| 1113 ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o; | |
| 1114 SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET); | |
| 1115 ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h; | |
| 1116 if (m != 0) { | |
| 1117 SET_SA_FAMILY(ifra.ifra_mask, AF_INET); | |
| 1118 ((struct sockaddr_in *) &ifra.ifra_mask)->sin_addr.s_addr = m; | |
| 1119 } else | |
| 1120 BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask)); | |
| 1121 BZERO(&ifr, sizeof(ifr)); | |
| 1122 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); | |
| 1123 if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifr) < 0) { | |
| 1124 if (errno != EADDRNOTAVAIL) | |
| 1125 syslog(LOG_WARNING, "Couldn't remove interface address: %d",errno); | |
| 1126 } | |
| 1127 if (ioctl(sockfd, SIOCAIFADDR, (caddr_t) &ifra) < 0) { | |
| 1128 if (errno != EEXIST) { | |
| 1129 syslog(LOG_ERR, "Couldn't set interface address: %d",errno); | |
| 1130 return 0; | |
| 1131 } | |
| 1132 syslog(LOG_WARNING, | |
| 1133 "Couldn't set interface address: Address %s already exists", | |
| 1134 ip_ntoa(o)); | |
| 1135 } | |
| 1136 ifaddrs[0] = o; | |
| 1137 ifaddrs[1] = h; | |
| 1138 return 1; | |
| 1139 } | |
| 1140 | |
| 1141 //========================================================================== | |
| 1142 /* | |
| 1143 * cifaddr - Clear the interface IP addresses, and delete routes | |
| 1144 * through the interface if possible. | |
| 1145 */ | |
| 1146 int | |
| 1147 cifaddr(u, o, h) | |
| 1148 int u; | |
| 1149 u_int32_t o, h; | |
| 1150 { | |
| 1151 struct ifaliasreq ifra; | |
| 1152 | |
| 1153 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1154 ifaddrs[0] = 0; | |
| 1155 strncpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); | |
| 1156 SET_SA_FAMILY(ifra.ifra_addr, AF_INET); | |
| 1157 ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o; | |
| 1158 SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET); | |
| 1159 ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h; | |
| 1160 BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask)); | |
| 1161 if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifra) < 0) { | |
| 1162 if (errno != EADDRNOTAVAIL) | |
| 1163 syslog(LOG_WARNING, "Couldn't delete interface address: %m"); | |
| 1164 return 0; | |
| 1165 } | |
| 1166 return 1; | |
| 1167 } | |
| 1168 | |
| 1169 //========================================================================== | |
| 1170 /* | |
| 1171 * sifdefaultroute - assign a default route through the address given. | |
| 1172 */ | |
| 1173 int | |
| 1174 sifdefaultroute(u, l, g) | |
| 1175 int u; | |
| 1176 u_int32_t l, g; | |
| 1177 { | |
| 1178 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1179 return dodefaultroute(g, 's'); | |
| 1180 } | |
| 1181 | |
| 1182 //========================================================================== | |
| 1183 /* | |
| 1184 * cifdefaultroute - delete a default route through the address given. | |
| 1185 */ | |
| 1186 int | |
| 1187 cifdefaultroute(u, l, g) | |
| 1188 int u; | |
| 1189 u_int32_t l, g; | |
| 1190 { | |
| 1191 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1192 return dodefaultroute(g, 'c'); | |
| 1193 } | |
| 1194 | |
| 1195 //========================================================================== | |
| 1196 /* | |
| 1197 * dodefaultroute - talk to a routing socket to add/delete a default route. | |
| 1198 */ | |
| 1199 static int | |
| 1200 dodefaultroute(g, cmd) | |
| 1201 u_int32_t g; | |
| 1202 int cmd; | |
| 1203 { | |
| 1204 int routes; | |
| 1205 struct { | |
| 1206 struct rt_msghdr hdr; | |
| 1207 struct sockaddr_in dst; | |
| 1208 struct sockaddr_in gway; | |
| 1209 struct sockaddr_in mask; | |
| 1210 } rtmsg; | |
| 1211 | |
| 1212 db_printf("%s %08x %c\n", __PRETTY_FUNCTION__,g,cmd); | |
| 1213 if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { | |
| 1214 syslog(LOG_ERR, "Couldn't %s default route: socket: %d", | |
| 1215 cmd=='s'? "add": "delete",errno); | |
| 1216 return 0; | |
| 1217 } | |
| 1218 | |
| 1219 memset(&rtmsg, 0, sizeof(rtmsg)); | |
| 1220 rtmsg.hdr.rtm_type = cmd == 's'? RTM_ADD: RTM_DELETE; | |
| 1221 rtmsg.hdr.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; | |
| 1222 rtmsg.hdr.rtm_version = RTM_VERSION; | |
| 1223 rtmsg.hdr.rtm_seq = ++rtm_seq; | |
| 1224 rtmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; | |
| 1225 rtmsg.dst.sin_len = sizeof(rtmsg.dst); | |
| 1226 rtmsg.dst.sin_family = AF_INET; | |
| 1227 rtmsg.gway.sin_len = sizeof(rtmsg.gway); | |
| 1228 rtmsg.gway.sin_family = AF_INET; | |
| 1229 rtmsg.gway.sin_addr.s_addr = g; | |
| 1230 rtmsg.mask.sin_len = sizeof(rtmsg.dst); | |
| 1231 rtmsg.mask.sin_family = AF_INET; | |
| 1232 | |
| 1233 rtmsg.hdr.rtm_msglen = sizeof(rtmsg); | |
| 1234 if (write(routes, &rtmsg, sizeof(rtmsg)) < 0) { | |
| 1235 syslog(LOG_ERR, "Couldn't %s default route: %d", | |
| 1236 cmd=='s'? "add": "delete",errno); | |
| 1237 close(routes); | |
| 1238 return 0; | |
| 1239 } | |
| 1240 | |
| 1241 close(routes); | |
| 1242 default_route_gateway = (cmd == 's')? g: 0; | |
| 1243 return 1; | |
| 1244 } | |
| 1245 | |
| 1246 //========================================================================== | |
| 1247 | |
| 1248 #if RTM_VERSION >= 3 | |
| 1249 | |
| 1250 /* | |
| 1251 * sifproxyarp - Make a proxy ARP entry for the peer. | |
| 1252 */ | |
| 1253 static struct { | |
| 1254 struct rt_msghdr hdr; | |
| 1255 struct sockaddr_inarp dst; | |
| 1256 struct sockaddr_dl hwa; | |
| 1257 char extra[128]; | |
| 1258 } arpmsg; | |
| 1259 | |
| 1260 static int arpmsg_valid; | |
| 1261 | |
| 1262 int | |
| 1263 sifproxyarp(unit, hisaddr) | |
| 1264 int unit; | |
| 1265 u_int32_t hisaddr; | |
| 1266 { | |
| 1267 int routes; | |
| 1268 | |
| 1269 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1270 /* | |
| 1271 * Get the hardware address of an interface on the same subnet | |
| 1272 * as our local address. | |
| 1273 */ | |
| 1274 memset(&arpmsg, 0, sizeof(arpmsg)); | |
| 1275 if (!get_ether_addr(hisaddr, &arpmsg.hwa)) { | |
| 1276 syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP"); | |
| 1277 return 0; | |
| 1278 } | |
| 1279 | |
| 1280 if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { | |
| 1281 syslog(LOG_ERR, "Couldn't add proxy arp entry: socket: %m"); | |
| 1282 return 0; | |
| 1283 } | |
| 1284 | |
| 1285 arpmsg.hdr.rtm_type = RTM_ADD; | |
| 1286 arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC; | |
| 1287 arpmsg.hdr.rtm_version = RTM_VERSION; | |
| 1288 arpmsg.hdr.rtm_seq = ++rtm_seq; | |
| 1289 arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY; | |
| 1290 arpmsg.hdr.rtm_inits = RTV_EXPIRE; | |
| 1291 arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp); | |
| 1292 arpmsg.dst.sin_family = AF_INET; | |
| 1293 arpmsg.dst.sin_addr.s_addr = hisaddr; | |
| 1294 arpmsg.dst.sin_other = SIN_PROXY; | |
| 1295 | |
| 1296 arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg | |
| 1297 + arpmsg.hwa.sdl_len; | |
| 1298 if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) { | |
| 1299 syslog(LOG_ERR, "Couldn't add proxy arp entry: %m"); | |
| 1300 close(routes); | |
| 1301 return 0; | |
| 1302 } | |
| 1303 | |
| 1304 close(routes); | |
| 1305 arpmsg_valid = 1; | |
| 1306 proxy_arp_addr = hisaddr; | |
| 1307 return 1; | |
| 1308 } | |
| 1309 | |
| 1310 /* | |
| 1311 * cifproxyarp - Delete the proxy ARP entry for the peer. | |
| 1312 */ | |
| 1313 int | |
| 1314 cifproxyarp(unit, hisaddr) | |
| 1315 int unit; | |
| 1316 u_int32_t hisaddr; | |
| 1317 { | |
| 1318 int routes; | |
| 1319 | |
| 1320 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1321 if (!arpmsg_valid) | |
| 1322 return 0; | |
| 1323 arpmsg_valid = 0; | |
| 1324 | |
| 1325 arpmsg.hdr.rtm_type = RTM_DELETE; | |
| 1326 arpmsg.hdr.rtm_seq = ++rtm_seq; | |
| 1327 | |
| 1328 if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { | |
| 1329 syslog(LOG_ERR, "Couldn't delete proxy arp entry: socket: %m"); | |
| 1330 return 0; | |
| 1331 } | |
| 1332 | |
| 1333 if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) { | |
| 1334 syslog(LOG_ERR, "Couldn't delete proxy arp entry: %m"); | |
| 1335 close(routes); | |
| 1336 return 0; | |
| 1337 } | |
| 1338 | |
| 1339 close(routes); | |
| 1340 proxy_arp_addr = 0; | |
| 1341 return 1; | |
| 1342 } | |
| 1343 | |
| 1344 //========================================================================== | |
| 1345 | |
| 1346 #else /* RTM_VERSION */ | |
| 1347 | |
| 1348 /* | |
| 1349 * sifproxyarp - Make a proxy ARP entry for the peer. | |
| 1350 */ | |
| 1351 int | |
| 1352 sifproxyarp(unit, hisaddr) | |
| 1353 int unit; | |
| 1354 u_int32_t hisaddr; | |
| 1355 { | |
| 1356 struct arpreq arpreq; | |
| 1357 struct { | |
| 1358 struct sockaddr_dl sdl; | |
| 1359 char space[128]; | |
| 1360 } dls; | |
| 1361 | |
| 1362 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1363 BZERO(&arpreq, sizeof(arpreq)); | |
| 1364 | |
| 1365 /* | |
| 1366 * Get the hardware address of an interface on the same subnet | |
| 1367 * as our local address. | |
| 1368 */ | |
| 1369 if (!get_ether_addr(hisaddr, &dls.sdl)) { | |
| 1370 syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP"); | |
| 1371 return 0; | |
| 1372 } | |
| 1373 | |
| 1374 arpreq.arp_ha.sa_len = sizeof(struct sockaddr); | |
| 1375 arpreq.arp_ha.sa_family = AF_UNSPEC; | |
| 1376 BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen); | |
| 1377 SET_SA_FAMILY(arpreq.arp_pa, AF_INET); | |
| 1378 ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; | |
| 1379 arpreq.arp_flags = ATF_PERM | ATF_PUBL; | |
| 1380 if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) { | |
| 1381 syslog(LOG_ERR, "Couldn't add proxy arp entry: %m"); | |
| 1382 return 0; | |
| 1383 } | |
| 1384 | |
| 1385 proxy_arp_addr = hisaddr; | |
| 1386 return 1; | |
| 1387 } | |
| 1388 | |
| 1389 /* | |
| 1390 * cifproxyarp - Delete the proxy ARP entry for the peer. | |
| 1391 */ | |
| 1392 int | |
| 1393 cifproxyarp(unit, hisaddr) | |
| 1394 int unit; | |
| 1395 u_int32_t hisaddr; | |
| 1396 { | |
| 1397 struct arpreq arpreq; | |
| 1398 | |
| 1399 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1400 BZERO(&arpreq, sizeof(arpreq)); | |
| 1401 SET_SA_FAMILY(arpreq.arp_pa, AF_INET); | |
| 1402 ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; | |
| 1403 if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) { | |
| 1404 syslog(LOG_WARNING, "Couldn't delete proxy arp entry: %m"); | |
| 1405 return 0; | |
| 1406 } | |
| 1407 proxy_arp_addr = 0; | |
| 1408 return 1; | |
| 1409 } | |
| 1410 #endif /* RTM_VERSION */ | |
| 1411 | |
| 1412 | |
| 1413 //========================================================================== | |
| 1414 /* | |
| 1415 * get_ether_addr - get the hardware address of an interface on the | |
| 1416 * the same subnet as ipaddr. | |
| 1417 */ | |
| 1418 #define MAX_IFS 32 | |
| 1419 | |
| 1420 static int | |
| 1421 get_ether_addr(ipaddr, hwaddr) | |
| 1422 u_int32_t ipaddr; | |
| 1423 struct sockaddr_dl *hwaddr; | |
| 1424 { | |
| 1425 struct ifreq *ifr, *ifend, *ifp; | |
| 1426 u_int32_t ina, mask; | |
| 1427 struct sockaddr_dl *dla; | |
| 1428 struct ifreq ifreq; | |
| 1429 struct ifconf ifc; | |
| 1430 struct ifreq ifs[MAX_IFS]; | |
| 1431 | |
| 1432 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1433 ifc.ifc_len = sizeof(ifs); | |
| 1434 ifc.ifc_req = ifs; | |
| 1435 if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { | |
| 1436 syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m"); | |
| 1437 return 0; | |
| 1438 } | |
| 1439 | |
| 1440 /* | |
| 1441 * Scan through looking for an interface with an Internet | |
| 1442 * address on the same subnet as `ipaddr'. | |
| 1443 */ | |
| 1444 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); | |
| 1445 for (ifr = ifc.ifc_req; ifr < ifend; | |
| 1446 ifr = (struct ifreq *) ((char *)&ifr->ifr_addr | |
| 1447 + MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr)))) { | |
| 1448 if (ifr->ifr_addr.sa_family == AF_INET) { | |
| 1449 ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; | |
| 1450 strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); | |
| 1451 /* | |
| 1452 * Check that the interface is up, and not point-to-point | |
| 1453 * or loopback. | |
| 1454 */ | |
| 1455 if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) | |
| 1456 continue; | |
| 1457 if ((ifreq.ifr_flags & | |
| 1458 (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP)) | |
| 1459 != (IFF_UP|IFF_BROADCAST)) | |
| 1460 continue; | |
| 1461 /* | |
| 1462 * Get its netmask and check that it's on the right subnet. | |
| 1463 */ | |
| 1464 if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0) | |
| 1465 continue; | |
| 1466 mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr; | |
| 1467 if ((ipaddr & mask) != (ina & mask)) | |
| 1468 continue; | |
| 1469 | |
| 1470 break; | |
| 1471 } | |
| 1472 } | |
| 1473 | |
| 1474 if (ifr >= ifend) | |
| 1475 return 0; | |
| 1476 syslog(LOG_INFO, "found interface %s for proxy arp", ifr->ifr_name); | |
| 1477 | |
| 1478 /* | |
| 1479 * Now scan through again looking for a link-level address | |
| 1480 * for this interface. | |
| 1481 */ | |
| 1482 ifp = ifr; | |
| 1483 for (ifr = ifc.ifc_req; ifr < ifend; ) { | |
| 1484 if (strcmp(ifp->ifr_name, ifr->ifr_name) == 0 | |
| 1485 && ifr->ifr_addr.sa_family == AF_LINK) { | |
| 1486 /* | |
| 1487 * Found the link-level address - copy it out | |
| 1488 */ | |
| 1489 dla = (struct sockaddr_dl *) &ifr->ifr_addr; | |
| 1490 BCOPY(dla, hwaddr, dla->sdl_len); | |
| 1491 return 1; | |
| 1492 } | |
| 1493 ifr = (struct ifreq *) ((char *)&ifr->ifr_addr | |
| 1494 + MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr))); | |
| 1495 } | |
| 1496 | |
| 1497 return 0; | |
| 1498 } | |
| 1499 | |
| 1500 //========================================================================== | |
| 1501 /* | |
| 1502 * Return user specified netmask, modified by any mask we might determine | |
| 1503 * for address `addr' (in network byte order). | |
| 1504 * Here we scan through the system's list of interfaces, looking for | |
| 1505 * any non-point-to-point interfaces which might appear to be on the same | |
| 1506 * network as `addr'. If we find any, we OR in their netmask to the | |
| 1507 * user-specified netmask. | |
| 1508 */ | |
| 1509 u_int32_t | |
| 1510 GetMask(addr) | |
| 1511 u_int32_t addr; | |
| 1512 { | |
| 1513 u_int32_t mask, nmask, ina; | |
| 1514 struct ifreq *ifr, *ifend, ifreq; | |
| 1515 struct ifconf ifc; | |
| 1516 struct ifreq ifs[MAX_IFS]; | |
| 1517 | |
| 1518 addr = ntohl(addr); | |
| 1519 if (IN_CLASSA(addr)) /* determine network mask for address class */ | |
| 1520 nmask = IN_CLASSA_NET; | |
| 1521 else if (IN_CLASSB(addr)) | |
| 1522 nmask = IN_CLASSB_NET; | |
| 1523 else | |
| 1524 nmask = IN_CLASSC_NET; | |
| 1525 /* class D nets are disallowed by bad_ip_adrs */ | |
| 1526 mask = netmask | htonl(nmask); | |
| 1527 | |
| 1528 /* | |
| 1529 * Scan through the system's network interfaces. | |
| 1530 */ | |
| 1531 ifc.ifc_len = sizeof(ifs); | |
| 1532 ifc.ifc_req = ifs; | |
| 1533 if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { | |
| 1534 syslog(LOG_WARNING, "ioctl(SIOCGIFCONF): %m"); | |
| 1535 return mask; | |
| 1536 } | |
| 1537 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); | |
| 1538 for (ifr = ifc.ifc_req; ifr < ifend; | |
| 1539 ifr = (struct ifreq *) ((char *)&ifr->ifr_addr | |
| 1540 + MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr)))) { | |
| 1541 /* | |
| 1542 * Check the interface's internet address. | |
| 1543 */ | |
| 1544 if (ifr->ifr_addr.sa_family != AF_INET) | |
| 1545 continue; | |
| 1546 ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; | |
| 1547 if ((ntohl(ina) & nmask) != (addr & nmask)) | |
| 1548 continue; | |
| 1549 /* | |
| 1550 * Check that the interface is up, and not point-to-point or loopback. | |
| 1551 */ | |
| 1552 strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); | |
| 1553 if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) | |
| 1554 continue; | |
| 1555 if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) | |
| 1556 != IFF_UP) | |
| 1557 continue; | |
| 1558 /* | |
| 1559 * Get its netmask and OR it into our mask. | |
| 1560 */ | |
| 1561 if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0) | |
| 1562 continue; | |
| 1563 mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr; | |
| 1564 } | |
| 1565 | |
| 1566 return mask; | |
| 1567 } | |
| 1568 | |
| 1569 //========================================================================== | |
| 1570 /* | |
| 1571 * Use the hostid as part of the random number seed. | |
| 1572 */ | |
| 1573 int | |
| 1574 get_host_seed() | |
| 1575 { | |
| 1576 //db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1577 #ifndef __ECOS | |
| 1578 return gethostid(); | |
| 1579 #endif | |
| 1580 return 0; | |
| 1581 } | |
| 1582 | |
| 1583 //===================================================================== | |
| 1584 // PAP stubs | |
| 1585 // | |
| 1586 // When omitting PAP, these fill in the dangling references from auth.c | |
| 1587 // | |
| 1588 | |
| 1589 #ifndef CYGPKG_PPP_PAP | |
| 1590 | |
| 1591 void | |
| 1592 upap_authwithpeer(unit, user, password) | |
| 1593 int unit; | |
| 1594 char *user, *password; | |
| 1595 { | |
| 1596 unit=unit; | |
| 1597 user=user; | |
| 1598 password=password; | |
| 1599 } | |
| 1600 | |
| 1601 void | |
| 1602 upap_authpeer(unit) | |
| 1603 int unit; | |
| 1604 { | |
| 1605 unit=unit; | |
| 1606 } | |
| 1607 | |
| 1608 #endif | |
| 1609 | |
| 1610 //===================================================================== | |
| 1611 // CHAP stubs | |
| 1612 // | |
| 1613 // When omitting CHAP, these fill in the dangling references from auth.c | |
| 1614 // | |
| 1615 | |
| 1616 #ifndef CYGPKG_PPP_CHAP | |
| 1617 | |
| 1618 void | |
| 1619 ChapAuthWithPeer(unit, our_name, digest) | |
| 1620 int unit; | |
| 1621 char *our_name; | |
| 1622 int digest; | |
| 1623 { | |
| 1624 unit=unit; | |
| 1625 our_name=our_name; | |
| 1626 digest=digest; | |
| 1627 } | |
| 1628 | |
| 1629 void | |
| 1630 ChapAuthPeer(unit, our_name, digest) | |
| 1631 int unit; | |
| 1632 char *our_name; | |
| 1633 int digest; | |
| 1634 { | |
| 1635 unit=unit; | |
| 1636 our_name=our_name; | |
| 1637 digest=digest; | |
| 1638 } | |
| 1639 | |
| 1640 #endif | |
| 1641 | |
| 1642 //===================================================================== | |
| 1643 // eCos API | |
| 1644 | |
| 1645 externC cyg_int32 cyg_ppp_options_init( cyg_ppp_options_t *options ) | |
| 1646 { | |
| 1647 if( options == NULL ) | |
| 1648 return -1; | |
| 1649 | |
| 1650 options->debug = 0; | |
| 1651 options->kdebugflag = 0; | |
| 1652 options->default_route = 1; | |
| 1653 options->modem = 0; | |
| 1654 options->flowctl = CYG_PPP_FLOWCTL_HARDWARE; | |
| 1655 options->refuse_pap = 0; | |
| 1656 options->refuse_chap = 0; | |
| 1657 | |
| 1658 options->baud = CYGNUM_SERIAL_BAUD_115200; | |
| 1659 | |
| 1660 options->idle_time_limit = 1*60; | |
| 1661 options->maxconnect = 0; | |
| 1662 | |
| 1663 options->our_address = 0; | |
| 1664 options->his_address = 0; | |
| 1665 | |
| 1666 options->script = NULL; | |
| 1667 | |
| 1668 strncpy( options->user, CYGPKG_PPP_AUTH_DEFAULT_USER, MAXNAMELEN ); | |
| 1669 strncpy( options->passwd, CYGPKG_PPP_AUTH_DEFAULT_PASSWD, MAXSECRETLEN ); | |
| 1670 | |
| 1671 return 0; | |
| 1672 } | |
| 1673 | |
| 1674 // ------------------------------------------------------------------------- | |
| 1675 | |
| 1676 | |
| 1677 #define CYGNUM_PPP_PPPD_THREAD_STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL+0x1000) | |
| 1678 | |
| 1679 static char cyg_pppd_stack[CYGNUM_PPP_PPPD_THREAD_STACK_SIZE]; | |
| 1680 static cyg_thread cyg_pppd_thread_obj; | |
| 1681 | |
| 1682 static char cyg_ppp_tx_thread_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; | |
| 1683 static cyg_thread cyg_ppp_tx_thread_obj; | |
| 1684 | |
| 1685 | |
| 1686 externC void cyg_pppd_main(CYG_ADDRWORD arg); | |
| 1687 | |
| 1688 | |
| 1689 externC cyg_ppp_handle_t cyg_ppp_up( const char *devnam_arg, | |
| 1690 const cyg_ppp_options_t *options ) | |
| 1691 { | |
| 1692 | |
| 1693 if( options == NULL || phase != PHASE_DEAD ) | |
| 1694 return 0; | |
| 1695 | |
|
1694
5629b7c30ed2
Various patches from Matt Jerdonek and Oyvind Harboe:
nickg
parents:
1629
diff
changeset
|
1696 // Initialize control block |
|
5629b7c30ed2
Various patches from Matt Jerdonek and Oyvind Harboe:
nickg
parents:
1629
diff
changeset
|
1697 memset(&ppp_tty, 0, sizeof(struct tty)); |
|
5629b7c30ed2
Various patches from Matt Jerdonek and Oyvind Harboe:
nickg
parents:
1629
diff
changeset
|
1698 |
| 1586 | 1699 strncpy( devnam, devnam_arg, PATH_MAX ); |
| 1700 | |
| 1701 ppp_tty.options = options; | |
| 1702 | |
| 1703 // Start the PPPD thread | |
| 1704 cyg_thread_create(CYGNUM_PPP_PPPD_THREAD_PRIORITY, | |
| 1705 cyg_pppd_main, | |
| 1706 (CYG_ADDRWORD)&ppp_tty, | |
| 1707 "PPPD", | |
| 1708 &cyg_pppd_stack[0], | |
| 1709 CYGNUM_PPP_PPPD_THREAD_STACK_SIZE, | |
| 1710 &ppp_tty.pppd_thread, | |
| 1711 &cyg_pppd_thread_obj | |
| 1712 ); | |
| 1713 cyg_thread_resume(ppp_tty.pppd_thread); | |
| 1714 | |
| 1715 // Start the TX thread | |
| 1716 cyg_semaphore_init( &ppp_tty.tx_sem, 0 ); | |
| 1717 | |
| 1718 cyg_thread_create(CYGNUM_PPP_PPPD_THREAD_PRIORITY+1, | |
| 1719 cyg_ppp_tx_thread, | |
| 1720 (CYG_ADDRWORD)&ppp_tty, | |
| 1721 "PPP Tx Thread", | |
| 1722 &cyg_ppp_tx_thread_stack[0], | |
| 1723 sizeof(cyg_ppp_tx_thread_stack), | |
| 1724 &ppp_tty.tx_thread, | |
| 1725 &cyg_ppp_tx_thread_obj | |
| 1726 ); | |
| 1727 cyg_thread_resume(ppp_tty.tx_thread); | |
| 1728 | |
| 1729 // Wait for the PPPD thread to get going and start the PPP | |
| 1730 // initialization phase. | |
| 1731 while(phase == PHASE_DEAD ) | |
| 1732 cyg_thread_delay(100); | |
| 1733 | |
| 1734 return (cyg_ppp_handle_t)&ppp_tty; | |
| 1735 } | |
| 1736 | |
| 1737 // ------------------------------------------------------------------------- | |
| 1738 | |
| 1739 externC char **script; | |
| 1740 | |
| 1741 externC void cyg_ppp_options_install( const cyg_ppp_options_t *options ) | |
| 1742 { | |
| 1743 debug = options->debug; | |
| 1744 kdebugflag = options->kdebugflag; | |
| 1745 | |
| 1746 modem = options->modem; | |
| 1747 flowctl = options->flowctl; | |
| 1748 refuse_pap = options->refuse_pap; | |
| 1749 refuse_chap = options->refuse_chap; | |
| 1750 | |
| 1751 inspeed = options->baud; | |
| 1752 | |
| 1753 idle_time_limit = options->idle_time_limit; | |
| 1754 maxconnect = options->maxconnect; | |
| 1755 | |
| 1756 { | |
| 1757 ipcp_options *wo = &ipcp_wantoptions[0]; | |
| 1758 | |
| 1759 wo->ouraddr = options->our_address; | |
| 1760 wo->hisaddr = options->his_address; | |
| 1761 | |
| 1762 wo->default_route = options->default_route; | |
| 1763 | |
| 1764 } | |
| 1765 | |
| 1766 script = options->script; | |
| 1767 | |
| 1768 strncpy( user, &options->user[0], MAXNAMELEN ); | |
| 1769 strncpy( passwd, &options->passwd[0], MAXSECRETLEN ); | |
| 1770 | |
| 1771 } | |
| 1772 | |
| 1773 // ------------------------------------------------------------------------- | |
| 1774 | |
| 1775 externC cyg_int32 cyg_ppp_down( const cyg_ppp_handle_t handle ) | |
| 1776 { | |
| 1777 if( phase != PHASE_DEAD ) | |
| 1778 { | |
| 1779 externC int kill_link; | |
| 1780 kill_link = 1; | |
| 1781 cyg_thread_release( ppp_tty.pppd_thread ); | |
| 1782 ppp_tty.pppd_wakeup = 1; | |
| 1783 return 0; | |
| 1784 } | |
| 1785 else | |
| 1786 return -1; | |
| 1787 } | |
| 1788 | |
| 1789 // ------------------------------------------------------------------------- | |
| 1790 | |
| 1791 externC cyg_int32 cyg_ppp_wait_up( cyg_ppp_handle_t handle ) | |
| 1792 { | |
| 1793 while(!( (phase == PHASE_NETWORK && ifaddrs[0] != 0) || | |
| 1794 phase == PHASE_DEAD ) ) | |
| 1795 cyg_thread_delay(100); | |
| 1796 | |
| 1797 return phase == PHASE_NETWORK ? 0 : -1; | |
| 1798 } | |
| 1799 | |
| 1800 // ------------------------------------------------------------------------- | |
| 1801 | |
| 1802 externC void cyg_ppp_wait_down( cyg_ppp_handle_t handle ) | |
| 1803 { | |
| 1804 while( ppp_tty.tx_thread_running || ppp_tty.pppd_thread_running ) | |
| 1805 cyg_thread_delay(100); | |
| 1806 | |
| 1807 cyg_thread_delete( ppp_tty.tx_thread ); | |
| 1808 cyg_thread_delete( ppp_tty.pppd_thread ); | |
| 1809 } | |
| 1810 | |
| 1811 //===================================================================== | |
| 1812 // eCos extras | |
| 1813 | |
| 1814 void syslog( int level, char *fmt, ... ) | |
| 1815 { | |
| 1816 va_list ap; | |
| 1817 int ret; | |
| 1818 | |
| 1819 #ifdef CYGPKG_PPP_DEBUG_WARN_ONLY | |
| 1820 if(!( level == LOG_ERR || | |
| 1821 level == LOG_WARNING )) | |
| 1822 return; | |
| 1823 #endif | |
| 1824 | |
| 1825 va_start(ap, fmt); | |
| 1826 diag_printf("SYSLOG %02x: ",level); | |
| 1827 ret = diag_vprintf(fmt, ap); | |
| 1828 diag_printf("\n"); | |
| 1829 va_end(ap); | |
| 1830 } | |
| 1831 | |
| 1832 //===================================================================== | |
| 1833 | |
| 1834 int gettimeofday(struct timeval *tv, struct timezone *tz) | |
| 1835 { | |
| 1836 cyg_tick_count_t time = cyg_current_time(); | |
| 1837 | |
| 1838 tv->tv_sec = time/CYGNUM_HAL_RTC_DENOMINATOR; | |
| 1839 tv->tv_usec = (time%CYGNUM_HAL_RTC_DENOMINATOR)*10000; | |
| 1840 | |
| 1841 // db_printf("%s: %d %d\n", __PRETTY_FUNCTION__, tv->tv_sec, tv->tv_usec); | |
| 1842 | |
| 1843 return 0; | |
| 1844 } | |
| 1845 | |
| 1846 //===================================================================== | |
| 1847 | |
| 1848 char *crypt (const char *key, const char *salt) | |
| 1849 { | |
| 1850 static char res[13]; | |
| 1851 | |
| 1852 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1853 | |
| 1854 return res; | |
| 1855 } | |
| 1856 | |
| 1857 | |
| 1858 //===================================================================== | |
| 1859 /* | |
| 1860 * Substitute procedures for those systems which don't have | |
| 1861 * drand48 et al. | |
| 1862 */ | |
| 1863 | |
| 1864 double | |
| 1865 drand48(void) | |
| 1866 { | |
| 1867 return (double)rand() / (double)0x7fffffffL; /* 2**31-1 */ | |
| 1868 } | |
| 1869 | |
| 1870 long | |
| 1871 mrand48(void) | |
| 1872 { | |
| 1873 return rand(); | |
| 1874 } | |
| 1875 | |
| 1876 void | |
| 1877 srand48(long seedval) | |
| 1878 { | |
| 1879 srand(seedval); | |
| 1880 } | |
| 1881 | |
| 1882 | |
| 1883 //===================================================================== | |
| 1884 | |
| 1885 #if 0 | |
| 1886 | |
| 1887 #undef MD5Init | |
| 1888 #undef MD5Update | |
| 1889 #undef MD5Final | |
| 1890 | |
| 1891 #include <sys/types.h> | |
| 1892 | |
| 1893 #include <sys/md5.h> | |
| 1894 | |
| 1895 | |
| 1896 void cyg_MD5Init( MD5_CTX *ctx ); | |
| 1897 void cyg_MD5Update (MD5_CTX *ctx, const unsigned char *buf, unsigned int size); | |
| 1898 void cyg_MD5Final (unsigned char hash[16], MD5_CTX *ctx); | |
| 1899 | |
| 1900 | |
| 1901 void cyg_ppp_MD5Init( MD5_CTX *ctx ) | |
| 1902 { | |
| 1903 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1904 cyg_MD5Init( ctx ); | |
| 1905 return; | |
| 1906 } | |
| 1907 | |
| 1908 void cyg_ppp_MD5Update (MD5_CTX *ctx, const unsigned char *buf, unsigned int size) | |
| 1909 { | |
| 1910 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1911 cyg_MD5Update( ctx, buf, size ); | |
| 1912 return; | |
| 1913 } | |
| 1914 | |
| 1915 void cyg_ppp_MD5Final (unsigned char hash[16], MD5_CTX *ctx) | |
| 1916 { | |
| 1917 db_printf("%s called\n", __PRETTY_FUNCTION__); | |
| 1918 cyg_MD5Final( hash, ctx ); | |
| 1919 return; | |
| 1920 } | |
| 1921 | |
| 1922 #endif | |
| 1923 | |
| 1924 //===================================================================== | |
| 1925 // End of sys-ecos.c | |
| 1926 | |
| 1927 |
