revarp.c revision b1241e9cf9226feb1f5e3763a6e7a377520b3d10
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
#include "defs.h"
#include "ifconfig.h"
#include <libdlpi.h>
#include <sys/sysmacros.h>
#include <deflt.h>
#define RARPRETRIES 5
/*
* The following value (8) is determined to work reliably in switched 10/100MB
* ethernet environments. Use caution if you plan on decreasing it.
*/
#define RARPTIMEOUT 8
static char defaultfile[] = "/etc/inet/rarp";
static char retries_var[] = "RARP_RETRIES=";
static int rarp_timeout = RARPTIMEOUT;
static int rarp_retries = RARPRETRIES;
uchar_t **);
/* ARGSUSED */
int
{
int if_fd;
union DL_primitives *dlp;
struct timeval currenttime;
int waittime;
int tries_left;
if (ifname[0] == '\0') {
exit(1);
}
if (debug)
Perror0_exit("socket");
}
Perror0_exit("SIOCGLIFFLAGS");
/* don't try to revarp if we know it won't work */
return (0);
/* open rarp interface */
&my_broadcast);
if (if_fd < 0)
return (0);
/*
* with 6 byte addresses currently.
*/
if (ifaddrlen != ETHERADDRL) {
return (0);
}
/* look for adjustments to rarp_retries in the RARP defaults file */
if (defopen(defaultfile) == 0) {
char *cp;
int ntries;
if (ntries > 0)
}
}
/* allocate request and response buffers */
return (0);
}
/* create rarp request */
/* send the request */
goto fail;
if (debug)
(void) printf("rarp sent\n");
/* read the answers */
goto fail;
}
goto fail;
}
for (;;) {
flags = 0;
/*
* Check to see when the packet was last sent.
* If we have not sent a packet in the last
* RARP_TIMEOUT seconds, we should send one now.
* Note that if some other host on the network is
* sending a broadcast packet, poll will return and we
* will find out that it does not match the reply we
* are waiting for and then go back to poll. If the
* frequency of such packets is > rarp_timeout, we don't
* want to just go back to poll. We should send out one
* more RARP request before blocking in poll.
*/
waittime = rarp_timeout -
if (waittime <= 0) {
if (--tries_left > 0) {
if (debug)
(void) printf("rarp retry\n");
goto rarp_retry;
} else {
if (debug)
(void) printf("rarp timeout\n");
goto fail;
}
}
/* start RARP reply timeout */
if (--tries_left > 0) {
if (debug)
(void) printf("rarp retry\n");
goto rarp_retry;
} else {
if (debug)
(void) printf("rarp timeout\n");
goto fail;
}
} else if (ret == -1) {
perror("ifconfig: RARP reply poll");
goto fail;
}
/* poll returned > 0 for this fd so getmsg should not block */
perror("ifconfig: RARP reply getmsg");
goto fail;
}
if (debug) {
(void) printf("rarp: ret[%d] ctl.len[%d] data.len[%d] "
}
/* Validate DL_UNITDATA_IND. */
/* LINTED: malloc returns a pointer aligned for any use */
if (debug) {
(void) printf("rarp: dl_primitive[%lu]\n",
dlp->dl_primitive);
(void) printf(
"rarp: err ak: dl_errno %lu errno %lu\n",
}
(void) printf("rarp: ud err: err[%lu] len[%lu] "
"off[%lu]\n",
}
}
cause = "MORECTL flag";
cause = "MOREDATA flag";
cause = "missing control part of message";
cause = "short control part of message";
cause = "not unitdata_ind";
cause = "short unitdata_ind";
cause = "short arp";
cause = "hrd";
cause = "pro";
cause = "hln";
cause = "pln";
if (cause) {
"sanity check failed; cause: %s\n", cause);
continue;
}
case ARPOP_REQUEST:
if (debug)
(void) printf("Got an arp request\n");
break;
case ARPOP_REPLY:
if (debug)
(void) printf("Got an arp reply.\n");
break;
case REVARP_REQUEST:
if (debug)
(void) printf("Got a rarp request.\n");
break;
case REVARP_REPLY:
if (debug) {
}
return (1);
default:
break;
}
}
/* NOTREACHED */
fail:
return (0);
}
/*
* Open the datalink provider device and bind to the REVARP type.
* Return the resulting descriptor.
*/
static int
{
char *str;
int i;
if (debug)
if (fd < 0) {
"%s\n", ifname);
return (-1);
}
NULL) < 0) {
goto failed;
}
goto failed;
}
NULL) < 0) {
goto failed;
}
if (debug) {
(void) printf("broadcast addr: ");
for (i = 0; i < dlinfo.dl_brdcst_addr_length; i++)
(void) printf("\n");
}
if (debug)
goto failed;
}
goto failed;
}
if (debug) {
(void) printf("device %s mac address %s\n",
}
}
return (fd);
(void) dlpi_close(fd);
return (-1);
}
static int
{
union DL_primitives *dlp;
char *ctlbuf;
int ret;
/*
* Construct DL_UNITDATA_REQ. Allocate at least BUFSIZ bytes.
*/
return (-1);
}
/* LINTED: malloc returns a pointer aligned for any use */
/*
* XXX FIXME Assumes a specific DLPI address format.
*/
sizeof (etype));
/* Send DL_UNITDATA_REQ. */
return (ret);
}
int
{
int fd;
if (fd < 0) {
"%s\n", ifname);
return (-1);
}
(void) dlpi_close(fd);
return (-1);
}
(void) dlpi_close(fd);
return (0);
}
void
dlpi_print_address(char *ifname)
{
if (fd < 0) {
/* Do not report an error */
return;
}
NULL) < 0) {
(void) dlpi_close(fd);
return;
}
goto failed;
}
goto failed;
}
(void) dlpi_close(fd);
switch (dl_info.dl_mac_type) {
case DL_IB:
break;
default:
break;
}
}
(void) dlpi_close(fd);
}