/* * Copyright (c) 2009 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * DHCPv6.c * - implementation of DHCPv6-specific functions (packet field set, get) */ /* * Modification History * * September 16, 2009 Dieter Siegmund (dieter@apple.com) * - created */ #include "DHCPv6.h" #include "DHCPv6Options.h" #include #include "util.h" const char * DHCPv6MessageName(int message) { const char * str; switch (message) { case kDHCPv6MessageNone: str = "None"; break; case kDHCPv6MessageSOLICIT: str = "SOLICIT"; break; case kDHCPv6MessageADVERTISE: str = "ADVERTISE"; break; case kDHCPv6MessageREQUEST: str = "REQUEST"; break; case kDHCPv6MessageCONFIRM: str = "CONFIRM"; break; case kDHCPv6MessageRENEW: str = "RENEW"; break; case kDHCPv6MessageREBIND: str = "REBIND"; break; case kDHCPv6MessageREPLY: str = "REPLY"; break; case kDHCPv6MessageRELEASE: str = "RELEASE"; break; case kDHCPv6MessageDECLINE: str = "DECLINE"; break; case kDHCPv6MessageRECONFIGURE: str = "RECONFIGURE"; break; case kDHCPv6MessageINFORMATION_REQUEST: str = "INFORMATION_REQUEST"; break; case kDHCPv6MessageRELAY_FORW: str = "RELAY_FORW"; break; case kDHCPv6MessageRELAY_REPL: str = "RELAY_REPL"; break; default: str = "msg_type = msg_type; return; } /* * Function: DHCPv6PacketSetTransactionID * Purpose: * Set the transaction id in the given DHCPv6 packet using the given * transaction id. Convert the transaction id to network byte order, then * take the bottom 3 bytes and place them in the DHCPv6 packet transaction_id * field. */ void DHCPv6PacketSetTransactionID(DHCPv6PacketRef pkt, uint32_t transaction_id) { uint32_t r = htonl(transaction_id); uint8_t * v; /* grab the lower 24 bits */ v = (uint8_t *)&r; pkt->transaction_id[0] = v[1]; pkt->transaction_id[1] = v[2]; pkt->transaction_id[2] = v[3]; return; } /* * Function: DHCPv6PacketGetTransactionID * Purpose: * Return the transaction id from the given DHCPv6 packet in host byte order. * The transaction id is 3 bytes long, so stuff the bytes into the lower * 3 bytes of the uint32_t, and convert to host byte order. * Returns: * Transaction id from DHCPv6 packet in host byte order as a 32-bit quantity. */ uint32_t DHCPv6PacketGetTransactionID(const DHCPv6PacketRef pkt) { uint32_t r; uint8_t * v; /* grab the lower 24 bits */ v = (uint8_t *)&r; v[0] = 0; v[1] = pkt->transaction_id[0]; v[2] = pkt->transaction_id[1]; v[3] = pkt->transaction_id[2]; return (ntohl(r)); } void DHCPv6PacketFPrint(FILE * file, const DHCPv6PacketRef pkt, int pkt_len) { if (pkt_len < DHCPV6_PACKET_HEADER_LENGTH) { fprintf(file, "Packet too short %d < %d\n", pkt_len, DHCPV6_PACKET_HEADER_LENGTH); return; } fprintf(file, "DHCPv6 %s (%d) Transaction ID 0x%06x Length %d\n", DHCPv6MessageName(pkt->msg_type), pkt->msg_type, DHCPv6PacketGetTransactionID(pkt), pkt_len); return; }