001/*
002 * To change this license header, choose License Headers in Project Properties.
003 * To change this template file, choose Tools | Templates
004 * and open the template in the editor.
005 */
006package org.anarres.dhcp.server.pcap;
007
008import com.google.common.base.Preconditions;
009import com.google.common.util.concurrent.MoreExecutors;
010import java.io.IOException;
011import java.util.ArrayList;
012import java.util.Arrays;
013import java.util.List;
014import java.util.concurrent.Executor;
015import javax.annotation.Nonnegative;
016import javax.annotation.Nonnull;
017import javax.annotation.PostConstruct;
018import javax.annotation.PreDestroy;
019import org.anarres.dhcp.common.address.AddressUtils;
020import org.anarres.dhcp.common.address.InterfaceAddress;
021import org.apache.directory.server.dhcp.service.DhcpService;
022import org.apache.directory.server.dhcp.service.manager.LeaseManager;
023import org.apache.directory.server.dhcp.service.manager.LeaseManagerDhcpService;
024import org.pcap4j.core.PcapAddress;
025import org.pcap4j.core.PcapHandle;
026import org.pcap4j.core.PcapNetworkInterface;
027import org.pcap4j.core.Pcaps;
028import org.slf4j.Logger;
029import org.slf4j.LoggerFactory;
030
031/**
032 * Don't use this yet.
033 *
034 * @author shevek
035 */
036public class DhcpServer {
037
038    private static final Logger LOG = LoggerFactory.getLogger(DhcpServer.class);
039    private final DhcpService service;
040    private final int port;
041    private Executor executor = MoreExecutors.directExecutor();
042
043    @Nonnull
044    private static InterfaceAddress toInterfaceAddress(@Nonnull PcapAddress address) {
045        Preconditions.checkNotNull(address, "PcapAddress was null.");
046        int netmask = AddressUtils.toNetmask(address.getNetmask());
047        return new InterfaceAddress(address.getAddress(), netmask);
048    }
049
050    @Nonnull
051    private static InterfaceAddress[] toInterfaceAddresses(@Nonnull PcapNetworkInterface iface) {
052        Preconditions.checkNotNull(iface, "PcapNetworkInterface was null.");
053        List<InterfaceAddress> out = new ArrayList<InterfaceAddress>();
054        for (PcapAddress address : iface.getAddresses())
055            out.add(toInterfaceAddress(address));
056        return out.toArray(new InterfaceAddress[out.size()]);
057    }
058
059    public DhcpServer(@Nonnull DhcpService service, @Nonnegative int port) {
060        this.service = service;
061        this.port = port;
062    }
063
064    public DhcpServer(@Nonnull DhcpService service) {
065        this(service, DhcpService.SERVER_PORT);
066    }
067
068    public DhcpServer(@Nonnull LeaseManager manager, @Nonnegative int port) {
069        this(new LeaseManagerDhcpService(manager), port);
070    }
071
072    public DhcpServer(@Nonnull LeaseManager manager) {
073        this(new LeaseManagerDhcpService(manager));
074    }
075
076    @PostConstruct
077    public void start() throws IOException, InterruptedException {
078    }
079
080    @PreDestroy
081    public void stop() throws IOException, InterruptedException {
082    }
083
084    public void run() throws Exception {
085        for (PcapNetworkInterface iface : Pcaps.findAllDevs())
086            LOG.info(iface.getName() + " : " + iface);
087        PcapNetworkInterface iface = Pcaps.getDevByName("eth0");
088        LOG.info("Using " + iface.getName() + " : " + iface);
089
090        InterfaceAddress[] interfaceAddresses = toInterfaceAddresses(iface);
091        LOG.info("Addresses are " + Arrays.toString(interfaceAddresses));
092
093        PcapHandle handle = iface.openLive(4096, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 0);
094        handle.loop(10, new DhcpPacketListener(service, interfaceAddresses));
095        // handle.setFilter("udp port " + port, BpfProgram.BpfCompileMode.OPTIMIZE);
096        // handle.breakLoop();
097        // handle.close();
098    }
099}