dlpi_io.c revision e704a8f24a369484ba8f4a1cf49d4db00dd91166
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stropts.h>
#include <string.h> /* strpbrk */
#include <stdlib.h>
#include <dhcpmsg.h>
#include "dlpi_io.h"
#include "v4_sum_impl.h"
#include "common.h"
/*
* timeout to wait for acknowledgement of packet filter, in seconds.
*/
#define FILTER_TIMEOUT 5
/*
* dlpi_recvfrom(): receives data on a DLPI stream
*
* input: dlpi_handle_t: dlpi handle to receive the data on
* void *: a buffer to store the data in
* size_t: the size of the buffer
* struct sockaddr_in *: if non-NULL, sender's IP address is filled in
* struct sockaddr_in *: if non-NULL, recipient's IP address
* output: ssize_t: the number of bytes read on success, -1 on failure
*/
{
void *msgbuf;
int rc;
return (-1);
}
if (rc != DLPI_SUCCESS) {
dlpi_strerror(rc));
return (-1);
}
/*
* since we're just pulling data off the wire, what we have
* may look nothing like a DHCP packet. note that this
* shouldn't happen (pfmod should have tossed it already).
*/
return (-1);
}
"data on streamhead");
}
/*
* verify checksums
*/
"ipv4 checksum");
return (-1);
}
"UDP checksum");
return (-1);
}
}
}
return (msglen);
}
/*
* dlpi_sendto(): sends UDP packets on a DLPI stream
*
* input: dlpi_handle_t: dlpi handle to send the packet on
* void *: a buffer to send
* size_t: the size of the buffer
* struct sockaddr_in *: the IP address to send the data to
* uchar_t *: the link-layer destination address
* size_t: the size of the link-layer destination address
* output: ssize_t: the number of bytes sent on success, -1 on failure
*/
{
void *msgbuf;
int rc;
/*
* TODO: someday we might want to support `to' not being
* the same as INADDR_BROADCAST. we don't need the support
* right now, but it's annoying to have a general interface
* that only supports a specific function.
*/
return (-1);
}
/*
* we allocate one extra byte here in case the UDP checksum
* routine needs it to get the packet length to be even.
*/
return (-1);
}
/*
* build the ipv4 header. assume that our source address is 0
* (since we wouldn't be using DLPI if we could actually send
* packets an easier way). note that we only need to set nonzero
* fields since we got calloc()'d memory above.
*/
/*
* From a purist's perspective, we should set the TTL to 1 for
* limited broadcasts. But operational experience (cisco routers)
* has shown that doing so results in the relay agent dropping our
* packets. These same devices (ciscos) also don't set the TTL
* to MAXTTL on the unicast side of the relay agent. Thus, the only
* safe thing to do is to always set the ttl to MAXTTL. Sigh.
*/
if (rc != DLPI_SUCCESS) {
dlpi_strerror(rc));
return (-1);
}
return (buflen);
}
/*
* set_packet_filter(): sets the current packet filter on a DLPI stream
*
* input: dlpi_handle_t: the DLPI handle to set the packet filter on
* filter_func_t *: the filter to use
* void *: an argument to pass to the filter function
* const char *: a text description of the filter's purpose
* output: boolean_t: B_TRUE on success, B_FALSE on failure.
*/
const char *filter_name)
{
struct packetfilt pf;
"open_dlpi_pif: cannot push pfmod on stream");
return (B_FALSE);
}
/*
* if this ioctl() fails, we're really hosed. the best we can
* really do is play on.
*/
else
/*
* clean out any potential cruft on the descriptor that
* appeared before we were able to set the filter
*/
return (B_TRUE);
}
/*
*
* input: ushort_t *: a place to store the packet filter code
* void *: not used
* output: ushort_t *: two bytes past the last byte in the packet filter
*/
/* ARGSUSED */
ushort_t *
{
/*
*/
/*
* make sure the IP packet doesn't have any options. 2nd
* nibble is the header length field.
* TODO: if we decide to handle options, this code goes away.
*/
*pfp++ = ENF_PUSHWORD + 0;
/*
* if there's a fragment offset, or if the IP_MF bit is lit,
* pitch the packet. this pitches all fragments.
* TODO: if we decide to handle fragments, this code goes away.
*/
/*
* make sure the packet is for the DHCP client port -- 22nd
* byte is the UDP port number.
*/
return (pfp);
}