diff options
author | cvs2svn <cvs2svn@FreeBSD.org> | 2006-11-18 03:53:17 +0000 |
---|---|---|
committer | cvs2svn <cvs2svn@FreeBSD.org> | 2006-11-18 03:53:17 +0000 |
commit | e729e23abef51b2f36c787e0026fbc4fa5183897 (patch) | |
tree | c712482caa078ebe9d0a0d278471e6aa11583ece | |
parent | 8fe69c690acc88aee0795acb666dd379d14882e9 (diff) | |
download | src-e729e23abef51b2f36c787e0026fbc4fa5183897.tar.gz src-e729e23abef51b2f36c787e0026fbc4fa5183897.zip |
This commit was manufactured by cvs2svn to create branch 'RELENG_6'.
Notes
Notes:
svn path=/stable/6/; revision=164371
-rw-r--r-- | share/man/man4/snd_spicds.4 | 87 | ||||
-rw-r--r-- | share/man/man4/uark.4 | 85 | ||||
-rw-r--r-- | sys/dev/isp/isp_stds.h | 213 | ||||
-rw-r--r-- | sys/dev/usb/uark.c | 367 | ||||
-rw-r--r-- | sys/modules/uark/Makefile | 8 | ||||
-rw-r--r-- | usr.sbin/ipfwpcap/ipfwpcap.8 | 132 | ||||
-rw-r--r-- | usr.sbin/pppd/eui64.c | 46 | ||||
-rw-r--r-- | usr.sbin/pppd/eui64.h | 97 | ||||
-rw-r--r-- | usr.sbin/pppd/ipv6cp.c | 1421 | ||||
-rw-r--r-- | usr.sbin/pppd/ipv6cp.h | 129 | ||||
-rw-r--r-- | usr.sbin/wpa/wpa_passphrase/Makefile | 11 | ||||
-rw-r--r-- | usr.sbin/wpa/wpa_passphrase/wpa_passphrase.8 | 66 |
12 files changed, 2662 insertions, 0 deletions
diff --git a/share/man/man4/snd_spicds.4 b/share/man/man4/snd_spicds.4 new file mode 100644 index 000000000000..fd7e5090d10b --- /dev/null +++ b/share/man/man4/snd_spicds.4 @@ -0,0 +1,87 @@ +.\" Copyright (c) 2006 Alexander Leidinger +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd September 30, 2006 +.Dt SND_SPICDS 4 +.Os +.Sh NAME +.Nm snd_spicds +.Nd "I2S SPI audio codec driver" +.Sh SYNOPSIS +To compile this driver into the kernel, place the following lines in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device snd_spicds" +.Ed +.Pp +Alternatively, to load the driver as a module at boot time, place the +following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +snd_spicds_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +I2S codec driver is used by several sound drivers for soundcards which use +the supported codec chips. +.Sh HARDWARE +The +.Nm +driver supports the following codecs: +.Pp +.Bl -bullet -compact +.It +AK4358 +.It +AK4381 +.It +AK4524 +.It +AK4528 +.It +WM8770 +.El +.Sh SEE ALSO +.Xr snd_envy24 4 , +.Xr snd_envy24ht 4 , +.Xr sound 4 +.Sh HISTORY +The +.Nm +device driver first appeared in +.Fx 7.0 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Konstantin Dimitrov +based upon the +.Xr snd_envy24 4 +driver. +This manual page was written by +.An Alexander Leidinger Aq netchild@FreeBSD.org . diff --git a/share/man/man4/uark.4 b/share/man/man4/uark.4 new file mode 100644 index 000000000000..c274ecc11f8d --- /dev/null +++ b/share/man/man4/uark.4 @@ -0,0 +1,85 @@ +.\" $OpenBSD: uark.4,v 1.3 2006/10/26 19:42:36 jmc Exp $ +.\" +.\" Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" $FreeBSD$ +.\" +.Dd November 15, 2006 +.Dt UARK 4 +.Os +.Sh NAME +.Nm uark +.Nd Arkmicro Technologies ARK3116 based USB serial adapter +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following lines in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device uark" +.Cd "device ucom" +.Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +uark_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +driver supports Arkmicro Technologies ARK3116 based serial adapters. +.Sh HARDWARE +The +.Nm +driver supports the following adapters: +.Pp +.Bl -bullet -compact +.It +HL USB-RS232 +.It +HugePine USB-UART +.It +KQ-U8A Data Cable +.It +Skymaster USB to RS232 +.El +.Sh SEE ALSO +.Xr tty 4 , +.Xr ucom 4 , +.Xr uhub 4 , +.Xr usb 4 +.Sh HISTORY +The +.Nm +device driver first appeared in +.Ox 4.0 . +The first +.Fx +release to include it was +.Fx 7.0 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Jonathan Gray +.Aq jsg@openbsd.org . +.Sh CAVEATS +Setting hardware flow control is not currently supported. +It is not yet known how to ask the hardware to send a break. +.Pp +Arkmicro Technologies do not reply to requests of documentation +for their products. diff --git a/sys/dev/isp/isp_stds.h b/sys/dev/isp/isp_stds.h new file mode 100644 index 000000000000..bfacd14decd4 --- /dev/null +++ b/sys/dev/isp/isp_stds.h @@ -0,0 +1,213 @@ +/* $FreeBSD$ */ +/*- + * Mailbox and Queue Entry Definitions for for Qlogic ISP SCSI adapters. + * + * Copyright (c) 1997-2006 by Matthew Jacob + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/* + * Structures that derive directly from public standards. + */ +#ifndef _ISP_STDS_H +#define _ISP_STDS_H + +/* + * FC Frame Header + * + * Source: dpANS-X3.xxx-199x, section 18 (AKA FC-PH-2) + * + */ +typedef struct { + uint8_t r_ctl; + uint8_t d_id[3]; + uint8_t cs_ctl; + uint8_t s_id[3]; + uint8_t type; + uint8_t f_ctl; + uint8_t seq_id; + uint8_t df_ctl; + uint16_t seq_cnt; + uint16_t ox_id; + uint16_t rx_id; + uint32_t parameter; +} fc_hdr_t; + +/* + * FCP_CMND_IU Payload + * + * Source: NICTS T10, Project 1144D, Revision 07a, Section 9 (AKA fcp2-r07a) + * + * Notes: + * When additional cdb length is defined in fcp_cmnd_alen_datadir, + * bits 2..7, the actual cdb length is 16 + ((fcp_cmnd_alen_datadir>>2)*4), + * with the datalength following in MSB format just after. + */ +typedef struct { + uint8_t fcp_cmnd_lun[8]; + uint8_t fcp_cmnd_crn; + uint8_t fcp_cmnd_task_attribute; + uint8_t fcp_cmnd_task_management; + uint8_t fcp_cmnd_alen_datadir; + union { + struct { + uint8_t fcp_cmnd_cdb[16]; + uint32_t fcp_cmnd_dl; + } sf; + struct { + uint8_t fcp_cmnd_cdb[1]; + } lf; + } cdb_dl; +} fcp_cmnd_iu_t; + + +#define FCP_CMND_TASK_ATTR_SIMPLE 0x00 +#define FCP_CMND_TASK_ATTR_HEAD 0x01 +#define FCP_CMND_TASK_ATTR_ORDERED 0x02 +#define FCP_CMND_TASK_ATTR_ACA 0x04 +#define FCP_CMND_TASK_ATTR_UNTAGGED 0x05 +#define FCP_CMND_TASK_ATTR_MASK 0x07 + +#define FCP_CMND_ADDTL_CDBLEN_SHIFT 2 + +#define FCP_CMND_DATA_WRITE 0x01 +#define FCP_CMND_DATA_READ 0x02 + +#define FCP_CMND_DATA_DIR_MASK 0x03 + +#define FCP_CMND_TMF_CLEAR_ACA 0x40 +#define FCP_CMND_TMF_TGT_RESET 0x20 +#define FCP_CMND_TMF_LUN_RESET 0x10 +#define FCP_CMND_TMF_CLEAR_TASK_SET 0x04 +#define FCP_CMND_TMF_ABORT_TASK_SET 0x02 + +/* + * Basic CT IU Header + * + * Source: X3.288-199x Generic Services 2 Rev 5.3 (FC-GS-2) Section 4.3.1 + */ + +typedef struct { + uint8_t ct_revision; + uint8_t ct_in_id[3]; + uint8_t ct_fcs_type; + uint8_t ct_fcs_subtype; + uint8_t ct_options; + uint8_t ct_reserved0; + uint16_t ct_cmd_resp; + uint16_t ct_bcnt_resid; + uint8_t ct_reserved1; + uint8_t ct_reason; + uint8_t ct_explanation; + uint8_t ct_vunique; +} ct_hdr_t; +#define CT_REVISION 1 +#define CT_FC_TYPE_FC 0xFC +#define CT_FC_SUBTYPE_NS 0x02 + +/* + * RFT_ID Requet CT_IU + * + * Source: NCITS xxx-200x Generic Services- 5 Rev 8.5 Section 5.2.5.30 + */ +typedef struct { + ct_hdr_t rftid_hdr; + uint8_t rftid_reserved; + uint8_t rftid_portid[3]; + uint32_t rftid_fc4types[8]; +} rft_id_t; + +/* + * FCP Response Code Definitions + * Source: NCITS T10, Project 1144D, Revision 07a (aka FCP2r07a) + */ +#define FCP_RSPNS_CODE_OFFSET 3 + +#define FCP_RSPNS_TMF_DONE 0 +#define FCP_RSPNS_DLBRSTX 1 +#define FCP_RSPNS_BADCMND 2 +#define FCP_RSPNS_EROFS 3 +#define FCP_RSPNS_TMF_REJECT 4 +#define FCP_RSPNS_TMF_FAILED 5 + + +/* unconverted miscellany */ +/* + * Basic FC Link Service defines + */ +/* + * These are in the R_CTL field. + */ +#define ABTS 0x81 +#define BA_ACC 0x84 /* of ABORT SEQUENCE */ +#define BA_RJT 0x85 /* of ABORT SEQUENCE */ + +/* + * Link Service Accept/Reject + */ +#define LS_ACC 0x8002 +#define LS_RJT 0x8001 + +/* + * FC ELS Codes- bits 31-24 of the first payload word of an ELS frame. + */ +#define PLOGI 0x03 +#define FLOGI 0x04 +#define LOGO 0x05 +#define ABTX 0x06 +#define PRLI 0x20 +#define PRLO 0x21 +#define TPRLO 0x24 +#define RNC 0x53 + +/* + * FC4 defines + */ +#define FC4_IP 5 /* ISO/EEC 8802-2 LLC/SNAP */ +#define FC4_SCSI 8 /* SCSI-3 via Fibre Channel Protocol (FCP) */ +#define FC4_FC_SVC 0x20 /* Fibre Channel Services */ + +#ifndef MSG_ABORT +#define MSG_ABORT 0x06 +#endif +#ifndef MSG_BUS_DEV_RESET +#define MSG_BUS_DEV_RESET 0x0c +#endif +#ifndef MSG_ABORT_TAG +#define MSG_ABORT_TAG 0x0d +#endif +#ifndef MSG_CLEAR_QUEUE +#define MSG_CLEAR_QUEUE 0x0e +#endif +#ifndef MSG_REL_RECOVERY +#define MSG_REL_RECOVERY 0x10 +#endif +#ifndef MSG_TERM_IO_PROC +#define MSG_TERM_IO_PROC 0x11 +#endif +#ifndef MSG_LUN_RESET +#define MSG_LUN_RESET 0x17 +#endif + +#endif /* _ISP_STDS_H */ diff --git a/sys/dev/usb/uark.c b/sys/dev/usb/uark.c new file mode 100644 index 000000000000..5aefc9ffe317 --- /dev/null +++ b/sys/dev/usb/uark.c @@ -0,0 +1,367 @@ +/* $OpenBSD: uark.c,v 1.1 2006/08/14 08:30:22 jsg Exp $ */ + +/* + * Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/module.h> +#include <sys/bus.h> +#include <sys/ioccom.h> +#include <sys/fcntl.h> +#include <sys/conf.h> +#include <sys/tty.h> +#include <sys/file.h> +#include <sys/selinfo.h> +#include <sys/sysctl.h> + +#include <dev/usb/usb.h> +#include <dev/usb/usbdi.h> +#include <dev/usb/usbdi_util.h> +#include "usbdevs.h" + +#include <dev/usb/ucomvar.h> + +#ifdef UARK_DEBUG +#define DPRINTFN(n, x) do { \ + if (uarkdebug > (n)) \ + logprintf x; \ +} while (0) +int uarkebug = 0; +#else +#define DPRINTFN(n, x) +#endif +#define DPRINTF(x) DPRINTFN(0, x) + +#define UARKBUFSZ 256 +#define UARK_CONFIG_NO 0 +#define UARK_IFACE_NO 0 + +#define UARK_SET_DATA_BITS(x) (x - 5) + +#define UARK_PARITY_NONE 0x00 +#define UARK_PARITY_ODD 0x08 +#define UARK_PARITY_EVEN 0x18 + +#define UARK_STOP_BITS_1 0x00 +#define UARK_STOP_BITS_2 0x04 + +#define UARK_BAUD_REF 3000000 + +#define UARK_WRITE 0x40 +#define UARK_READ 0xc0 + +#define UARK_REQUEST 0xfe + +#define UARK_CONFIG_INDEX 0 +#define UARK_IFACE_INDEX 0 + +struct uark_softc { + struct ucom_softc sc_ucom; + usbd_interface_handle sc_iface; + + u_char sc_msr; + u_char sc_lsr; +}; + +static void uark_get_status(void *, int portno, u_char *lsr, u_char *msr); +static void uark_set(void *, int, int, int); +static int uark_param(void *, int, struct termios *); +static void uark_break(void *, int, int); +static int uark_cmd(struct uark_softc *, uint16_t, uint16_t); + +struct ucom_callback uark_callback = { + uark_get_status, + uark_set, + uark_param, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +static const struct uark_product { + uint16_t vendor; + uint16_t product; +} uark_products[] = { + { USB_VENDOR_ARKMICRO, USB_PRODUCT_ARKMICRO_ARK3116 }, + { 0, 0 } +}; + +USB_MATCH(uark) +{ + USB_MATCH_START(uark, uaa); + int i; + + if (uaa->iface != NULL) + return (UMATCH_NONE); + + for (i = 0; uark_products[i].vendor != 0; i++) { + if (uark_products[i].vendor == uaa->vendor && + uark_products[i].product == uaa->product) { + return (UMATCH_VENDOR_PRODUCT); + } + } + + return (UMATCH_NONE); +} + +USB_ATTACH(uark) +{ + USB_ATTACH_START(uark, sc, uaa); + usbd_device_handle dev = uaa->device; + usbd_interface_handle iface; + usb_interface_descriptor_t *id; + usb_endpoint_descriptor_t *ed; + usbd_status error; + char *devinfo; + const char *devname; + int i; + struct ucom_softc *ucom = &sc->sc_ucom; + + devinfo = malloc(1024, M_USBDEV, M_WAITOK); + + bzero(ucom, sizeof(struct ucom_softc)); + ucom->sc_dev = self; + ucom->sc_udev = dev; + + devname = device_get_nameunit(ucom->sc_dev); + + if (uaa->iface == NULL) { + /* Move the device into the configured state. */ + error = usbd_set_config_index(dev, UARK_CONFIG_INDEX, 1); + if (error) { + printf("\n%s: failed to set configuration, err=%s\n", + devname, usbd_errstr(error)); + goto bad; + } + error = + usbd_device2interface_handle(dev, UARK_IFACE_INDEX, &iface); + if (error) { + printf("\n%s: failed to get interface, err=%s\n", + devname, usbd_errstr(error)); + goto bad; + } + } else + iface = uaa->iface; + + usbd_devinfo(dev, 0, devinfo); + printf("%s: %s\n", devname, devinfo); + + id = usbd_get_interface_descriptor(iface); + ucom->sc_iface = iface; + + ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1; + for (i = 0; i < id->bNumEndpoints; i++) { + ed = usbd_interface2endpoint_descriptor(iface, i); + if (ed == NULL) { + printf("%s: could not read endpoint descriptor\n", + devname); + goto bad; + } + if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) + ucom->sc_bulkin_no = ed->bEndpointAddress; + else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) + ucom->sc_bulkout_no = ed->bEndpointAddress; + } + if (ucom->sc_bulkin_no == -1 || ucom->sc_bulkout_no == -1) { + printf("%s: missing endpoint\n", devname); + goto bad; + } + ucom->sc_parent = sc; + ucom->sc_ibufsize = UARKBUFSZ; + ucom->sc_obufsize = UARKBUFSZ; + ucom->sc_ibufsizepad = UARKBUFSZ; + ucom->sc_opkthdrlen = 0; + + ucom->sc_callback = &uark_callback; + + DPRINTF(("uark: in=0x%x out=0x%x\n", ucom->sc_bulkin_no, ucom->sc_bulkout_no)); + ucom_attach(&sc->sc_ucom); + free(devinfo, M_USBDEV); + + USB_ATTACH_SUCCESS_RETURN; + +bad: + DPRINTF(("uftdi_attach: ATTACH ERROR\n")); + ucom->sc_dying = 1; + free(devinfo, M_USBDEV); + + USB_ATTACH_ERROR_RETURN; +} + +USB_DETACH(uark) +{ + USB_DETACH_START(uark, sc); + int rv = 0; + + DPRINTF(("uark_detach: sc=%p\n", sc)); + sc->sc_ucom.sc_dying = 1; + rv = ucom_detach(&sc->sc_ucom); + + return (rv); +} + +static void +uark_set(void *vsc, int portno, int reg, int onoff) +{ + struct uark_softc *sc = vsc; + + switch (reg) { + case UCOM_SET_BREAK: + uark_break(sc, portno, onoff); + return; + /* NOTREACHED */ + case UCOM_SET_DTR: + case UCOM_SET_RTS: + default: + return; + /* NOTREACHED */ + } +} + +static int +uark_param(void *vsc, int portno, struct termios *t) +{ + struct uark_softc *sc = (struct uark_softc *)vsc; + int data; + + switch (t->c_ospeed) { + case 300: + case 600: + case 1200: + case 1800: + case 2400: + case 4800: + case 9600: + case 19200: + case 38400: + case 57600: + case 115200: + uark_cmd(sc, 3, 0x83); + uark_cmd(sc, 0, (UARK_BAUD_REF / t->c_ospeed) & 0xFF); + uark_cmd(sc, 1, (UARK_BAUD_REF / t->c_ospeed) >> 8); + uark_cmd(sc, 3, 0x03); + break; + default: + return (EINVAL); + /* NOTREACHED */ + } + if (ISSET(t->c_cflag, CSTOPB)) + data = UARK_STOP_BITS_2; + else + data = UARK_STOP_BITS_1; + + if (ISSET(t->c_cflag, PARENB)) { + if (ISSET(t->c_cflag, PARODD)) + data |= UARK_PARITY_ODD; + else + data |= UARK_PARITY_EVEN; + } else + data |= UARK_PARITY_NONE; + + switch (ISSET(t->c_cflag, CSIZE)) { + case CS5: + data |= UARK_SET_DATA_BITS(5); + break; + case CS6: + data |= UARK_SET_DATA_BITS(6); + break; + case CS7: + data |= UARK_SET_DATA_BITS(7); + break; + case CS8: + data |= UARK_SET_DATA_BITS(8); + break; + } + uark_cmd(sc, 3, 0x00); + uark_cmd(sc, 3, data); + + return (0); +} + +void +uark_get_status(void *vsc, int portno, u_char *lsr, u_char *msr) +{ + struct uark_softc *sc = vsc; + + if (msr != NULL) + *msr = sc->sc_msr; + if (lsr != NULL) + *lsr = sc->sc_lsr; +} + +void +uark_break(void *vsc, int portno, int onoff) +{ +#ifdef UARK_DEBUG + struct uark_softc *sc = vsc; + + printf("%s: break %s!\n", device_get_nameunit(sc->sc_dev), + onoff ? "on" : "off"); + + if (onoff) + /* break on */ + uark_cmd(sc, 4, 0x01); + else + uark_cmd(sc, 4, 0x00); +#endif +} + +int +uark_cmd(struct uark_softc *sc, uint16_t index, uint16_t value) +{ + usb_device_request_t req; + usbd_status err; + struct ucom_softc *ucom = &sc->sc_ucom; + + req.bmRequestType = UARK_WRITE; + req.bRequest = UARK_REQUEST; + USETW(req.wValue, value); + USETW(req.wIndex, index); + USETW(req.wLength, 0); + err = usbd_do_request(ucom->sc_udev, &req, NULL); + + if (err) + return (EIO); + + return (0); +} + +static device_method_t uark_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, uark_match), + DEVMETHOD(device_attach, uark_attach), + DEVMETHOD(device_detach, uark_detach), + + { 0, 0 } +}; + +static driver_t uark_driver = { + "ucom", + uark_methods, + sizeof (struct uark_softc) +}; + +DRIVER_MODULE(uark, uhub, uark_driver, ucom_devclass, usbd_driver_load, 0); +MODULE_DEPEND(uark, usb, 1, 1, 1); +MODULE_DEPEND(uark, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER); diff --git a/sys/modules/uark/Makefile b/sys/modules/uark/Makefile new file mode 100644 index 000000000000..703cc851505c --- /dev/null +++ b/sys/modules/uark/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/usb + +KMOD= uark +SRCS= uark.c opt_usb.h bus_if.h device_if.h usbdevs.h + +.include <bsd.kmod.mk> diff --git a/usr.sbin/ipfwpcap/ipfwpcap.8 b/usr.sbin/ipfwpcap/ipfwpcap.8 new file mode 100644 index 000000000000..53787fcbb545 --- /dev/null +++ b/usr.sbin/ipfwpcap/ipfwpcap.8 @@ -0,0 +1,132 @@ +.\" Copyright (c) 2006 Niclas Zeising +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd May 22, 2006 +.Dt IPFWPCAP 8 +.Os +.Sh NAME +.Nm ipfwpcap +.Nd "copy diverted packets to a file in tcpdump format" +.Sh SYNOPSIS +.Nm +.Op Fl dr +.Op Fl b Ar maxbytes +.Op Fl p Ar maxpkts +.Op Fl P Ar pidfile +.Ar portnum +.Ar dumpfile +.Sh DESCRIPTION +The +.Nm +utility is used to copy diverted packets to a file in +.Xr tcpdump 1 +format. +The interesting packets are diverted by +.Xr ipfw 8 +to a port on which +.Nm +listens. +The packets are then dropped unless +.Fl r +is used. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl d +Turns on extra debugging messages. +.It Fl r +Writes packets back to the +.Xr divert 4 +socket. +.It Fl rr +Indicates that it is okay to quit if +.Ar maxbytes +or +.Ar maxpkts +are reached. +Diverted packets will silently disappear if nothing is listening on the +.Xr divert 4 +socket. +.It Fl b Ar maxbytes +Stop dumping after +.Ar maxbytes +bytes. +.It Fl p Ar maxpkts +Stop dumping after +.Ar maxpkt +packets. +.It Fl P Ar pidfile +File to store PID number in. +Default is +.Pa /var/run/ipwfpcap.portnr.pid . +.El +.Pp +The +.Ar portnum +argument specifies which +.Xr divert 4 +socket port to listen on. +The +.Ar dumpfile +argument is the path to the file to write captured packets to. +Specify +.Sq Fl +to write to stdout. +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +.Dl "ipfwpcap -r 8091 divt.log &" +.Pp +Starts +.Nm +as a background job listening to port 8091 and reflecting the packets +back to the socket. +.Pp +.Dl "ipfw add 2864 divert 8091 ip from 192.0.2.101" +.Pp +Example +.Xr ipfw 8 +rule to divert all packets from 192.0.2.101 to port 8091. +See +.Xr ipfw 8 +for details. +.Sh SEE ALSO +.Xr tcpdump 1 , +.Xr pcap 3 , +.Xr divert 4 , +.Xr ipfw 8 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 7.0 . +.Sh AUTHORS +.An -nosplit +.Nm +was written by +.An P. Kern Aq pkern@cns.utoronto.ca . +This manual page was written by +.An Niclas Zeising Aq niclas.zeising@gmail.com . diff --git a/usr.sbin/pppd/eui64.c b/usr.sbin/pppd/eui64.c new file mode 100644 index 000000000000..28335a3797ff --- /dev/null +++ b/usr.sbin/pppd/eui64.c @@ -0,0 +1,46 @@ +/* + eui64.c - EUI64 routines for IPv6CP. + Copyright (C) 1999 Tommi Komulainen <Tommi.Komulainen@iki.fi> + + Redistribution and use in source and binary forms are permitted + provided that the above copyright notice and this paragraph are + duplicated in all such forms and that any documentation, + advertising materials, and other materials related to such + distribution and use acknowledge that the software was developed + by Tommi Komulainen. The name of the author may not be used + to endorse or promote products derived from this software without + specific prior written permission. + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + + $Id: eui64.c,v 1.3 1999/08/25 04:15:51 paulus Exp $ +*/ + +#ifndef lint +#define RCSID "$Id: eui64.c,v 1.3 1999/08/25 04:15:51 paulus Exp $" +#endif +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include "pppd.h" + +#ifdef RCSID +static const char rcsid[] = RCSID; +#endif + +/* + * eui64_ntoa - Make an ascii representation of an interface identifier + */ +char * +eui64_ntoa(e) + eui64_t e; +{ + static char buf[32]; + + snprintf(buf, 32, "%02x%02x:%02x%02x:%02x%02x:%02x%02x", + e.e8[0], e.e8[1], e.e8[2], e.e8[3], + e.e8[4], e.e8[5], e.e8[6], e.e8[7]); + return buf; +} diff --git a/usr.sbin/pppd/eui64.h b/usr.sbin/pppd/eui64.h new file mode 100644 index 000000000000..efdf7441f4ba --- /dev/null +++ b/usr.sbin/pppd/eui64.h @@ -0,0 +1,97 @@ +/* + eui64.h - EUI64 routines for IPv6CP. + Copyright (C) 1999 Tommi Komulainen <Tommi.Komulainen@iki.fi> + + Redistribution and use in source and binary forms are permitted + provided that the above copyright notice and this paragraph are + duplicated in all such forms and that any documentation, + advertising materials, and other materials related to such + distribution and use acknowledge that the software was developed + by Tommi Komulainen. The name of the author may not be used + to endorse or promote products derived from this software without + specific prior written permission. + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + + $Id: eui64.h,v 1.3 1999/09/30 19:56:37 masputra Exp $ +*/ + +#ifndef __EUI64_H__ +#define __EUI64_H__ + +#if !defined(INET6) +#error "this file should only be included when INET6 is defined" +#endif /* not defined(INET6) */ + +#if defined(SOL2) +#include <netinet/in.h> + +typedef union { + uint8_t e8[8]; /* lower 64-bit IPv6 address */ + uint32_t e32[2]; /* lower 64-bit IPv6 address */ +} eui64_t; + +/* + * Declare the two below, since in.h only defines them when _KERNEL + * is declared - which shouldn't be true when dealing with user-land programs + */ +#define s6_addr8 _S6_un._S6_u8 +#define s6_addr32 _S6_un._S6_u32 + +#else /* else if not defined(SOL2) */ + +/* + * TODO: + * + * Maybe this should be done by processing struct in6_addr directly... + */ +typedef union +{ + u_int8_t e8[8]; + u_int16_t e16[4]; + u_int32_t e32[2]; +} eui64_t; + +#endif /* defined(SOL2) */ + +#define eui64_iszero(e) (((e).e32[0] | (e).e32[1]) == 0) +#define eui64_equals(e, o) (((e).e32[0] == (o).e32[0]) && \ + ((e).e32[1] == (o).e32[1])) +#define eui64_zero(e) (e).e32[0] = (e).e32[1] = 0; + +#define eui64_copy(s, d) memcpy(&(d), &(s), sizeof(eui64_t)) + +#define eui64_magic(e) do { \ + (e).e32[0] = magic(); \ + (e).e32[1] = magic(); \ + (e).e8[0] &= ~2; \ + } while (0) +#define eui64_magic_nz(x) do { \ + eui64_magic(x); \ + } while (eui64_iszero(x)) +#define eui64_magic_ne(x, y) do { \ + eui64_magic(x); \ + } while (eui64_equals(x, y)) + +#define eui64_get(ll, cp) do { \ + eui64_copy((*cp), (ll)); \ + (cp) += sizeof(eui64_t); \ + } while (0) + +#define eui64_put(ll, cp) do { \ + eui64_copy((ll), (*cp)); \ + (cp) += sizeof(eui64_t); \ + } while (0) + +#define eui64_set32(e, l) do { \ + (e).e32[0] = 0; \ + (e).e32[1] = htonl(l); \ + } while (0) +#define eui64_setlo32(e, l) eui64_set32(e, l) + +char *eui64_ntoa __P((eui64_t)); /* Returns ascii representation of id */ + +#endif /* __EUI64_H__ */ + diff --git a/usr.sbin/pppd/ipv6cp.c b/usr.sbin/pppd/ipv6cp.c new file mode 100644 index 000000000000..0be6dc4e116e --- /dev/null +++ b/usr.sbin/pppd/ipv6cp.c @@ -0,0 +1,1421 @@ +/* + ipv6cp.c - PPP IPV6 Control Protocol. + Copyright (C) 1999 Tommi Komulainen <Tommi.Komulainen@iki.fi> + + Redistribution and use in source and binary forms are permitted + provided that the above copyright notice and this paragraph are + duplicated in all such forms. The name of the author may not be + used to endorse or promote products derived from this software + without specific prior written permission. + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +*/ + +/* Original version, based on RFC2023 : + + Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt + Économique ayant pour membres BULL S.A. et l'INRIA). + + Ce logiciel informatique est disponible aux conditions + usuelles dans la recherche, c'est-à-dire qu'il peut + être utilisé, copié, modifié, distribué à l'unique + condition que ce texte soit conservé afin que + l'origine de ce logiciel soit reconnue. + + Le nom de l'Institut National de Recherche en Informatique + et en Automatique (INRIA), de l'IMAG, ou d'une personne morale + ou physique ayant participé à l'élaboration de ce logiciel ne peut + être utilisé sans son accord préalable explicite. + + Ce logiciel est fourni tel quel sans aucune garantie, + support ou responsabilité d'aucune sorte. + Ce logiciel est dérivé de sources d'origine + "University of California at Berkeley" et + "Digital Equipment Corporation" couvertes par des copyrights. + + L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) + est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National + Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant + sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). + + This work has been done in the context of GIE DYADE (joint R & D venture + between BULL S.A. and INRIA). + + This software is available with usual "research" terms + with the aim of retain credits of the software. + Permission to use, copy, modify and distribute this software for any + purpose and without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies, + and the name of INRIA, IMAG, or any contributor not be used in advertising + or publicity pertaining to this material without the prior explicit + permission. The software is provided "as is" without any + warranties, support or liabilities of any kind. + This software is derived from source code from + "University of California at Berkeley" and + "Digital Equipment Corporation" protected by copyrights. + + Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) + is a federation of seven research units funded by the CNRS, National + Polytechnic Institute of Grenoble and University Joseph Fourier. + The research unit in Software, Systems, Networks (LSR) is member of IMAG. +*/ + +/* + * Derived from : + * + * + * ipcp.c - PPP IP Control Protocol. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: ipv6cp.c,v 1.7 1999/10/08 01:08:18 masputra Exp $ + */ + +#ifndef lint +#define RCSID "$Id: ipv6cp.c,v 1.7 1999/10/08 01:08:18 masputra Exp $" +#endif +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * TODO: + * + * Proxy Neighbour Discovery. + * + * Better defines for selecting the ordering of + * interface up / set address. (currently checks for __linux__, + * since SVR4 && (SNI || __USLC__) didn't work properly) + */ + +#include <stdio.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> +#include <netdb.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "pppd.h" +#include "fsm.h" +#include "ipcp.h" +#include "ipv6cp.h" +#include "magic.h" +#include "pathnames.h" + +#define s6_addr32 __u6_addr.__u6_addr32 + +#ifdef RCSID +static const char rcsid[] = RCSID; +#endif + +/* global vars */ +ipv6cp_options ipv6cp_wantoptions[NUM_PPP]; /* Options that we want to request */ +ipv6cp_options ipv6cp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ +ipv6cp_options ipv6cp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ +ipv6cp_options ipv6cp_hisoptions[NUM_PPP]; /* Options that we ack'd */ +int no_ifaceid_neg = 0; + +/* local vars */ +static int ipv6cp_is_up; + +/* + * Callbacks for fsm code. (CI = Configuration Information) + */ +static void ipv6cp_resetci __P((fsm *)); /* Reset our CI */ +static int ipv6cp_cilen __P((fsm *)); /* Return length of our CI */ +static void ipv6cp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ +static int ipv6cp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ +static int ipv6cp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */ +static int ipv6cp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ +static int ipv6cp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ +static void ipv6cp_up __P((fsm *)); /* We're UP */ +static void ipv6cp_down __P((fsm *)); /* We're DOWN */ +static void ipv6cp_finished __P((fsm *)); /* Don't need lower layer */ + +fsm ipv6cp_fsm[NUM_PPP]; /* IPV6CP fsm structure */ + +static fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */ + ipv6cp_resetci, /* Reset our Configuration Information */ + ipv6cp_cilen, /* Length of our Configuration Information */ + ipv6cp_addci, /* Add our Configuration Information */ + ipv6cp_ackci, /* ACK our Configuration Information */ + ipv6cp_nakci, /* NAK our Configuration Information */ + ipv6cp_rejci, /* Reject our Configuration Information */ + ipv6cp_reqci, /* Request peer's Configuration Information */ + ipv6cp_up, /* Called when fsm reaches OPENED state */ + ipv6cp_down, /* Called when fsm leaves OPENED state */ + NULL, /* Called when we want the lower layer up */ + ipv6cp_finished, /* Called when we want the lower layer down */ + NULL, /* Called when Protocol-Reject received */ + NULL, /* Retransmission is necessary */ + NULL, /* Called to handle protocol-specific codes */ + "IPV6CP" /* String name of protocol */ +}; + + +/* + * Protocol entry points from main code. + */ +static void ipv6cp_init __P((int)); +static void ipv6cp_open __P((int)); +static void ipv6cp_close __P((int, char *)); +static void ipv6cp_lowerup __P((int)); +static void ipv6cp_lowerdown __P((int)); +static void ipv6cp_input __P((int, u_char *, int)); +static void ipv6cp_protrej __P((int)); +static int ipv6cp_printpkt __P((u_char *, int, + void (*) __P((void *, char *, ...)), void *)); +static void ipv6_check_options __P((void)); +static int ipv6_demand_conf __P((int)); +static int ipv6_active_pkt __P((u_char *, int)); + +struct protent ipv6cp_protent = { + PPP_IPV6CP, + ipv6cp_init, + ipv6cp_input, + ipv6cp_protrej, + ipv6cp_lowerup, + ipv6cp_lowerdown, + ipv6cp_open, + ipv6cp_close, + ipv6cp_printpkt, + NULL, + 0, + "IPV6CP", + ipv6_check_options, + ipv6_demand_conf, + ipv6_active_pkt +}; + +static void ipv6cp_clear_addrs __P((int, eui64_t, eui64_t)); +static void ipv6cp_script __P((char *)); + +/* + * Lengths of configuration options. + */ +#define CILEN_VOID 2 +#define CILEN_COMPRESS 4 /* length for RFC2023 compress opt. */ +#define CILEN_IFACEID 10 /* RFC2472, interface identifier */ + +#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ + (x) == CONFNAK ? "NAK" : "REJ") + +/* + * This state variable is used to ensure that we don't + * run an ipcp-up/down script while one is already running. + */ +static enum script_state { + s_down, + s_up, +} ipv6cp_script_state; + +/* + * setifaceid - set the interface identifiers manually + */ +int +setifaceid(argv) + char **argv; +{ + char *comma, *arg; + ipv6cp_options *wo = &ipv6cp_wantoptions[0]; + struct in6_addr addr; + +#define VALIDID(a) ( (((a).s6_addr32[0] == 0) && ((a).s6_addr32[1] == 0)) && \ + (((a).s6_addr32[2] != 0) || ((a).s6_addr32[3] != 0)) ) + + arg = *argv; + if ((comma = strchr(arg, ',')) == NULL) + comma = arg + strlen(arg); + + /* + * If comma first character, then no local identifier + */ + if (comma != arg) { + *comma = '\0'; + + if (inet_pton(AF_INET6, arg, &addr) == 0 || !VALIDID(addr)) { + option_error("Illegal interface identifier (local): %s", arg); + return 0; + } + + eui64_copy(addr.s6_addr32[2], wo->ourid); + wo->opt_local = 1; + *comma = ','; + } + + /* + * If comma last character, the no remote identifier + */ + if (*comma != 0 && *++comma != '\0') { + if (inet_pton(AF_INET6, comma, &addr) == 0 || !VALIDID(addr)) { + option_error("Illegal interface identifier (remote): %s", comma); + return 0; + } + eui64_copy(addr.s6_addr32[2], wo->hisid); + wo->opt_remote = 1; + } + + ipv6cp_protent.enabled_flag = 1; + return 1; +} + +/* + * Make a string representation of a network address. + */ +char * +llv6_ntoa(ifaceid) + eui64_t ifaceid; +{ + static char b[64]; + + sprintf(b, "fe80::%s", eui64_ntoa(ifaceid)); + return b; +} + + +/* + * ipv6cp_init - Initialize IPV6CP. + */ +static void +ipv6cp_init(unit) + int unit; +{ + fsm *f = &ipv6cp_fsm[unit]; + ipv6cp_options *wo = &ipv6cp_wantoptions[unit]; + ipv6cp_options *ao = &ipv6cp_allowoptions[unit]; + + f->unit = unit; + f->protocol = PPP_IPV6CP; + f->callbacks = &ipv6cp_callbacks; + fsm_init(&ipv6cp_fsm[unit]); + + memset(wo, 0, sizeof(*wo)); + memset(ao, 0, sizeof(*ao)); + + wo->accept_local = 1; + wo->neg_ifaceid = 1; + ao->neg_ifaceid = 1; + +#ifdef IPV6CP_COMP + wo->neg_vj = 1; + ao->neg_vj = 1; + wo->vj_protocol = IPV6CP_COMP; +#endif + +} + + +/* + * ipv6cp_open - IPV6CP is allowed to come up. + */ +static void +ipv6cp_open(unit) + int unit; +{ + fsm_open(&ipv6cp_fsm[unit]); +} + + +/* + * ipv6cp_close - Take IPV6CP down. + */ +static void +ipv6cp_close(unit, reason) + int unit; + char *reason; +{ + fsm_close(&ipv6cp_fsm[unit], reason); +} + + +/* + * ipv6cp_lowerup - The lower layer is up. + */ +static void +ipv6cp_lowerup(unit) + int unit; +{ + fsm_lowerup(&ipv6cp_fsm[unit]); +} + + +/* + * ipv6cp_lowerdown - The lower layer is down. + */ +static void +ipv6cp_lowerdown(unit) + int unit; +{ + fsm_lowerdown(&ipv6cp_fsm[unit]); +} + + +/* + * ipv6cp_input - Input IPV6CP packet. + */ +static void +ipv6cp_input(unit, p, len) + int unit; + u_char *p; + int len; +{ + fsm_input(&ipv6cp_fsm[unit], p, len); +} + + +/* + * ipv6cp_protrej - A Protocol-Reject was received for IPV6CP. + * + * Pretend the lower layer went down, so we shut up. + */ +static void +ipv6cp_protrej(unit) + int unit; +{ + fsm_lowerdown(&ipv6cp_fsm[unit]); +} + + +/* + * ipv6cp_resetci - Reset our CI. + */ +static void +ipv6cp_resetci(f) + fsm *f; +{ + ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + + wo->req_ifaceid = wo->neg_ifaceid && ipv6cp_allowoptions[f->unit].neg_ifaceid; + + if (!wo->opt_local) { + eui64_magic_nz(wo->ourid); + } + + *go = *wo; + eui64_zero(go->hisid); /* last proposed interface identifier */ +} + + +/* + * ipv6cp_cilen - Return length of our CI. + */ +static int +ipv6cp_cilen(f) + fsm *f; +{ + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + +#define LENCIVJ(neg) (neg ? CILEN_COMPRESS : 0) +#define LENCIIFACEID(neg) (neg ? CILEN_IFACEID : 0) + + return (LENCIIFACEID(go->neg_ifaceid) + + LENCIVJ(go->neg_vj)); +} + + +/* + * ipv6cp_addci - Add our desired CIs to a packet. + */ +static void +ipv6cp_addci(f, ucp, lenp) + fsm *f; + u_char *ucp; + int *lenp; +{ + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + int len = *lenp; + +#define ADDCIVJ(opt, neg, val) \ + if (neg) { \ + int vjlen = CILEN_COMPRESS; \ + if (len >= vjlen) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(vjlen, ucp); \ + PUTSHORT(val, ucp); \ + len -= vjlen; \ + } else \ + neg = 0; \ + } + +#define ADDCIIFACEID(opt, neg, val1) \ + if (neg) { \ + int idlen = CILEN_IFACEID; \ + if (len >= idlen) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(idlen, ucp); \ + eui64_put(val1, ucp); \ + len -= idlen; \ + } else \ + neg = 0; \ + } + + ADDCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); + + ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); + + *lenp -= len; +} + + +/* + * ipv6cp_ackci - Ack our CIs. + * + * Returns: + * 0 - Ack was bad. + * 1 - Ack was good. + */ +static int +ipv6cp_ackci(f, p, len) + fsm *f; + u_char *p; + int len; +{ + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + u_short cilen, citype, cishort; + eui64_t ifaceid; + + /* + * CIs must be in exactly the same order that we sent... + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ + +#define ACKCIVJ(opt, neg, val) \ + if (neg) { \ + int vjlen = CILEN_COMPRESS; \ + if ((len -= vjlen) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != vjlen || \ + citype != opt) \ + goto bad; \ + GETSHORT(cishort, p); \ + if (cishort != val) \ + goto bad; \ + } + +#define ACKCIIFACEID(opt, neg, val1) \ + if (neg) { \ + int idlen = CILEN_IFACEID; \ + if ((len -= idlen) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != idlen || \ + citype != opt) \ + goto bad; \ + eui64_get(ifaceid, p); \ + if (! eui64_equals(val1, ifaceid)) \ + goto bad; \ + } + + ACKCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); + + ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) + goto bad; + return (1); + +bad: + IPV6CPDEBUG(("ipv6cp_ackci: received bad Ack!")); + return (0); +} + +/* + * ipv6cp_nakci - Peer has sent a NAK for some of our CIs. + * This should not modify any state if the Nak is bad + * or if IPV6CP is in the OPENED state. + * + * Returns: + * 0 - Nak was bad. + * 1 - Nak was good. + */ +static int +ipv6cp_nakci(f, p, len) + fsm *f; + u_char *p; + int len; +{ + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + u_char citype, cilen, *next; + u_short cishort; + eui64_t ifaceid; + ipv6cp_options no; /* options we've seen Naks for */ + ipv6cp_options try; /* options to request next time */ + + BZERO(&no, sizeof(no)); + try = *go; + + /* + * Any Nak'd CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define NAKCIIFACEID(opt, neg, code) \ + if (go->neg && \ + len >= (cilen = CILEN_IFACEID) && \ + p[1] == cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + eui64_get(ifaceid, p); \ + no.neg = 1; \ + code \ + } + +#define NAKCIVJ(opt, neg, code) \ + if (go->neg && \ + ((cilen = p[1]) == CILEN_COMPRESS) && \ + len >= cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + no.neg = 1; \ + code \ + } + + /* + * Accept the peer's idea of {our,his} interface identifier, if different + * from our idea, only if the accept_{local,remote} flag is set. + */ + NAKCIIFACEID(CI_IFACEID, neg_ifaceid, + if (go->accept_local) { + while (eui64_iszero(ifaceid) || + eui64_equals(ifaceid, go->hisid)) /* bad luck */ + eui64_magic(ifaceid); + try.ourid = ifaceid; + IPV6CPDEBUG(("local LL address %s", llv6_ntoa(ifaceid))); + } + ); + +#ifdef IPV6CP_COMP + NAKCIVJ(CI_COMPRESSTYPE, neg_vj, + { + if (cishort == IPV6CP_COMP) { + try.vj_protocol = cishort; + } else { + try.neg_vj = 0; + } + } + ); +#else + NAKCIVJ(CI_COMPRESSTYPE, neg_vj, + { + try.neg_vj = 0; + } + ); +#endif + + /* + * There may be remaining CIs, if the peer is requesting negotiation + * on an option that we didn't include in our request packet. + * If they want to negotiate about interface identifier, we comply. + * If they want us to ask for compression, we refuse. + */ + while (len > CILEN_VOID) { + GETCHAR(citype, p); + GETCHAR(cilen, p); + if( (len -= cilen) < 0 ) + goto bad; + next = p + cilen - 2; + + switch (citype) { + case CI_COMPRESSTYPE: + if (go->neg_vj || no.neg_vj || + (cilen != CILEN_COMPRESS)) + goto bad; + no.neg_vj = 1; + break; + case CI_IFACEID: + if (go->neg_ifaceid || no.neg_ifaceid || cilen != CILEN_IFACEID) + goto bad; + try.neg_ifaceid = 1; + eui64_get(ifaceid, p); + if (go->accept_local) { + while (eui64_iszero(ifaceid) || + eui64_equals(ifaceid, go->hisid)) /* bad luck */ + eui64_magic(ifaceid); + try.ourid = ifaceid; + } + no.neg_ifaceid = 1; + break; + } + p = next; + } + + /* If there is still anything left, this packet is bad. */ + if (len != 0) + goto bad; + + /* + * OK, the Nak is good. Now we can update state. + */ + if (f->state != OPENED) + *go = try; + + return 1; + +bad: + IPV6CPDEBUG(("ipv6cp_nakci: received bad Nak!")); + return 0; +} + + +/* + * ipv6cp_rejci - Reject some of our CIs. + */ +static int +ipv6cp_rejci(f, p, len) + fsm *f; + u_char *p; + int len; +{ + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + u_char cilen; + u_short cishort; + eui64_t ifaceid; + ipv6cp_options try; /* options to request next time */ + + try = *go; + /* + * Any Rejected CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define REJCIIFACEID(opt, neg, val1) \ + if (go->neg && \ + len >= (cilen = CILEN_IFACEID) && \ + p[1] == cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + eui64_get(ifaceid, p); \ + /* Check rejected value. */ \ + if (! eui64_equals(ifaceid, val1)) \ + goto bad; \ + try.neg = 0; \ + } + +#define REJCIVJ(opt, neg, val) \ + if (go->neg && \ + p[1] == CILEN_COMPRESS && \ + len >= p[1] && \ + p[0] == opt) { \ + len -= p[1]; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + /* Check rejected value. */ \ + if (cishort != val) \ + goto bad; \ + try.neg = 0; \ + } + + REJCIIFACEID(CI_IFACEID, neg_ifaceid, go->ourid); + + REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) + goto bad; + /* + * Now we can update state. + */ + if (f->state != OPENED) + *go = try; + return 1; + +bad: + IPV6CPDEBUG(("ipv6cp_rejci: received bad Reject!")); + return 0; +} + + +/* + * ipv6cp_reqci - Check the peer's requested CIs and send appropriate response. + * + * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified + * appropriately. If reject_if_disagree is non-zero, doesn't return + * CONFNAK; returns CONFREJ if it can't return CONFACK. + */ +static int +ipv6cp_reqci(f, inp, len, reject_if_disagree) + fsm *f; + u_char *inp; /* Requested CIs */ + int *len; /* Length of requested CIs */ + int reject_if_disagree; +{ + ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; + ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit]; + ipv6cp_options *ao = &ipv6cp_allowoptions[f->unit]; + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + u_char *cip, *next; /* Pointer to current and next CIs */ + u_short cilen, citype; /* Parsed len, type */ + u_short cishort; /* Parsed short value */ + eui64_t ifaceid; /* Parsed interface identifier */ + int rc = CONFACK; /* Final packet return code */ + int orc; /* Individual option return code */ + u_char *p; /* Pointer to next char to parse */ + u_char *ucp = inp; /* Pointer to current output char */ + int l = *len; /* Length left */ + + /* + * Reset all his options. + */ + BZERO(ho, sizeof(*ho)); + + /* + * Process all his options. + */ + next = inp; + while (l) { + orc = CONFACK; /* Assume success */ + cip = p = next; /* Remember begining of CI */ + if (l < 2 || /* Not enough data for CI header or */ + p[1] < 2 || /* CI length too small or */ + p[1] > l) { /* CI length too big? */ + IPV6CPDEBUG(("ipv6cp_reqci: bad CI length!")); + orc = CONFREJ; /* Reject bad CI */ + cilen = l; /* Reject till end of packet */ + l = 0; /* Don't loop again */ + goto endswitch; + } + GETCHAR(citype, p); /* Parse CI type */ + GETCHAR(cilen, p); /* Parse CI length */ + l -= cilen; /* Adjust remaining length */ + next += cilen; /* Step to next CI */ + + switch (citype) { /* Check CI type */ + case CI_IFACEID: + IPV6CPDEBUG(("ipv6cp: received interface identifier ")); + + if (!ao->neg_ifaceid || + cilen != CILEN_IFACEID) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + + /* + * If he has no interface identifier, or if we both have same + * identifier then NAK it with new idea. + * In particular, if we don't know his identifier, but he does, + * then accept it. + */ + eui64_get(ifaceid, p); + IPV6CPDEBUG(("(%s)", llv6_ntoa(ifaceid))); + if (eui64_iszero(ifaceid) && eui64_iszero(go->ourid)) { + orc = CONFREJ; /* Reject CI */ + break; + } + if (!eui64_iszero(wo->hisid) && + !eui64_equals(ifaceid, wo->hisid) && + eui64_iszero(go->hisid)) { + + orc = CONFNAK; + ifaceid = wo->hisid; + go->hisid = ifaceid; + DECPTR(sizeof(ifaceid), p); + eui64_put(ifaceid, p); + } else + if (eui64_iszero(ifaceid) || eui64_equals(ifaceid, go->ourid)) { + orc = CONFNAK; + if (eui64_iszero(go->hisid)) /* first time, try option */ + ifaceid = wo->hisid; + while (eui64_iszero(ifaceid) || + eui64_equals(ifaceid, go->ourid)) /* bad luck */ + eui64_magic(ifaceid); + go->hisid = ifaceid; + DECPTR(sizeof(ifaceid), p); + eui64_put(ifaceid, p); + } + + ho->neg_ifaceid = 1; + ho->hisid = ifaceid; + break; + + case CI_COMPRESSTYPE: + IPV6CPDEBUG(("ipv6cp: received COMPRESSTYPE ")); + if (!ao->neg_vj || + (cilen != CILEN_COMPRESS)) { + orc = CONFREJ; + break; + } + GETSHORT(cishort, p); + IPV6CPDEBUG(("(%d)", cishort)); + +#ifdef IPV6CP_COMP + if (!(cishort == IPV6CP_COMP)) { + orc = CONFREJ; + break; + } +#else + orc = CONFREJ; + break; +#endif + + ho->neg_vj = 1; + ho->vj_protocol = cishort; + break; + + default: + orc = CONFREJ; + break; + } + +endswitch: + IPV6CPDEBUG((" (%s)\n", CODENAME(orc))); + + if (orc == CONFACK && /* Good CI */ + rc != CONFACK) /* but prior CI wasnt? */ + continue; /* Don't send this one */ + + if (orc == CONFNAK) { /* Nak this CI? */ + if (reject_if_disagree) /* Getting fed up with sending NAKs? */ + orc = CONFREJ; /* Get tough if so */ + else { + if (rc == CONFREJ) /* Rejecting prior CI? */ + continue; /* Don't send this one */ + if (rc == CONFACK) { /* Ack'd all prior CIs? */ + rc = CONFNAK; /* Not anymore... */ + ucp = inp; /* Backup */ + } + } + } + + if (orc == CONFREJ && /* Reject this CI */ + rc != CONFREJ) { /* but no prior ones? */ + rc = CONFREJ; + ucp = inp; /* Backup */ + } + + /* Need to move CI? */ + if (ucp != cip) + BCOPY(cip, ucp, cilen); /* Move it */ + + /* Update output pointer */ + INCPTR(cilen, ucp); + } + + /* + * If we aren't rejecting this packet, and we want to negotiate + * their identifier and they didn't send their identifier, then we + * send a NAK with a CI_IFACEID option appended. We assume the + * input buffer is long enough that we can append the extra + * option safely. + */ + if (rc != CONFREJ && !ho->neg_ifaceid && + wo->req_ifaceid && !reject_if_disagree) { + if (rc == CONFACK) { + rc = CONFNAK; + ucp = inp; /* reset pointer */ + wo->req_ifaceid = 0; /* don't ask again */ + } + PUTCHAR(CI_IFACEID, ucp); + PUTCHAR(CILEN_IFACEID, ucp); + eui64_put(wo->hisid, ucp); + } + + *len = ucp - inp; /* Compute output length */ + IPV6CPDEBUG(("ipv6cp: returning Configure-%s", CODENAME(rc))); + return (rc); /* Return final code */ +} + + +/* + * ipv6_check_options - check that any IP-related options are OK, + * and assign appropriate defaults. + */ +static void +ipv6_check_options() +{ + ipv6cp_options *wo = &ipv6cp_wantoptions[0]; + +#if defined(SOL2) + /* + * Persistent link-local id is only used when user has not explicitly + * configure/hard-code the id + */ + if ((wo->use_persistent) && (!wo->opt_local) && (!wo->opt_remote)) { + + /* + * On systems where there are no Ethernet interfaces used, there + * may be other ways to obtain a persistent id. Right now, it + * will fall back to using magic [see eui64_magic] below when + * an EUI-48 from MAC address can't be obtained. Other possibilities + * include obtaining EEPROM serial numbers, or some other unique + * yet persistent number. On Sparc platforms, this is possible, + * but too bad there's no standards yet for x86 machines. + */ + if (ether_to_eui64(&wo->ourid)) { + wo->opt_local = 1; + } + } +#endif + + if (!wo->opt_local) { /* init interface identifier */ + if (wo->use_ip && eui64_iszero(wo->ourid)) { + eui64_setlo32(wo->ourid, ntohl(ipcp_wantoptions[0].ouraddr)); + if (!eui64_iszero(wo->ourid)) + wo->opt_local = 1; + } + + while (eui64_iszero(wo->ourid)) + eui64_magic(wo->ourid); + } + + if (!wo->opt_remote) { + if (wo->use_ip && eui64_iszero(wo->hisid)) { + eui64_setlo32(wo->hisid, ntohl(ipcp_wantoptions[0].hisaddr)); + if (!eui64_iszero(wo->hisid)) + wo->opt_remote = 1; + } + } + + if (demand && (eui64_iszero(wo->ourid) || eui64_iszero(wo->hisid))) { + option_error("local/remote LL address required for demand-dialling\n"); + exit(1); + } +} + + +/* + * ipv6_demand_conf - configure the interface as though + * IPV6CP were up, for use with dial-on-demand. + */ +static int +ipv6_demand_conf(u) + int u; +{ + ipv6cp_options *wo = &ipv6cp_wantoptions[u]; + +#if defined(__linux__) || defined(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) +#if defined(SOL2) + if (!sif6up(u)) + return 0; +#else + if (!sifup(u)) + return 0; +#endif /* defined(SOL2) */ +#endif + if (!sif6addr(u, wo->ourid, wo->hisid)) + return 0; +#if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) + if (!sifup(u)) + return 0; +#endif + if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE)) + return 0; + + syslog(LOG_NOTICE, "ipv6_demand_conf"); + syslog(LOG_NOTICE, "local LL address %s", llv6_ntoa(wo->ourid)); + syslog(LOG_NOTICE, "remote LL address %s", llv6_ntoa(wo->hisid)); + + return 1; +} + + +/* + * ipv6cp_up - IPV6CP has come UP. + * + * Configure the IPv6 network interface appropriately and bring it up. + */ +static void +ipv6cp_up(f) + fsm *f; +{ + ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit]; + ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; + ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; + + IPV6CPDEBUG(("ipv6cp: up")); + + /* + * We must have a non-zero LL address for both ends of the link. + */ + if (!ho->neg_ifaceid) + ho->hisid = wo->hisid; + + if(!no_ifaceid_neg) { + if (eui64_iszero(ho->hisid)) { + syslog(LOG_ERR, "Could not determine remote LL address"); + ipv6cp_close(f->unit, "Could not determine remote LL address"); + return; + } + if (eui64_iszero(go->ourid)) { + syslog(LOG_ERR, "Could not determine local LL address"); + ipv6cp_close(f->unit, "Could not determine local LL address"); + return; + } + if (eui64_equals(go->ourid, ho->hisid)) { + syslog(LOG_ERR, "local and remote LL addresses are equal"); + ipv6cp_close(f->unit, "local and remote LL addresses are equal"); + return; + } + } + script_setenv("LLLOCAL", llv6_ntoa(go->ourid)); + script_setenv("LLREMOTE", llv6_ntoa(ho->hisid)); + +#ifdef IPV6CP_COMP + /* set tcp compression */ + sif6comp(f->unit, ho->neg_vj); +#endif + + /* + * If we are doing dial-on-demand, the interface is already + * configured, so we put out any saved-up packets, then set the + * interface to pass IPv6 packets. + */ + if (demand) { + if (! eui64_equals(go->ourid, wo->ourid) || + ! eui64_equals(ho->hisid, wo->hisid)) { + if (! eui64_equals(go->ourid, wo->ourid)) + warn("Local LL address changed to %s", + llv6_ntoa(go->ourid)); + if (! eui64_equals(ho->hisid, wo->hisid)) + warn("Remote LL address changed to %s", + llv6_ntoa(ho->hisid)); + ipv6cp_clear_addrs(f->unit, go->ourid, ho->hisid); + + /* Set the interface to the new addresses */ + if (!sif6addr(f->unit, go->ourid, ho->hisid)) { + if (debug) + warn("sif6addr failed"); + ipv6cp_close(f->unit, "Interface configuration failed"); + return; + } + + } + demand_rexmit(PPP_IPV6); + sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); + + } else { + /* + * Set LL addresses + */ +#if !defined(__linux__) && !defined(SOL2) && !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) + if (!sif6addr(f->unit, go->ourid, ho->hisid)) { + if (debug) + warn("sif6addr failed"); + ipv6cp_close(f->unit, "Interface configuration failed"); + return; + } +#endif + + /* bring the interface up for IPv6 */ +#if defined(SOL2) + if (!sif6up(f->unit)) { + if (debug) + warn("sifup failed (IPV6)"); + ipv6cp_close(f->unit, "Interface configuration failed"); + return; + } +#else + if (!sifup(f->unit)) { + if (debug) + warn("sifup failed (IPV6)"); + ipv6cp_close(f->unit, "Interface configuration failed"); + return; + } +#endif /* defined(SOL2) */ + +#if defined(__linux__) || defined(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) + if (!sif6addr(f->unit, go->ourid, ho->hisid)) { + if (debug) + warn("sif6addr failed"); + ipv6cp_close(f->unit, "Interface configuration failed"); + return; + } +#endif + sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); + + syslog(LOG_NOTICE, "local LL address %s", llv6_ntoa(go->ourid)); + syslog(LOG_NOTICE, "remote LL address %s", llv6_ntoa(ho->hisid)); + } + + np_up(f->unit, PPP_IPV6); + ipv6cp_is_up = 1; + + /* + * Execute the ipv6-up script, like this: + * /etc/ppp/ipv6-up interface tty speed local-LL remote-LL + */ + if (ipv6cp_script_state == s_down) { + ipv6cp_script_state = s_up; + ipv6cp_script(_PATH_IPV6UP); + } +} + + +/* + * ipv6cp_down - IPV6CP has gone DOWN. + * + * Take the IPv6 network interface down, clear its addresses + * and delete routes through it. + */ +static void +ipv6cp_down(f) + fsm *f; +{ + IPV6CPDEBUG(("ipv6cp: down")); + if (ipv6cp_is_up) { + ipv6cp_is_up = 0; + np_down(f->unit, PPP_IPV6); + } +#ifdef IPV6CP_COMP + sif6comp(f->unit, 0); +#endif + + /* + * If we are doing dial-on-demand, set the interface + * to queue up outgoing packets (for now). + */ + if (demand) { + sifnpmode(f->unit, PPP_IPV6, NPMODE_QUEUE); + } else { + sifnpmode(f->unit, PPP_IPV6, NPMODE_DROP); +#if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC))) +#if defined(SOL2) + sif6down(f->unit); +#else + sifdown(f->unit); +#endif /* defined(SOL2) */ +#endif + ipv6cp_clear_addrs(f->unit, + ipv6cp_gotoptions[f->unit].ourid, + ipv6cp_hisoptions[f->unit].hisid); +#if defined(__linux__) || (defined(SVR4) && (defined(SNI) || defined(__USLC))) + sifdown(f->unit); +#endif + } + + /* Execute the ipv6-down script */ + if (ipv6cp_script_state == s_up) { + ipv6cp_script_state = s_down; + ipv6cp_script(_PATH_IPV6DOWN); + } +} + + +/* + * ipv6cp_clear_addrs() - clear the interface addresses, routes, + * proxy neighbour discovery entries, etc. + */ +static void +ipv6cp_clear_addrs(unit, ourid, hisid) + int unit; + eui64_t ourid; + eui64_t hisid; +{ + cif6addr(unit, ourid, hisid); +} + + +/* + * ipv6cp_finished - possibly shut down the lower layers. + */ +static void +ipv6cp_finished(f) + fsm *f; +{ + np_finished(f->unit, PPP_IPV6); +} + + +/* + * ipv6cp_script - Execute a script with arguments + * interface-name tty-name speed local-LL remote-LL. + */ +static void +ipv6cp_script(script) + char *script; +{ + char strspeed[32], strlocal[32], strremote[32]; + char *argv[8]; + + sprintf(strspeed, "%d", baud_rate); + strcpy(strlocal, llv6_ntoa(ipv6cp_gotoptions[0].ourid)); + strcpy(strremote, llv6_ntoa(ipv6cp_hisoptions[0].hisid)); + + argv[0] = script; + argv[1] = ifname; + argv[2] = devnam; + argv[3] = strspeed; + argv[4] = strlocal; + argv[5] = strremote; + argv[6] = ipparam; + argv[7] = NULL; + + run_program(script, argv, 0); +} + +/* + * ipv6cp_printpkt - print the contents of an IPV6CP packet. + */ +static char *ipv6cp_codenames[] = { + "ConfReq", "ConfAck", "ConfNak", "ConfRej", + "TermReq", "TermAck", "CodeRej" +}; + +static int +ipv6cp_printpkt(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + int code, id, len, olen; + u_char *pstart, *optend; + u_short cishort; + eui64_t ifaceid; + + if (plen < HEADERLEN) + return 0; + pstart = p; + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < HEADERLEN || len > plen) + return 0; + + if (code >= 1 && code <= sizeof(ipv6cp_codenames) / sizeof(char *)) + printer(arg, " %s", ipv6cp_codenames[code-1]); + else + printer(arg, " code=0x%x", code); + printer(arg, " id=0x%x", id); + len -= HEADERLEN; + switch (code) { + case CONFREQ: + case CONFACK: + case CONFNAK: + case CONFREJ: + /* print option list */ + while (len >= 2) { + GETCHAR(code, p); + GETCHAR(olen, p); + p -= 2; + if (olen < 2 || olen > len) { + break; + } + printer(arg, " <"); + len -= olen; + optend = p + olen; + switch (code) { + case CI_COMPRESSTYPE: + if (olen >= CILEN_COMPRESS) { + p += 2; + GETSHORT(cishort, p); + printer(arg, "compress "); + printer(arg, "0x%x", cishort); + } + break; + case CI_IFACEID: + if (olen == CILEN_IFACEID) { + p += 2; + eui64_get(ifaceid, p); + printer(arg, "addr %s", llv6_ntoa(ifaceid)); + } + break; + } + while (p < optend) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + printer(arg, ">"); + } + break; + + case TERMACK: + case TERMREQ: + if (len > 0 && *p >= ' ' && *p < 0x7f) { + printer(arg, " "); + print_string(p, len, printer, arg); + p += len; + len = 0; + } + break; + } + + /* print the rest of the bytes in the packet */ + for (; len > 0; --len) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + + return p - pstart; +} + +/* + * ipv6_active_pkt - see if this IP packet is worth bringing the link up for. + * We don't bring the link up for IP fragments or for TCP FIN packets + * with no data. + */ +#define IP6_HDRLEN 40 /* bytes */ +#define IP6_NHDR_FRAG 44 /* fragment IPv6 header */ +#define IPPROTO_TCP 6 +#define TCP_HDRLEN 20 +#define TH_FIN 0x01 + +/* + * We use these macros because the IP header may be at an odd address, + * and some compilers might use word loads to get th_off or ip_hl. + */ + +#define get_ip6nh(x) (((unsigned char *)(x))[6]) +#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) +#define get_tcpflags(x) (((unsigned char *)(x))[13]) + +static int +ipv6_active_pkt(pkt, len) + u_char *pkt; + int len; +{ + u_char *tcp; + + len -= PPP_HDRLEN; + pkt += PPP_HDRLEN; + if (len < IP6_HDRLEN) + return 0; + if (get_ip6nh(pkt) == IP6_NHDR_FRAG) + return 0; + if (get_ip6nh(pkt) != IPPROTO_TCP) + return 1; + if (len < IP6_HDRLEN + TCP_HDRLEN) + return 0; + tcp = pkt + IP6_HDRLEN; + if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == IP6_HDRLEN + get_tcpoff(tcp) * 4) + return 0; + return 1; +} diff --git a/usr.sbin/pppd/ipv6cp.h b/usr.sbin/pppd/ipv6cp.h new file mode 100644 index 000000000000..2641008e99ad --- /dev/null +++ b/usr.sbin/pppd/ipv6cp.h @@ -0,0 +1,129 @@ +/* + ipv6cp.h - PPP IPV6 Control Protocol. + Copyright (C) 1999 Tommi Komulainen <Tommi.Komulainen@iki.fi> + + Redistribution and use in source and binary forms are permitted + provided that the above copyright notice and this paragraph are + duplicated in all such forms. The name of the author may not be + used to endorse or promote products derived from this software + without specific prior written permission. + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +*/ + +/* Original version, based on RFC2023 : + + Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt + Économique ayant pour membres BULL S.A. et l'INRIA). + + Ce logiciel informatique est disponible aux conditions + usuelles dans la recherche, c'est-à-dire qu'il peut + être utilisé, copié, modifié, distribué à l'unique + condition que ce texte soit conservé afin que + l'origine de ce logiciel soit reconnue. + + Le nom de l'Institut National de Recherche en Informatique + et en Automatique (INRIA), de l'IMAG, ou d'une personne morale + ou physique ayant participé à l'élaboration de ce logiciel ne peut + être utilisé sans son accord préalable explicite. + + Ce logiciel est fourni tel quel sans aucune garantie, + support ou responsabilité d'aucune sorte. + Ce logiciel est dérivé de sources d'origine + "University of California at Berkeley" et + "Digital Equipment Corporation" couvertes par des copyrights. + + L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) + est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National + Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant + sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). + + This work has been done in the context of GIE DYADE (joint R & D venture + between BULL S.A. and INRIA). + + This software is available with usual "research" terms + with the aim of retain credits of the software. + Permission to use, copy, modify and distribute this software for any + purpose and without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies, + and the name of INRIA, IMAG, or any contributor not be used in advertising + or publicity pertaining to this material without the prior explicit + permission. The software is provided "as is" without any + warranties, support or liabilities of any kind. + This software is derived from source code from + "University of California at Berkeley" and + "Digital Equipment Corporation" protected by copyrights. + + Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) + is a federation of seven research units funded by the CNRS, National + Polytechnic Institute of Grenoble and University Joseph Fourier. + The research unit in Software, Systems, Networks (LSR) is member of IMAG. +*/ + +/* + * Derived from : + * + * + * ipcp.h - IP Control Protocol definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: ipv6cp.h,v 1.3 1999/09/30 19:57:45 masputra Exp $ + * $FreeBSD$ + */ + +/* + * Options. + */ +#define CI_IFACEID 1 /* Interface Identifier */ +#define CI_COMPRESSTYPE 2 /* Compression Type */ + +/* No compression types yet defined. + *#define IPV6CP_COMP 0x004f + */ +typedef struct ipv6cp_options { + int neg_ifaceid; /* Negotiate interface identifier? */ + int req_ifaceid; /* Ask peer to send interface identifier? */ + int accept_local; /* accept peer's value for iface id? */ + int opt_local; /* ourtoken set by option */ + int opt_remote; /* histoken set by option */ + int use_ip; /* use IP as interface identifier */ +#if defined(SOL2) + int use_persistent; /* use uniquely persistent value for address */ +#endif /* defined(SOL2) */ + int neg_vj; /* Van Jacobson Compression? */ + u_short vj_protocol; /* protocol value to use in VJ option */ + eui64_t ourid, hisid; /* Interface identifiers */ +} ipv6cp_options; + +extern fsm ipv6cp_fsm[]; +extern ipv6cp_options ipv6cp_wantoptions[]; +extern ipv6cp_options ipv6cp_gotoptions[]; +extern ipv6cp_options ipv6cp_allowoptions[]; +extern ipv6cp_options ipv6cp_hisoptions[]; + +extern struct protent ipv6cp_protent; + +extern int setifaceid __P((char **arg)); diff --git a/usr.sbin/wpa/wpa_passphrase/Makefile b/usr.sbin/wpa/wpa_passphrase/Makefile new file mode 100644 index 000000000000..c5ddce166b40 --- /dev/null +++ b/usr.sbin/wpa/wpa_passphrase/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +WPA_SUPPLICANT_DISTDIR?= ${.CURDIR}/../../../contrib/wpa_supplicant +.PATH: ${WPA_SUPPLICANT_DISTDIR} + +PROG= wpa_passphrase +SRCS= wpa_passphrase.c sha1.c md5.c + +MAN= wpa_passphrase.8 + +.include <bsd.prog.mk> diff --git a/usr.sbin/wpa/wpa_passphrase/wpa_passphrase.8 b/usr.sbin/wpa/wpa_passphrase/wpa_passphrase.8 new file mode 100644 index 000000000000..3a725de6a0e6 --- /dev/null +++ b/usr.sbin/wpa/wpa_passphrase/wpa_passphrase.8 @@ -0,0 +1,66 @@ +.\" Copyright (c) 2006 Henrik Brix Andersen <henrik@brixandersen.dk> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd October 16, 2006 +.Dt WPA_PASSPHRASE 8 +.Os +.Sh NAME +.Nm wpa_passphrase +.Nd "utility for generating a 256-bit pre-shared WPA key from an ASCII passphrase" +.Sh SYNOPSIS +.Nm +.Aq Ar ssid +.Op Ar passphrase +.Sh DESCRIPTION +The +.Nm +utility is a small program for generating a 256-bit pre-shared WPA key +from an ASCII passphrase and a given SSID. The output is formatted for +inclusion in +.Xr wpa_supplicant.conf 5 . +.Pp +If +.Nm +is called with only an SSID as argument it will prompt for a +passphrase on standard input. +.Sh SEE ALSO +.Xr wpa_supplicant.conf 5 , +.Xr wpa_supplicant 8 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 6.2 . +.Sh AUTHORS +The +.Nm +utility was written by +.An Jouni Malinen +.Aq jkmaline@cc.hut.fi . +.Pp +This manual page was written by +.An Henrik Brix Andersen +.Aq henrik@brixandersen.dk . |