summaryrefslogtreecommitdiff
path: root/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c
diff options
context:
space:
mode:
authormeem <none@none>2007-10-30 11:15:43 -0700
committermeem <none@none>2007-10-30 11:15:43 -0700
commite704a8f24a369484ba8f4a1cf49d4db00dd91166 (patch)
tree4762654df7e0a47345da07a85ce6936794c883fa /usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c
parent4a52ef43505e10e3f14cc54c97c2458c40aa4072 (diff)
downloadillumos-gate-e704a8f24a369484ba8f4a1cf49d4db00dd91166.tar.gz
PSARC/2007/565 IP_XMIT_IF removal and IP_BOUND_IF rationalization
PSARC/2007/571 IP_DHCPINIT_IF socket option 4354207 dhcpagent should use sockets rather than DLPI 6533610 IP_XMIT_IF should fade from in.routed's view 6607674 DHCP client's "checkaddr" warnings have output reversed 6607676 DHCP client misreports dhcp_bound_complete as configure_bound 6609845 torch IP_XMIT_IF and complete IP_BOUND_IF 6609852 need a way to receive IP unicast DHCP traffic before lease acquisition 6609868 IP should create broadcast IREs when bringing up 0.0.0.0 6616106 IP_UNSPEC_SRC sockets should skip calls to ipif_select_source() --HG-- rename : usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.c => deleted_files/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.c rename : usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.h => deleted_files/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.h rename : usr/src/cmd/cmd-inet/sbin/dhcpagent/inc.flg => deleted_files/usr/src/cmd/cmd-inet/sbin/dhcpagent/inc.flg
Diffstat (limited to 'usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c')
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c113
1 files changed, 74 insertions, 39 deletions
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c
index 2206ca4b23..9782d1480c 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c
@@ -372,7 +372,7 @@ compute_points_v6(const PKT_LIST *pkt, const dhcp_smach_t *dsmp)
/*
* Look through the packet contents. Valid packets must have our
* client ID and a server ID, which has already been checked by
- * dhcp_acknak_lif. Bonus points for each option.
+ * dhcp_packet_lif. Bonus points for each option.
*/
/* One point for having a valid message. */
@@ -959,7 +959,7 @@ accept_v6_message(dhcp_smach_t *dsmp, PKT_LIST *plp, const char *pname,
}
/*
- * dhcp_acknak_common(): Processes reception of an ACK or NAK packet on the
+ * dhcp_acknak_global(): Processes reception of an ACK or NAK packet on the
* global socket -- broadcast packets for IPv4, all
* packets for DHCPv6.
*
@@ -973,7 +973,7 @@ accept_v6_message(dhcp_smach_t *dsmp, PKT_LIST *plp, const char *pname,
/* ARGSUSED */
void
-dhcp_acknak_common(iu_eh_t *ehp, int fd, short events, iu_event_id_t id,
+dhcp_acknak_global(iu_eh_t *ehp, int fd, short events, iu_event_id_t id,
void *arg)
{
PKT_LIST *plp;
@@ -983,14 +983,18 @@ dhcp_acknak_common(iu_eh_t *ehp, int fd, short events, iu_event_id_t id,
uint_t xid;
dhcp_smach_t *dsmp;
boolean_t isv6 = (fd == v6_sock_fd);
+ struct sockaddr_in sin;
+ const char *reason;
+ size_t sinlen = sizeof (sin);
+ int sock;
- plp = recv_pkt(fd, get_max_mtu(isv6), isv6, B_FALSE, NULL);
+ plp = recv_pkt(fd, get_max_mtu(isv6), isv6);
if (plp == NULL)
return;
pif = lookup_pif_by_index(plp->ifindex, isv6);
if (pif == NULL) {
- dhcpmsg(MSG_VERBOSE, "dhcp_acknak_common: ignored packet "
+ dhcpmsg(MSG_VERBOSE, "dhcp_acknak_global: ignored packet "
"received on v%d ifIndex %d", isv6 ? 6 : 4, plp->ifindex);
free_pkt_entry(plp);
return;
@@ -998,33 +1002,45 @@ dhcp_acknak_common(iu_eh_t *ehp, int fd, short events, iu_event_id_t id,
recv_type = pkt_recv_type(plp);
pname = pkt_type_to_string(recv_type, isv6);
- if (!isv6 && !pkt_v4_match(recv_type, DHCP_PACK|DHCP_PNAK)) {
- dhcpmsg(MSG_VERBOSE, "dhcp_acknak_common: ignored %s packet "
- "received via broadcast on %s", pname, pif->pif_name);
- free_pkt_entry(plp);
- return;
- }
/*
- * Find the corresponding state machine not using DLPI.
+ * Find the corresponding state machine.
*
* Note that DHCPv6 Reconfigure would be special: it's not the reply to
* any transaction, and thus we would need to search on transaction ID
- * zero (all state machines) to find the match. However, Reconfigure
+ * zero (all state machines) to find the match. However, Reconfigure
* is not yet supported.
*/
xid = pkt_get_xid(plp->pkt, isv6);
+ if (!isv6 && !pkt_v4_match(recv_type, DHCP_PACK|DHCP_PNAK)) {
+ reason = "not ACK or NAK";
+ goto drop;
+ }
+
for (dsmp = lookup_smach_by_xid(xid, NULL, isv6); dsmp != NULL;
dsmp = lookup_smach_by_xid(xid, dsmp, isv6)) {
if (dsmp->dsm_lif->lif_pif == pif)
break;
}
- if (dsmp == NULL || dsmp->dsm_using_dlpi) {
- dhcpmsg(MSG_VERBOSE, "dhcp_acknak_common: ignored %s packet "
- "received via broadcast %s; %s", pname, pif->pif_name,
- dsmp == NULL ? "unknown state machine" : "not using DLPI");
- free_pkt_entry(plp);
- return;
+
+ if (dsmp == NULL) {
+ reason = "unknown state machine";
+ goto drop;
+ }
+
+ /*
+ * For IPv4, most packets will be handled by dhcp_packet_lif(). The
+ * only exceptions are broadcast packets sent when lif_sock_ip_fd has
+ * bound to something other than INADDR_ANY.
+ */
+ if (!isv6) {
+ sock = dsmp->dsm_lif->lif_sock_ip_fd;
+
+ if (getsockname(sock, (struct sockaddr *)&sin, &sinlen) != -1 &&
+ sin.sin_addr.s_addr == INADDR_ANY) {
+ reason = "handled by lif_sock_ip_fd";
+ goto drop;
+ }
}
/*
@@ -1035,6 +1051,12 @@ dhcp_acknak_common(iu_eh_t *ehp, int fd, short events, iu_event_id_t id,
accept_v6_message(dsmp, plp, pname, recv_type);
else
accept_v4_acknak(dsmp, plp);
+ return;
+drop:
+ dhcpmsg(MSG_VERBOSE, "dhcp_acknak_global: ignored v%d %s packet for %s "
+ "received on global socket: %s", isv6 ? 6 : 4, pname, pif->pif_name,
+ reason);
+ free_pkt_entry(plp);
}
/*
@@ -1062,11 +1084,11 @@ request_failed(dhcp_smach_t *dsmp)
}
/*
- * dhcp_acknak_lif(): Processes reception of an ACK or NAK packet on a given
- * logical interface for IPv4 (only).
+ * dhcp_packet_lif(): Processes reception of an ACK, NAK, or OFFER packet on
+ * a given logical interface for IPv4 (only).
*
* input: iu_eh_t *: unused
- * int: the global file descriptor the ACK/NAK arrived on
+ * int: the file descriptor the packet arrived on
* short: unused
* iu_event_id_t: the id of this event callback with the handler
* void *: pointer to logical interface receiving message
@@ -1075,7 +1097,7 @@ request_failed(dhcp_smach_t *dsmp)
/* ARGSUSED */
void
-dhcp_acknak_lif(iu_eh_t *ehp, int fd, short events, iu_event_id_t id,
+dhcp_packet_lif(iu_eh_t *ehp, int fd, short events, iu_event_id_t id,
void *arg)
{
dhcp_lif_t *lif = arg;
@@ -1085,21 +1107,22 @@ dhcp_acknak_lif(iu_eh_t *ehp, int fd, short events, iu_event_id_t id,
uint_t xid;
dhcp_smach_t *dsmp;
- if ((plp = recv_pkt(fd, lif->lif_max, B_FALSE, B_FALSE, NULL)) == NULL)
+ if ((plp = recv_pkt(fd, lif->lif_max, B_FALSE)) == NULL)
return;
recv_type = pkt_recv_type(plp);
pname = pkt_type_to_string(recv_type, B_FALSE);
- if (!pkt_v4_match(recv_type, DHCP_PACK | DHCP_PNAK)) {
- dhcpmsg(MSG_VERBOSE, "dhcp_acknak_lif: ignored v4 %s packet "
+ if (!pkt_v4_match(recv_type,
+ DHCP_PACK | DHCP_PNAK | DHCP_PUNTYPED | DHCP_POFFER)) {
+ dhcpmsg(MSG_VERBOSE, "dhcp_packet_lif: ignored v4 %s packet "
"received via LIF %s", pname, lif->lif_name);
free_pkt_entry(plp);
return;
}
/*
- * Find the corresponding state machine not using DLPI.
+ * Find the corresponding state machine.
*/
xid = pkt_get_xid(plp->pkt, B_FALSE);
for (dsmp = lookup_smach_by_xid(xid, NULL, B_FALSE); dsmp != NULL;
@@ -1107,19 +1130,31 @@ dhcp_acknak_lif(iu_eh_t *ehp, int fd, short events, iu_event_id_t id,
if (dsmp->dsm_lif == lif)
break;
}
- if (dsmp == NULL || dsmp->dsm_using_dlpi) {
- dhcpmsg(MSG_VERBOSE, "dhcp_acknak_lif: ignored %s packet xid "
- "%x received via LIF %s; %s", pname, xid, lif->lif_name,
- dsmp == NULL ? "unknown state machine" : "not using DLPI");
- free_pkt_entry(plp);
- return;
- }
- /*
- * We've got a packet; make sure it's acceptable and cancel the REQUEST
- * retransmissions.
- */
- accept_v4_acknak(dsmp, plp);
+ if (dsmp == NULL)
+ goto drop;
+
+ if (pkt_v4_match(recv_type, DHCP_PACK|DHCP_PNAK)) {
+ /*
+ * We've got an ACK/NAK; make sure it's acceptable and cancel
+ * the REQUEST retransmissions.
+ */
+ accept_v4_acknak(dsmp, plp);
+ } else {
+ if (is_bound_state(dsmp->dsm_state))
+ goto drop;
+ /*
+ * Must be an OFFER or a BOOTP message: enqueue it for later
+ * processing by select_best().
+ */
+ pkt_smach_enqueue(dsmp, plp);
+ }
+ return;
+drop:
+ dhcpmsg(MSG_VERBOSE, "dhcp_packet_lif: ignored %s packet xid "
+ "%x received via LIF %s; %s", pname, xid, lif->lif_name,
+ dsmp == NULL ? "unknown state machine" : "bound");
+ free_pkt_entry(plp);
}
/*