static void configure_interface1(struct interface *ifp) { struct if_options *ifo = ifp->options; int ra_global, ra_iface; /* Do any platform specific configuration */ if_conf(ifp); if (ifp->flags & IFF_POINTOPOINT && !(ifo->options & DHCPCD_INFORM)) ifo->options |= DHCPCD_STATIC; if (ifp->flags & IFF_NOARP || ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)) ifo->options &= ~(DHCPCD_ARP | DHCPCD_IPV4LL); if (!(ifp->flags & (IFF_POINTOPOINT | IFF_LOOPBACK | IFF_MULTICAST))) ifo->options &= ~DHCPCD_IPV6RS; if (ifo->options & DHCPCD_LINK && carrier_status(ifp) == LINK_UNKNOWN) ifo->options &= ~DHCPCD_LINK; if (ifo->metric != -1) ifp->metric = ifo->metric; /* We want to disable kernel interface RA as early as possible. */ if (ifo->options & DHCPCD_IPV6RS) { ra_global = check_ipv6(NULL, options & DHCPCD_IPV6RA_OWN ? 1:0); ra_iface = check_ipv6(ifp->name, ifp->options->options & DHCPCD_IPV6RA_OWN ? 1 : 0); if (ra_global == -1 || ra_iface == -1) ifo->options &= ~DHCPCD_IPV6RS; else if (ra_iface == 0) ifo->options |= DHCPCD_IPV6RA_OWN; } /* If we haven't specified a ClientID and our hardware address * length is greater than DHCP_CHADDR_LEN then we enforce a ClientID * of the hardware address family and the hardware address. */ if (ifp->hwlen > DHCP_CHADDR_LEN) ifo->options |= DHCPCD_CLIENTID; /* Firewire and InfiniBand interfaces require ClientID and * the broadcast option being set. */ switch (ifp->family) { case ARPHRD_IEEE1394: /* FALLTHROUGH */ case ARPHRD_INFINIBAND: ifo->options |= DHCPCD_CLIENTID | DHCPCD_BROADCAST; break; } }
int main(int argc, char *argv[]) { int err; char *buf[2]; struct sockaddr_storage address; if (argc == 1) { /* automated tests */ check_ipv4(); check_ipv6(); check_resolve(); exit(EXIT_SUCCESS); } else if (argc != 3) { printf("usage: %s [host] [port]\n", argv[0]); exit(EXIT_SUCCESS); } err = strtoaddr(argv[1], argv[2], (struct sockaddr *) &address, sizeof(struct sockaddr_storage)); if (err != 0) { printf("Unable to convert strings to sockaddr\n"); exit(EXIT_FAILURE); } err = addrtostr((struct sockaddr *) &address, sizeof(struct sockaddr_storage), buf); if (err != 0) { printf("Unable to convert sockaddr to strings\n"); exit(EXIT_FAILURE); } printf("host: %s port: %s\n", buf[0], buf[1]); addrtostr_free(buf); return 0; }
static void configure_interface1(struct interface *ifp) { struct if_options *ifo = ifp->options; int ra_global, ra_iface; /* Do any platform specific configuration */ if_conf(ifp); if (ifp->flags & IFF_POINTOPOINT && !(ifo->options & DHCPCD_INFORM)) ifo->options |= DHCPCD_STATIC; if (ifp->flags & IFF_NOARP || ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)) ifo->options &= ~(DHCPCD_ARP | DHCPCD_IPV4LL); if (!(ifp->flags & (IFF_POINTOPOINT | IFF_LOOPBACK | IFF_MULTICAST))) ifo->options &= ~DHCPCD_IPV6RS; if (ifo->options & DHCPCD_LINK && carrier_status(ifp) == LINK_UNKNOWN) ifo->options &= ~DHCPCD_LINK; if (ifo->metric != -1) ifp->metric = ifo->metric; if (!(ifo->options & DHCPCD_IPV6)) ifo->options &= ~DHCPCD_IPV6RS; /* We want to disable kernel interface RA as early as possible. */ if (ifo->options & DHCPCD_IPV6RS) { ra_global = check_ipv6(NULL, options & DHCPCD_IPV6RA_OWN ? 1:0); ra_iface = check_ipv6(ifp->name, ifp->options->options & DHCPCD_IPV6RA_OWN ? 1 : 0); if (ra_global == -1 || ra_iface == -1) ifo->options &= ~DHCPCD_IPV6RS; else if (ra_iface == 0) ifo->options |= DHCPCD_IPV6RA_OWN; } /* If we haven't specified a ClientID and our hardware address * length is greater than DHCP_CHADDR_LEN then we enforce a ClientID * of the hardware address family and the hardware address. */ if (ifp->hwlen > DHCP_CHADDR_LEN) ifo->options |= DHCPCD_CLIENTID; /* Firewire and InfiniBand interfaces require ClientID and * the broadcast option being set. */ switch (ifp->family) { case ARPHRD_IEEE1394: /* FALLTHROUGH */ case ARPHRD_INFINIBAND: ifo->options |= DHCPCD_CLIENTID | DHCPCD_BROADCAST; break; } if (!(ifo->options & DHCPCD_IAID)) { /* * An IAID is for identifying a unqiue interface within * the client. It is 4 bytes long. Working out a default * value is problematic. * * Interface name and number are not stable * between different OS's. Some OS's also cannot make * up their mind what the interface should be called * (yes, udev, I'm looking at you). * Also, the name could be longer than 4 bytes. * Also, with pluggable interfaces the name and index * could easily get swapped per actual interface. * * The MAC address is 6 bytes long, the final 3 * being unique to the manufacturer and the initial 3 * being unique to the organisation which makes it. * We could use the last 4 bytes of the MAC address * as the IAID as it's the most stable part given the * above, but equally it's not guaranteed to be * unique. * * Given the above, and our need to reliably work * between reboots without persitent storage, * generating the IAID from the MAC address is the only * logical default. * * dhclient uses the last 4 bytes of the MAC address. * dibbler uses an increamenting counter. * wide-dhcpv6 uses 0 or a configured value. * odhcp6c uses 1. * Windows 7 uses the first 3 bytes of the MAC address * and an unknown byte. * dhcpcd-6.1.0 and earlier used the interface name, * falling back to interface index if name > 4. */ memcpy(ifo->iaid, ifp->hwaddr + ifp->hwlen - sizeof(ifo->iaid), sizeof(ifo->iaid)); #if 0 len = strlen(ifp->name); if (len <= sizeof(ifo->iaid)) { memcpy(ifo->iaid, ifp->name, len); memset(ifo->iaid + len, 0, sizeof(ifo->iaid) - len); } else { /* IAID is the same size as a uint32_t */ len = htonl(ifp->index); memcpy(ifo->iaid, &len, sizeof(len)); } #endif ifo->options |= DHCPCD_IAID; } #ifdef INET6 if (ifo->ia == NULL && ifo->options & DHCPCD_IPV6) { ifo->ia = malloc(sizeof(*ifo->ia)); if (ifo->ia == NULL) syslog(LOG_ERR, "%s: %m", __func__); else { if (ifo->ia_type == 0) ifo->ia_type = D6_OPTION_IA_NA; memcpy(ifo->ia->iaid, ifo->iaid, sizeof(ifo->iaid)); ifo->ia_len = 1; ifo->ia->sla = NULL; ifo->ia->sla_len = 0; } } #endif }
// TODO and for non NTP packets? (ie 1588) // FIXME: the ip pointer is dirty and will break with IPv6 packets int get_valid_ntp_payload(radpcap_packet_t *packet, struct ntp_pkt **ntp, struct sockaddr_storage *ss_src, struct sockaddr_storage *ss_dst, int *ttl) { struct sockaddr_in *sin; struct sockaddr_in6 *sin6; struct ip *iph; struct ip6_hdr *ip6h; struct udphdr *udph; linux_sll_header_t *sllh; uint16_t proto; int remaining; int err; JDEBUG remaining = ((struct pcap_pkthdr *)packet->header)->caplen; switch (packet->type) { /* * This is format #1, skip 14 bytes ethernet header. Only NTP packets ever * captured in this format are IPv4 */ case DLT_EN10MB: iph = (struct ip *)(packet->payload + sizeof(struct ether_header)); remaining -= sizeof(struct ether_header); ip6h = NULL; break; /* * This is format #2 and #3. Here we take advantage of a bug in bytes order in * libtrace-3.0-beta3 to identify the formats. * - if sllh->hatype = ARPHRD_ETHER (0x0001), we have format 3. * - if sllh->hatype is 256 (0x0100) it's a libtrace format. */ case DLT_LINUX_SLL: sllh = (linux_sll_header_t*) packet->payload; /* Format #2 */ if (ntohs(sllh->hatype) != 0x0001) { iph = (struct ip *)(packet->payload + sizeof(struct ether_header) + sizeof(linux_sll_header_t)); remaining -= sizeof(struct ether_header); ip6h = NULL; break; } /* This is format 3 */ proto = ntohs(sllh->protocol); switch (proto) { /* IPv4 */ case (ETHERTYPE_IP): ip6h = NULL; iph = (struct ip *)(packet->payload + sizeof(linux_sll_header_t)); remaining -= sizeof(linux_sll_header_t); err = check_ipv4(iph, remaining); if (err) return (1); ss_src->ss_family = AF_INET; ss_dst->ss_family = AF_INET; sin = (struct sockaddr_in *)ss_src; sin->sin_addr = iph->ip_src; sin = (struct sockaddr_in *)ss_dst; sin->sin_addr = iph->ip_dst; *ttl = iph->ip_ttl; udph = (struct udphdr *)((char *)iph + (iph->ip_hl * 4)); remaining -= sizeof(struct ip); break; /* IPv6 */ case (ETHERTYPE_IPV6): iph = NULL; ip6h = (struct ip6_hdr *)(packet->payload + sizeof(linux_sll_header_t)); remaining -= sizeof(linux_sll_header_t); err = check_ipv6(ip6h, remaining); if (err) return (1); ss_src->ss_family = AF_INET6; ss_dst->ss_family = AF_INET6; sin6 = (struct sockaddr_in6 *)ss_src; sin6->sin6_addr = ip6h->ip6_src; sin6 = (struct sockaddr_in6 *)ss_dst; sin6->sin6_addr = ip6h->ip6_dst; *ttl = ip6h->ip6_hops; udph = (struct udphdr *)((char *)ip6h + sizeof(struct ip6_hdr)); remaining -= sizeof(struct ip6_hdr); break; /* IEEE 1588 over Ethernet */ case (0x88F7): verbose(LOG_ERR, "1588 over Ethernet not implemented"); return (1); default: verbose(LOG_ERR, "Unsupported protocol in SLL header %u", proto); return(1); } break; default: verbose(LOG_ERR, "MAC layer type not supported yet."); return (1); break; } if (remaining < sizeof(struct udphdr)) { verbose(LOG_WARNING, "Broken UDP datagram"); return (1); } *ntp = (struct ntp_pkt *)((char *)udph + sizeof(struct udphdr)); remaining -= sizeof(struct udphdr); /* * Make sure the NTP packet is not truncated. A normal NTP packet is at * least 48 bytes long, but a control or private request is as small as 12 * bytes. */ if (remaining < 12) { verbose(LOG_WARNING, "NTP packet truncated, payload is %d bytes " "instead of at least 12 bytes", remaining); return (1); } return (0); }