1e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* 2e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * dhcpcd - DHCP client daemon 3e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Copyright (c) 2006-2008 Roy Marples <roy@marples.name> 4e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * All rights reserved 5e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 6e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Redistribution and use in source and binary forms, with or without 7e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * modification, are permitted provided that the following conditions 8e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * are met: 9e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 1. Redistributions of source code must retain the above copyright 10e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * notice, this list of conditions and the following disclaimer. 11e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 2. Redistributions in binary form must reproduce the above copyright 12e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * notice, this list of conditions and the following disclaimer in the 13e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * documentation and/or other materials provided with the distribution. 14e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 15e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * SUCH DAMAGE. 26e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt */ 27e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 28e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define THIRTY_YEARS_IN_SECONDS 946707779 29e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 30e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <errno.h> 31e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <stdio.h> 32e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <stdlib.h> 33e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <string.h> 34e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <time.h> 35e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <unistd.h> 36e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 37e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "common.h" 38e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "duid.h" 39e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "net.h" 40e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 41e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtsize_t 42e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtget_duid(unsigned char *duid, const struct interface *iface) 43e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 44e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt FILE *f; 45e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt uint16_t type = 0; 46e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt uint16_t hw = 0; 47e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt uint32_t ul; 48e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt time_t t; 49e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int x = 0; 50e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt unsigned char *p = duid; 51e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt size_t len = 0; 52e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char *line; 53e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 54e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* If we already have a DUID then use it as it's never supposed 55e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * to change once we have one even if the interfaces do */ 56e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((f = fopen(DUID, "r"))) { 57e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while ((line = get_line(f))) { 58e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt len = hwaddr_aton(NULL, line); 59e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (len && len <= DUID_LEN) { 60e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt hwaddr_aton(duid, line); 61e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 62e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 63e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt len = 0; 64e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 65e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt fclose(f); 66e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (len) 67e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return len; 68e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else { 69e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (errno != ENOENT) 70e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return 0; 71e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 72e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 73e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* No file? OK, lets make one based on our interface */ 74e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!(f = fopen(DUID, "w"))) 75e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return 0; 76e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt type = htons(1); /* DUI-D-LLT */ 77e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(p, &type, 2); 78e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p += 2; 79e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt hw = htons(iface->family); 80e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(p, &hw, 2); 81e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p += 2; 82e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* time returns seconds from jan 1 1970, but DUID-LLT is 83e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * seconds from jan 1 2000 modulo 2^32 */ 84e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt t = time(NULL) - THIRTY_YEARS_IN_SECONDS; 85e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ul = htonl(t & 0xffffffff); 86e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(p, &ul, 4); 87e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p += 4; 88e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Finally, add the MAC address of the interface */ 89e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(p, iface->hwaddr, iface->hwlen); 90e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p += iface->hwlen; 91e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt len = p - duid; 92e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt x = fprintf(f, "%s\n", hwaddr_ntoa(duid, len)); 93e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt fclose(f); 94e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Failed to write the duid? scrub it, we cannot use it */ 95e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (x < 1) { 96e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt len = 0; 97e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt unlink(DUID); 98e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 99e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return len; 100e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 101