code: func Serve(conn ServeConn, handler Handler, jobs chan job, ctx context.Context) error {
  
  	buffer := make([]byte, 1500)
  
  	for {
  
  		n, cm, addr, err := conn.ReadFromRaw(buffer)
  		if err != nil {
  			return err
  		}
  		if n < 240 { // Packet too small to be DHCP
  			continue
  		}
  
  		req := dhcp.Packet(buffer[:n])
  
  		if req.HLen() > 16 { // Invalid size
  			continue
  		}
  		options := req.ParseOptions()
  
  		var reqType dhcp.MessageType
  		if t := options[dhcp.OptionDHCPMessageType]; len(t) != 1 {
  			continue
  		} else {
  			reqType = dhcp.MessageType(t[0])
  			if reqType < dhcp.Discover || reqType > dhcp.Inform {
  				continue
  			}
  		}
  		var dhcprequest dhcp.Packet
  		dhcprequest = append([]byte(nil), req...)
  		jobe := job{dhcprequest, reqType, handler, addr, cm.Dst, ctx}
  		go func() {
  			jobs <- jobe
  		}()
  
  	}
  }
docs: // Serve takes a ServeConn (such as a net.PacketConn) that it uses for both
  // reading and writing DHCP packets. Every packet is passed to the handler,
  // which processes it and optionally return a response packet for writing back
  // to the network.
  //
  // To capture limited broadcast packets (sent to 255.255.255.255), you must
  // listen on a socket bound to IP_ADDRANY (0.0.0.0). This means that broadcast
  // packets sent to any interface on the system may be delivered to this
  // socket.  See: https://code.google.com/p/go/issues/detail?id=7106
  //
  // Additionally, response packets may not return to the same
  // interface that the request was received from.  Writing a custom ServeConn,
  // or using ServeIf() can provide a workaround to this problem.