diff --git a/src/hostinfo/dhcpd.py b/src/hostinfo/dhcpd.py
index a315a7309a0042ea9c2a81fd334209539af86adf..c255d7db507289725b29777b8ee6b4a55df1294a 100755
--- a/src/hostinfo/dhcpd.py
+++ b/src/hostinfo/dhcpd.py
@@ -48,105 +48,142 @@ class "AppleNBI-ppc" {
     
 def conf(tree, dhcphost):
     #
-    # A. Check if host is a dhcpserver
+    # A. Get interfaces to serve
     #
-    emit = False
+    interface = []
     for ds in tree._host_._interface_._dhcpserver_:
         if dhcphost in ds.name[0::1]:
-            # Given host is a dhcpserver
-            dhcphost = ds.name[0:]
+            # Host is dhcpserver for this interface
             dhcpip = ds.ip[0:]
-            emit = True
-
-    if not emit:
+            interface.append(ds._parent)
+    if not interface:
         raise Exception("%s is not a dhcpserver" % dhcphost)
 
+    #
+    # B. Emit header
+    #
     result = "ddns-update-style none;\n"
     result += "authoritative;\n"
     result += MacOS_NETBOOT(dhcpip)
-    for n in tree._subnet_:
-        if not n.network[0]:
-            continue
-        netmask = aton(n.netmask[0])
-        subnet = aton(n.network[0]) & netmask
-        static = {}
-        dynamic = {}
-        emit = None
-        for i in tree._host_._interface_:
-            # Find all hosts that belong to this network
-            if i.ip[0]:
-                net = aton(i.ip[0]) & netmask
-                if net == subnet:
-                    if i.name[0:] == dhcphost:
-                        emit = i._dhcpserver_
-                    if i.dynamic[0] == dhcphost:
-                        # Dynamic address served by this host
-                        dynamic[aton(i.ip[0])] = i
-                    else:
-                        static[i.name[0:]] = i
-        if not emit:
-            continue
 
-        result += "subnet %s netmask %s {\n" % (n.network[0], n.netmask[0])
-        result += "  option subnet-mask %s;\n" % n.netmask[0]
-        if n.broadcast[0]:
-            result += "  option broadcast-address %s;\n" % n.broadcast[0]
-        if n.gateway[0]:
-            result += "  option routers %s;\n" % n.gateway[0]
-        if n.domain[0]:
-            result += "  option domain-name \"%s\";\n" % n.domain[0]
-        if n.name_servers[0]:
-            result += "  option domain-name-servers %s;\n" % n.name_servers[0]
+    #
+    # C. Emit subnet declarations for each interface
+    #
+    for i in interface:
+        address = []
+        if i.ip[0]:
+            # Main address
+            address.append(i.ip[0])
+        for ip in i._ip_:
+            # Alias addresses
+            if ip.address[0]:
+                address.append(ip.address[0])
 
-        #
-        # Emit dynamic hosts
-        #
-        result += "  default-lease-time 604800; # One week\n"
-        result += "  max-lease-time 604800;\n"
-        dk = dynamic.keys()
-        dk.sort()
-        min = 0
-        max = 0
-        for d in dk:
-            if d == max + 1:
-                max = d
-            else:
-                if min:
-                    result += "  range %s %s;\n" % (ntoa(min), ntoa(max))
-                min = d
-                max = d
-        if min:
-            result += "  range %s %s;\n" % (ntoa(min), ntoa(max))
-        result += "  get-lease-hostnames true;\n"
-        result += "  use-host-decl-names on;\n"
+        # Collect subnets for this interface
+        network = {}
+        for n in tree._subnet_:
+            if not n.network[0]:
+                continue
+            netmask = aton(n.netmask[0])
+            subnet = aton(n.network[0]) & netmask
+            for a in address:
+                if aton(a) & netmask == subnet:
+                    network[ntoa(subnet)] = n
 
-        #
-        # Emit static hosts
-        #
-        result += "\n  group {\n"
-        result += "    default-lease-time 315360000; # 10 year\n"
-        result += "    max-lease-time     315360000; # 10 years\n\n"
- 
-        sk = static.keys()
-        sk.sort()
-        for i in [static[x] for x in sk]:
-            ether = i.ethernet[0]
-            ip = i.ip[0]
-            if ether:
-                result += "    host %s.%s {\n"% (i.name[0:], n.domain[0])
-                result += "      hardware ethernet %s;\n" % ether
-                result += "      fixed-address %s;\n" % ip
-                result += "      option host-name \"%s\";\n" % i.name[0:]
-                if i._kickstart_:
-                    kf = i._kickstart_[0].file[0]
-                    result += "      server-name \"%s\";\n" % dhcphost
-                    result += "      next-server %s;\n" % dhcphost
-                    result += "      filename \"/local/kickstart/%s\";\n" % kf
-                for d in i._dhcp_:
-                    result += "      %s\n" % d.value[0]
-                result += "    }\n"
-            
+        # Emit subnet declarations
+        if len(network.keys()) > 1:
+            # Multiple networks served on this interface
+            result += 'shared-network "MAC(%s)" {\n\n' % i.ethernet[0]
+            for n in network.values():
+                for l in emit_subnet(tree, n, dhcphost).split("\n"):
+                    result += "  %s\n" % l
+            result += "}\n"
+        else:
+            result += emit_subnet(tree, network.values()[0], dhcphost)
+
+    return result
+
+def emit_subnet(tree, n, dhcphost):
+    result = ""
+
+    netmask = aton(n.netmask[0])
+    subnet = aton(n.network[0]) & netmask
+    static = {}
+    dynamic = {}
+
+    for i in tree._host_._interface_:
+        # Find all hosts that belong to this network
+        if i.ip[0]:
+            net = aton(i.ip[0]) & netmask
+            if net == subnet:
+                if i.dynamic[0] == dhcphost:
+                    # Dynamic address served by this host
+                    dynamic[aton(i.ip[0])] = i
+                else:
+                    static[i.name[0:]] = i
 
-        result += "  }\n"
-        result += "}\n\n"
+    result += "subnet %s netmask %s {\n" % (n.network[0], n.netmask[0])
+    result += "  option subnet-mask %s;\n" % n.netmask[0]
+    if n.broadcast[0]:
+        result += "  option broadcast-address %s;\n" % n.broadcast[0]
+    if n.gateway[0]:
+        result += "  option routers %s;\n" % n.gateway[0]
+    if n.domain[0]:
+        result += "  option domain-name \"%s\";\n" % n.domain[0]
+    if n.name_servers[0]:
+        result += "  option domain-name-servers %s;\n" % (
+            n.name_servers[0])
+
+    #
+    # Emit dynamic hosts
+    #
+    result += "  default-lease-time 604800; # One week\n"
+    result += "  max-lease-time 604800;\n"
+    dk = dynamic.keys()
+    dk.sort()
+    min = 0
+    max = 0
+    for d in dk:
+        if d == max + 1:
+            max = d
+        else:
+            if min:
+                result += "  range %s %s;\n" % (ntoa(min), ntoa(max))
+            min = d
+            max = d
+    if min:
+        result += "  range %s %s;\n" % (ntoa(min), ntoa(max))
+    result += "  get-lease-hostnames true;\n"
+    result += "  use-host-decl-names on;\n"
+
+    #
+    # Emit static hosts
+    #
+    result += "\n  group {\n"
+    result += "    default-lease-time 315360000; # 10 year\n"
+    result += "    max-lease-time     315360000; # 10 years\n\n"
+
+    sk = static.keys()
+    sk.sort()
+    for i in [static[x] for x in sk]:
+        ether = i.ethernet[0]
+        ip = i.ip[0]
+        if ether:
+            result += "    host %s.%s {\n"% (i.name[0:], n.domain[0])
+            result += "      hardware ethernet %s;\n" % ether
+            result += "      fixed-address %s;\n" % ip
+            result += "      option host-name \"%s\";\n" % i.name[0:]
+            if i._kickstart_:
+                kf = i._kickstart_[0].file[0]
+                result += "      server-name \"%s\";\n" % dhcphost
+                result += "      next-server %s;\n" % dhcphost
+                result += "      filename \"/local/kickstart/%s\";\n" % kf
+            for d in i._dhcp_:
+                result += "      %s\n" % d.value[0]
+            result += "    }\n"
+    
+
+    result += "  }\n"
+    result += "}\n"
+    
     return result